diff --git a/daemon/cli.c b/daemon/cli.c index 6f97a446b..e48d60a23 100644 --- a/daemon/cli.c +++ b/daemon/cli.c @@ -312,7 +312,7 @@ RTPE_CONFIG_UINT64_PARAMS } count=0; for (__auto_type s = initial_rtpe_config.redis_subscribed_keyspaces.head; s ; s = s->next) { - cw->cw_printf(cw, "keyspace[%d] = %d\n", count, GPOINTER_TO_UINT(s->data)); + cw->cw_printf(cw, "keyspace[%d] = %d\n", count, GPOINTER_TO_INT(s->data)); ++count; } @@ -364,7 +364,7 @@ RTPE_CONFIG_UINT64_PARAMS } count=0; for (__auto_type c = rtpe_config.redis_subscribed_keyspaces.head; c ; c = c->next) { - cw->cw_printf(cw, "keyspace[%d] = %d\n", count, GPOINTER_TO_UINT(c->data)); + cw->cw_printf(cw, "keyspace[%d] = %d\n", count, GPOINTER_TO_INT(c->data)); ++count; } @@ -1043,7 +1043,7 @@ static void cli_incoming_terminate(str *instr, struct cli_writer *cw) { } static void cli_incoming_ksadd(str *instr, struct cli_writer *cw) { - unsigned long uint_keyspace_db; + long int_keyspace_db; char *endptr; if (!rtpe_redis_notify) { @@ -1057,28 +1057,30 @@ static void cli_incoming_ksadd(str *instr, struct cli_writer *cw) { } errno = 0; - uint_keyspace_db = strtoul(instr->s, &endptr, 10); + int_keyspace_db = strtol(instr->s, &endptr, 10); - if ((errno == ERANGE && (uint_keyspace_db == ULONG_MAX)) || (errno != 0 && uint_keyspace_db == 0)) { - cw->cw_printf(cw, "Fail adding keyspace %s to redis notifications; errno=%d\n", instr->s, errno); + if ((errno == ERANGE && (int_keyspace_db == ULONG_MAX)) || int_keyspace_db >= INT_MAX + || int_keyspace_db < 0 + || (errno != 0 && int_keyspace_db == 0)) { + cw->cw_printf(cw, "Fail adding keyspace " STR_FORMAT " to redis notifications; errno=%d\n", STR_FMT(instr), errno); } else if (endptr == instr->s) { - cw->cw_printf(cw, "Fail adding keyspace %s to redis notifications; no digits found\n", instr->s); + cw->cw_printf(cw, "Fail adding keyspace " STR_FORMAT " to redis notifications; no digits found\n", STR_FMT(instr)); } else { rwlock_lock_w(&rtpe_config.keyspaces_lock); - if (!g_queue_find(&rtpe_config.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db))) { - g_queue_push_tail(&rtpe_config.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db)); - redis_notify_subscribe_action(rtpe_redis_notify, SUBSCRIBE_KEYSPACE, uint_keyspace_db); - cw->cw_printf(cw, "Success adding keyspace %lu to redis notifications.\n", uint_keyspace_db); + if (!g_queue_find(&rtpe_config.redis_subscribed_keyspaces, GINT_TO_POINTER(int_keyspace_db))) { + g_queue_push_tail(&rtpe_config.redis_subscribed_keyspaces, GINT_TO_POINTER(int_keyspace_db)); + redis_notify_subscribe_action(rtpe_redis_notify, SUBSCRIBE_KEYSPACE, int_keyspace_db); + cw->cw_printf(cw, "Success adding keyspace %ld to redis notifications.\n", int_keyspace_db); } else { - cw->cw_printf(cw, "Keyspace %lu is already among redis notifications.\n", uint_keyspace_db); + cw->cw_printf(cw, "Keyspace %ld is already among redis notifications.\n", int_keyspace_db); } rwlock_unlock_w(&rtpe_config.keyspaces_lock); } } static void cli_incoming_ksrm(str *instr, struct cli_writer *cw) { - GList *l; - unsigned long uint_keyspace_db; + GList *l; + long int_keyspace_db; char *endptr; if (!rtpe_redis_notify) { @@ -1092,26 +1094,28 @@ static void cli_incoming_ksrm(str *instr, struct cli_writer *cw) { } errno = 0; - uint_keyspace_db = strtoul(instr->s, &endptr, 10); + int_keyspace_db = strtol(instr->s, &endptr, 10); rwlock_lock_w(&rtpe_config.keyspaces_lock); - if ((errno == ERANGE && (uint_keyspace_db == ULONG_MAX)) || (errno != 0 && uint_keyspace_db == 0)) { - cw->cw_printf(cw, "Fail removing keyspace %s to redis notifications; errno=%d\n", instr->s, errno); + if ((errno == ERANGE && (int_keyspace_db == ULONG_MAX)) || int_keyspace_db >= INT_MAX + || int_keyspace_db < 0 + || (errno != 0 && int_keyspace_db == 0)) { + cw->cw_printf(cw, "Fail removing keyspace " STR_FORMAT " to redis notifications; errno=%d\n", STR_FMT(instr), errno); } else if (endptr == instr->s) { - cw->cw_printf(cw, "Fail removing keyspace %s to redis notifications; no digits found\n", instr->s); - } else if ((l = g_queue_find(&rtpe_config.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db)))) { + cw->cw_printf(cw, "Fail removing keyspace " STR_FORMAT " to redis notifications; no digits found\n", STR_FMT(instr)); + } else if ((l = g_queue_find(&rtpe_config.redis_subscribed_keyspaces, GINT_TO_POINTER(int_keyspace_db)))) { // remove this keyspace - redis_notify_subscribe_action(rtpe_redis_notify, UNSUBSCRIBE_KEYSPACE, uint_keyspace_db); + redis_notify_subscribe_action(rtpe_redis_notify, UNSUBSCRIBE_KEYSPACE, int_keyspace_db); g_queue_remove(&rtpe_config.redis_subscribed_keyspaces, l->data); - cw->cw_printf(cw, "Successfully unsubscribed from keyspace %lu.\n", uint_keyspace_db); + cw->cw_printf(cw, "Successfully unsubscribed from keyspace %lu.\n", int_keyspace_db); // destroy foreign calls for this keyspace - destroy_keyspace_foreign_calls(uint_keyspace_db); + destroy_keyspace_foreign_calls(int_keyspace_db); // update cli - cw->cw_printf(cw, "Successfully removed all foreign calls for keyspace %lu.\n", uint_keyspace_db); + cw->cw_printf(cw, "Successfully removed all foreign calls for keyspace %ld.\n", int_keyspace_db); } else { - cw->cw_printf(cw, "Keyspace %lu is not among redis notifications.\n", uint_keyspace_db); + cw->cw_printf(cw, "Keyspace %ld is not among redis notifications.\n", int_keyspace_db); } rwlock_unlock_w(&rtpe_config.keyspaces_lock); @@ -1129,7 +1133,7 @@ static void cli_incoming_kslist(str *instr, struct cli_writer *cw) { rwlock_lock_r(&rtpe_config.keyspaces_lock); for (l = rtpe_config.redis_subscribed_keyspaces.head; l; l = l->next) { - cw->cw_printf(cw, "%u ", GPOINTER_TO_UINT(l->data)); + cw->cw_printf(cw, "%d ", GPOINTER_TO_INT(l->data)); } rwlock_unlock_r(&rtpe_config.keyspaces_lock); diff --git a/daemon/main.c b/daemon/main.c index 4c770c94c..0e0789943 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -377,19 +377,21 @@ static int redis_ep_parse(endpoint_t *ep, int *db, char **hostname, char **auth, else if ((sl = getenv(auth_env))) *auth = g_strdup(sl); - sl = strchr(s, '/'); - if (!sl) - return -1; - *sl = 0; - sl++; - if (!*sl) - return -1; - l = strtol(sl, &sl, 10); - if (*sl != 0) - return -1; - if (l < 0) - return -1; - *db = l; + if (db) { + sl = strchr(s, '/'); + if (!sl) + return -1; + *sl = 0; + sl++; + if (!*sl) + return -1; + l = strtol(sl, &sl, 10); + if (*sl != 0) + return -1; + if (l < 0) + return -1; + *db = l; + } /* copy for the case with re-resolve during re-connections */ sp = strrchr(s, ':'); /* make sure to not take port into the value of hostname */ @@ -488,7 +490,7 @@ static void release_listeners(GQueue *q) { static void options(int *argc, char ***argv, GHashTable *templates) { g_autoptr(char_p) if_a = NULL; g_autoptr(char_p) ks_a = NULL; - unsigned long uint_keyspace_db; + long int_keyspace_db; str str_keyspace_db; char **iter; g_autoptr(char_p) listenps = NULL; @@ -795,15 +797,15 @@ static void options(int *argc, char ***argv, GHashTable *templates) { if (ks_a) { for (iter = ks_a; *iter; iter++) { str_keyspace_db = STR(*iter); - uint_keyspace_db = strtoul(str_keyspace_db.s, &endptr, 10); + int_keyspace_db = strtol(str_keyspace_db.s, &endptr, 10); - if ((errno == ERANGE && (uint_keyspace_db == ULONG_MAX)) || - (errno != 0 && uint_keyspace_db == 0)) { + if ((errno == ERANGE && (int_keyspace_db == ULONG_MAX)) || int_keyspace_db >= INT_MAX || + (errno != 0 && int_keyspace_db == 0)) { ilog(LOG_ERR, "Fail adding keyspace '" STR_FORMAT "' to redis notifications; errno=%d\n", STR_FMT(&str_keyspace_db), errno); } else if (endptr == str_keyspace_db.s) { ilog(LOG_ERR, "Fail adding keyspace '" STR_FORMAT "' to redis notifications; no digits found\n", STR_FMT(&str_keyspace_db)); } else { - g_queue_push_tail(&rtpe_config.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db)); + g_queue_push_tail(&rtpe_config.redis_subscribed_keyspaces, GINT_TO_POINTER(int_keyspace_db)); } } } @@ -1143,7 +1145,7 @@ static void fill_initial_rtpe_cfg(struct rtpengine_config* ini_rtpe_cfg) { for (__auto_type l = rtpe_config.redis_subscribed_keyspaces.head; l ; l = l->next) { // l->data has been assigned to a variable before being given into the queue structure not to get a shallow copy - unsigned int num = GPOINTER_TO_UINT(l->data); + int num = GPOINTER_TO_INT(l->data); g_queue_push_tail(&ini_rtpe_cfg->redis_subscribed_keyspaces, GINT_TO_POINTER(num)); } @@ -1464,6 +1466,8 @@ static void do_redis_restore(void) { for (GList *l = rtpe_config.redis_subscribed_keyspaces.head; l; l = l->next) { int db = GPOINTER_TO_INT(l->data); + if (db < 0) + continue; if (redis_restore(r, true, db)) ilog(LOG_WARN, "Unable to restore calls from the active-active peer"); } diff --git a/daemon/redis.c b/daemon/redis.c index 8ea220eed..f891efde7 100644 --- a/daemon/redis.c +++ b/daemon/redis.c @@ -776,7 +776,10 @@ static int redis_notify(struct redis *r) { // subscribe to the values in the configured keyspaces rwlock_lock_r(&rtpe_config.keyspaces_lock); for (l = rtpe_config.redis_subscribed_keyspaces.head; l; l = l->next) { - redis_notify_subscribe_action(r, SUBSCRIBE_KEYSPACE, GPOINTER_TO_INT(l->data)); + int id = GPOINTER_TO_INT(l->data); + if (id < 0) + continue; + redis_notify_subscribe_action(r, SUBSCRIBE_KEYSPACE, id); } rwlock_unlock_r(&rtpe_config.keyspaces_lock); diff --git a/docs/rtpengine.md b/docs/rtpengine.md index e628beecf..a5e15d6db 100644 --- a/docs/rtpengine.md +++ b/docs/rtpengine.md @@ -542,6 +542,12 @@ call to inject-DTMF won't be sent to __\-\-dtmf-log-dest=__ or __\-\-listen-tcp- Further subscriptions could be added/removed via __rtpengine-ctl ksadd/ksrm__. This may lead to enabling/disabling of the redis keyspace notification feature. + The list of keyspace subscriptions can initially be left empty, but if any + keyspaces are to be added later during runtime, the feature must still be + configured at *rtpengine* startup. This can be achieved by either setting + __\-\-redis-subscribe=__ to a valid address, or by listing the single value + __-1__ under __\-\-subscribe-keyspace=__. + - __\-\-redis-num-threads=__*INT* How many redis restore threads to create.