Module: kamailio
Branch: master
Commit: 5f6cfaf302a9509326d7d5113468bb596fcd11f1
URL: 
https://github.com/kamailio/kamailio/commit/5f6cfaf302a9509326d7d5113468bb596fcd11f1

Author: nickakt <[email protected]>
Committer: Henning Westerholt <[email protected]>
Date: 2025-12-01T15:41:56+01:00

ndb_redis: fix error handling for multiple servers with init_without_redis

- moved error handling labels (err and err2) inside the server loop
  to allow continuation when init_without_redis=1
- added cleanup_redis_context() helper function for proper resource cleanup
- properly free failed context and set ctxRedis=NULL for failed servers
- allows setups with multiple Redis servers to have partial initialization
  when some servers are unavailable

When init_without_redis=1 and multiple servers are configured:
- Previously: if one server failed, error handler would exit and lose
  all connections including successful ones
- Now: failed servers are cleaned up and marked as NULL, loop continues
  to initialize remaining servers

Changes:
- Added cleanup_redis_context() for code reuse
- Moved err/err2 labels inside loop
- Added proper cleanup on failure
- Simplified success path logic

---

Modified: src/modules/ndb_redis/redis_client.c

---

Diff:  
https://github.com/kamailio/kamailio/commit/5f6cfaf302a9509326d7d5113468bb596fcd11f1.diff
Patch: 
https://github.com/kamailio/kamailio/commit/5f6cfaf302a9509326d7d5113468bb596fcd11f1.patch

---

diff --git a/src/modules/ndb_redis/redis_client.c 
b/src/modules/ndb_redis/redis_client.c
index 4afb0b96158..aab2db2a09a 100644
--- a/src/modules/ndb_redis/redis_client.c
+++ b/src/modules/ndb_redis/redis_client.c
@@ -78,6 +78,23 @@ int redis_append_formatted_command(
 #define redis_append_formatted_command redisAppendFormattedCommand
 #endif
 
+/**
+ * Cleanup Redis connection and free resources
+ */
+static inline void cleanup_redis_context(redisc_server_t *rsrv)
+{
+       if(rsrv->ctxRedis) {
+               redisFree(rsrv->ctxRedis);
+               rsrv->ctxRedis = NULL;
+       }
+#ifdef WITH_SSL
+       if(rsrv->sslCtxRedis != NULL) {
+               redisFreeSSLContext(rsrv->sslCtxRedis);
+               rsrv->sslCtxRedis = NULL;
+       }
+#endif
+}
+
 /**
  *
  */
@@ -312,43 +329,71 @@ int redisc_init(void)
                                        db, rsrv->ctxRedis->errstr);
                        goto err2;
                }
-       }
+               LM_INFO("successfully initialized redis server [%.*s] 
ctxRedis=%p\n",
+                               rsrv->sname->len, rsrv->sname->s, 
rsrv->ctxRedis);
+               continue;
 
-       return 0;
+       err2:
+               if(sock != 0) {
+                       LM_ERR("error communicating with redis server [%.*s]"
+                                  " (unix:%s db:%d): %s\n",
+                                       rsrv->sname->len, rsrv->sname->s, 
unix_sock_path, db,
+                                       rsrv->ctxRedis->errstr);
+               } else {
+                       LM_ERR("error communicating with redis server [%.*s] 
(%s:%d/%d): "
+                                  "%s\n",
+                                       rsrv->sname->len, rsrv->sname->s, addr, 
port, db,
+                                       rsrv->ctxRedis->errstr);
+               }
+               if(init_without_redis == 1) {
+                       /* Clean up resources once before deciding what to do */
+                       cleanup_redis_context(rsrv);
+
+                       /* Now decide whether to continue or return */
+                       if(rsrv->next != NULL) {
+                               LM_WARN("failed to connect to redis server 
[%.*s], trying next "
+                                               "server\n",
+                                               rsrv->sname->len, 
rsrv->sname->s);
+                               continue;
+                       } else {
+                               LM_WARN("failed to initialize redis 
connections, but "
+                                               "initializing"
+                                               " module anyway.\n");
+                               return 0;
+                       }
+               }
 
-err2:
-       if(sock != 0) {
-               LM_ERR("error communicating with redis server [%.*s]"
-                          " (unix:%s db:%d): %s\n",
-                               rsrv->sname->len, rsrv->sname->s, 
unix_sock_path, db,
-                               rsrv->ctxRedis->errstr);
-       } else {
-               LM_ERR("error communicating with redis server [%.*s] 
(%s:%d/%d): %s\n",
-                               rsrv->sname->len, rsrv->sname->s, addr, port, 
db,
-                               rsrv->ctxRedis->errstr);
-       }
-       if(init_without_redis == 1) {
-               LM_WARN("failed to initialize redis connections, but 
initializing"
-                               " module anyway.\n");
-               return 0;
-       }
+               return -1;
 
-       return -1;
-err:
-       if(sock != 0) {
-               LM_ERR("failed to connect to redis server [%.*s] (unix:%s 
db:%d)\n",
-                               rsrv->sname->len, rsrv->sname->s, 
unix_sock_path, db);
-       } else {
-               LM_ERR("failed to connect to redis server [%.*s] (%s:%d/%d)\n",
-                               rsrv->sname->len, rsrv->sname->s, addr, port, 
db);
-       }
-       if(init_without_redis == 1) {
-               LM_WARN("failed to initialize redis connections, but 
initializing"
-                               " module anyway.\n");
-               return 0;
-       }
+       err:
+               if(sock != 0) {
+                       LM_ERR("failed to connect to redis server [%.*s] 
(unix:%s db:%d)\n",
+                                       rsrv->sname->len, rsrv->sname->s, 
unix_sock_path, db);
+               } else {
+                       LM_ERR("failed to connect to redis server [%.*s] 
(%s:%d/%d)\n",
+                                       rsrv->sname->len, rsrv->sname->s, addr, 
port, db);
+               }
+               if(init_without_redis == 1) {
+                       /* Clean up resources once before deciding what to do */
+                       cleanup_redis_context(rsrv);
+
+                       /* Now decide whether to continue or return */
+                       if(rsrv->next != NULL) {
+                               LM_WARN("failed to connect to redis server 
[%.*s], trying next "
+                                               "server\n",
+                                               rsrv->sname->len, 
rsrv->sname->s);
+                               continue;
+                       } else {
+                               LM_WARN("failed to initialize redis 
connections, but "
+                                               "initializing"
+                                               " module anyway.\n");
+                               return 0;
+                       }
+               }
 
-       return -1;
+               return -1;
+       }
+       return 0;
 }
 
 /**

_______________________________________________
Kamailio - Development Mailing List -- [email protected]
To unsubscribe send an email to [email protected]
Important: keep the mailing list in the recipients, do not reply only to the 
sender!

Reply via email to