From e354d41e12ad0cabb63e84a7620cfac326f75cd9 Mon Sep 17 00:00:00 2001 From: fsantulli Date: Mon, 6 Jan 2020 18:02:12 +0100 Subject: [PATCH 1/5] Added missing KEMI functions, fixed sources loading and match_mode in check_whitelist function --- src/modules/userblacklist/userblacklist.c | 173 ++++++++++++++++++++-- 1 file changed, 162 insertions(+), 11 deletions(-) diff --git a/src/modules/userblacklist/userblacklist.c b/src/modules/userblacklist/userblacklist.c index 479c7bef813..b1189991c27 100644 --- a/src/modules/userblacklist/userblacklist.c +++ b/src/modules/userblacklist/userblacklist.c @@ -403,6 +403,34 @@ static struct dtrie_node_t *table2dt(const char *table) } +/** + * Prepares source d-tree table and loads data. + * \return entries count on success, -1 otherwise + */ +static int load_source(struct source_t *src) +{ + str tmp; + int result; + + if(!src || !src->table) { + LM_ERR("could not access source or no table defined\n"); + return -1; + } + + tmp.s = src->table; + tmp.len = strlen(src->table); + + result = db_reload_source(&tmp, src->dtrie_root); + if (result < 0) { + LM_ERR("cannot load source from '%.*s'\n", tmp.len, tmp.s); + return 0; + } + + LM_INFO("got %d entries from '%.*s'\n", result, tmp.len, tmp.s); + return result; +} + + /** * Adds a new table to the list, if the table is * already present, nothing will be done. @@ -413,7 +441,10 @@ static int add_source(const char *table) /* check if the table is already present */ struct source_t *src = sources->head; while (src) { - if (strcmp(table, src->table) == 0) return 0; + if (strcmp(table, src->table) == 0) { + LM_DBG("table %s is already present", src->table); + return 0; + } src = src->next; } @@ -424,6 +455,9 @@ static int add_source(const char *table) } memset(src, 0, sizeof(struct source_t)); + /* avoids dirty reads when adding source and d-tree */ + lock_get(lock); + src->next = sources->head; sources->head = src; @@ -431,6 +465,7 @@ static int add_source(const char *table) if (!src->table) { SHM_MEM_ERROR; shm_free(src); + lock_release(lock); return -1; } strcpy(src->table, table); @@ -440,9 +475,17 @@ static int add_source(const char *table) if (src->dtrie_root == NULL) { LM_ERR("could not initialize data"); + lock_release(lock); return -1; } + if(load_source(src) < 0) { + LM_ERR("could not load table data"); + lock_release(lock); + return -1; + } + + lock_release(lock); return 0; } @@ -474,6 +517,38 @@ static int check_globalblacklist_fixup(void** param, int param_no) return 0; } +static int ki_check_globalblacklist(sip_msg_t *msg) +{ + char * table = globalblacklist_table.s; + struct check_blacklist_fs_t* arg = NULL; + + if (!table) { + LM_ERR("no table name\n"); + return -1; + } + /* try to add the table */ + if (add_source(table) != 0) { + LM_ERR("could not add table"); + return -1; + } + + gnode = table2dt(table); + if (!gnode) { + LM_ERR("invalid table '%s'\n", table); + return -1; + } + + arg = pkg_malloc(sizeof(struct check_blacklist_fs_t)); + if (!arg) { + PKG_MEM_ERROR; + return -1; + } + memset(arg, 0, sizeof(struct check_blacklist_fs_t)); + arg->dtrie_root = gnode; + + return check_blacklist(msg, arg); +} + static int check_globalblacklist(sip_msg_t* msg) { static struct check_blacklist_fs_t* arg = NULL; @@ -529,6 +604,39 @@ static int check_blacklist_fixup(void **arg, int arg_no) return 0; } +static int ki_check_blacklist(sip_msg_t *msg, str* stable) +{ + struct dtrie_node_t *node = NULL; + struct check_blacklist_fs_t* arg = NULL; + + if(stable==NULL || stable->len<=0) { + LM_ERR("no table name\n"); + return -1; + } + + /* try to add the table */ + if (add_source(stable->s) != 0) { + LM_ERR("could not add table '%s'\n", stable->s); + return -1; + } + + /* get the node that belongs to the table */ + node = table2dt(stable->s); + if (!node) { + LM_ERR("invalid table '%s'\n", stable->s); + return -1; + } + + arg = pkg_malloc(sizeof(struct check_blacklist_fs_t)); + if (!arg) { + PKG_MEM_ERROR; + return -1; + } + memset(arg, 0, sizeof(struct check_blacklist_fs_t)); + arg->dtrie_root = node; + + return check_blacklist(msg, arg); +} static int check_blacklist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1) { @@ -578,6 +686,40 @@ static int check_blacklist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1) return ret; } +static int ki_check_whitelist(sip_msg_t *msg, str* stable) +{ + struct dtrie_node_t *node = NULL; + struct check_blacklist_fs_t* arg = NULL; + + if(stable==NULL || stable->len<=0) { + LM_ERR("no table name\n"); + return -1; + } + + /* try to add the table */ + if (add_source(stable->s) != 0) { + LM_ERR("could not add table '%s'\n", stable->s); + return -1; + } + + /* get the node that belongs to the table */ + node = table2dt(stable->s); + if (!node) { + LM_ERR("invalid table '%s'\n", stable->s); + return -1; + } + + arg = pkg_malloc(sizeof(struct check_blacklist_fs_t)); + if (!arg) { + PKG_MEM_ERROR; + return -1; + } + memset(arg, 0, sizeof(struct check_blacklist_fs_t)); + arg->dtrie_root = node; + + return check_whitelist(msg, arg); +} + static int check_whitelist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1) { void **nodeflags; @@ -599,7 +741,7 @@ static int check_whitelist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1) ptr = req_number; /* Skip over non-digits. */ - while (strlen(ptr) > 0 && !isdigit(*ptr)) { + while (match_mode == 10 && strlen(ptr) > 0 && !isdigit(*ptr)) { ptr = ptr + 1; } @@ -607,7 +749,7 @@ static int check_whitelist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1) /* avoids dirty reads when updating d-tree */ lock_get(lock); - nodeflags = dtrie_longest_match(arg1->dtrie_root, ptr, strlen(ptr), NULL, 10); + nodeflags = dtrie_longest_match(arg1->dtrie_root, ptr, strlen(ptr), NULL, match_mode); if (nodeflags) { if (*nodeflags == (void *)MARK_WHITELIST) { /* LM_DBG("whitelisted"); */ @@ -633,24 +775,18 @@ static int check_whitelist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1) static int reload_sources(void) { int result = 0; - str tmp; struct source_t *src; - int n; /* critical section start: avoids dirty reads when updating d-tree */ lock_get(lock); src = sources->head; while (src) { - tmp.s = src->table; - tmp.len = strlen(src->table); - n = db_reload_source(&tmp, src->dtrie_root); - if (n < 0) { - LM_ERR("cannot reload source from '%.*s'\n", tmp.len, tmp.s); + LM_INFO("Reloading source table '%s' with dtrie root '%p'\n", src->table, src->dtrie_root); + if(load_source(src) < 0) { result = -1; break; } - LM_INFO("got %d entries from '%.*s'\n", n, tmp.len, tmp.s); src = src->next; } @@ -1225,6 +1361,21 @@ static sr_kemi_t sr_kemi_userblacklist_exports[] = { { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE } }, + { str_init("userblacklist"), str_init("check_whitelist"), + SR_KEMIP_INT, ki_check_whitelist, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("userblacklist"), str_init("check_blacklist"), + SR_KEMIP_INT, ki_check_blacklist, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("userblacklist"), str_init("check_global_blacklist"), + SR_KEMIP_INT, ki_check_globalblacklist, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } } }; From d5294563c3be9bcc7e21579c1fdf59af2e3a8cc0 Mon Sep 17 00:00:00 2001 From: fsantulli Date: Mon, 6 Jan 2020 18:29:20 +0100 Subject: [PATCH 2/5] Added pkg_free at returning of check_whitelist and check_blacklist functions. --- src/modules/userblacklist/userblacklist.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/modules/userblacklist/userblacklist.c b/src/modules/userblacklist/userblacklist.c index b1189991c27..24854c7c530 100644 --- a/src/modules/userblacklist/userblacklist.c +++ b/src/modules/userblacklist/userblacklist.c @@ -647,11 +647,13 @@ static int check_blacklist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1) if (msg->first_line.type != SIP_REQUEST) { LM_ERR("SIP msg is not a request\n"); + pkg_free(arg1); return -1; } if ((parse_sip_msg_uri(msg) < 0) || (!msg->parsed_uri.user.s) || (msg->parsed_uri.user.len > MAXNUMBERLEN)) { LM_ERR("cannot parse msg URI\n"); + pkg_free(arg1); return -1; } strncpy(req_number, msg->parsed_uri.user.s, msg->parsed_uri.user.len); @@ -683,6 +685,8 @@ static int check_blacklist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1) } lock_release(lock); + pkg_free(arg1); + return ret; } @@ -729,11 +733,13 @@ static int check_whitelist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1) if (msg->first_line.type != SIP_REQUEST) { LM_ERR("SIP msg is not a request\n"); + pkg_free(arg1); return -1; } if ((parse_sip_msg_uri(msg) < 0) || (!msg->parsed_uri.user.s) || (msg->parsed_uri.user.len > MAXNUMBERLEN)) { LM_ERR("cannot parse msg URI\n"); + pkg_free(arg1); return -1; } strncpy(req_number, msg->parsed_uri.user.s, msg->parsed_uri.user.len); @@ -765,6 +771,8 @@ static int check_whitelist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1) } lock_release(lock); + pkg_free(arg1); + return ret; } From 08a17afe1c18ab0f54287b7fb9d22bedad94983d Mon Sep 17 00:00:00 2001 From: fsantulli Date: Mon, 6 Jan 2020 18:44:32 +0100 Subject: [PATCH 3/5] userblacklist: moved pkg_free to kemi functions instead of native ones. --- src/modules/userblacklist/userblacklist.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/modules/userblacklist/userblacklist.c b/src/modules/userblacklist/userblacklist.c index 24854c7c530..992e43d3bca 100644 --- a/src/modules/userblacklist/userblacklist.c +++ b/src/modules/userblacklist/userblacklist.c @@ -608,6 +608,7 @@ static int ki_check_blacklist(sip_msg_t *msg, str* stable) { struct dtrie_node_t *node = NULL; struct check_blacklist_fs_t* arg = NULL; + int result; if(stable==NULL || stable->len<=0) { LM_ERR("no table name\n"); @@ -635,7 +636,10 @@ static int ki_check_blacklist(sip_msg_t *msg, str* stable) memset(arg, 0, sizeof(struct check_blacklist_fs_t)); arg->dtrie_root = node; - return check_blacklist(msg, arg); + result = check_blacklist(msg, arg); + pkg_free(arg); + + return result; } static int check_blacklist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1) @@ -647,13 +651,11 @@ static int check_blacklist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1) if (msg->first_line.type != SIP_REQUEST) { LM_ERR("SIP msg is not a request\n"); - pkg_free(arg1); return -1; } if ((parse_sip_msg_uri(msg) < 0) || (!msg->parsed_uri.user.s) || (msg->parsed_uri.user.len > MAXNUMBERLEN)) { LM_ERR("cannot parse msg URI\n"); - pkg_free(arg1); return -1; } strncpy(req_number, msg->parsed_uri.user.s, msg->parsed_uri.user.len); @@ -685,8 +687,6 @@ static int check_blacklist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1) } lock_release(lock); - pkg_free(arg1); - return ret; } @@ -694,6 +694,7 @@ static int ki_check_whitelist(sip_msg_t *msg, str* stable) { struct dtrie_node_t *node = NULL; struct check_blacklist_fs_t* arg = NULL; + int result; if(stable==NULL || stable->len<=0) { LM_ERR("no table name\n"); @@ -721,7 +722,10 @@ static int ki_check_whitelist(sip_msg_t *msg, str* stable) memset(arg, 0, sizeof(struct check_blacklist_fs_t)); arg->dtrie_root = node; - return check_whitelist(msg, arg); + result = check_whitelist(msg, arg); + pkg_free(arg); + + return result; } static int check_whitelist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1) @@ -733,13 +737,11 @@ static int check_whitelist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1) if (msg->first_line.type != SIP_REQUEST) { LM_ERR("SIP msg is not a request\n"); - pkg_free(arg1); return -1; } if ((parse_sip_msg_uri(msg) < 0) || (!msg->parsed_uri.user.s) || (msg->parsed_uri.user.len > MAXNUMBERLEN)) { LM_ERR("cannot parse msg URI\n"); - pkg_free(arg1); return -1; } strncpy(req_number, msg->parsed_uri.user.s, msg->parsed_uri.user.len); @@ -771,8 +773,6 @@ static int check_whitelist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1) } lock_release(lock); - pkg_free(arg1); - return ret; } From 5f14c488d9ac416864562f888c40e4f005307c3f Mon Sep 17 00:00:00 2001 From: fsantulli Date: Mon, 6 Jan 2020 19:48:31 +0100 Subject: [PATCH 4/5] userblacklist: fixed rpc_child_init behaviour as changed add_source routine, fixup must be called after db is open. --- src/modules/userblacklist/userblacklist.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/modules/userblacklist/userblacklist.c b/src/modules/userblacklist/userblacklist.c index 992e43d3bca..469dfa2d0fe 100644 --- a/src/modules/userblacklist/userblacklist.c +++ b/src/modules/userblacklist/userblacklist.c @@ -1301,11 +1301,6 @@ static int blacklist_child_initialized = 0; static int rpc_child_init(void) { - /* global blacklist init */ - if (check_globalblacklist_fixup(NULL, 0) != 0) { - LM_ERR("could not add global table when init the module"); - } - /* user blacklist init */ if(userblacklist_child_initialized) return 0; @@ -1316,6 +1311,11 @@ static int rpc_child_init(void) return -1; } + /* global blacklist init */ + if (check_globalblacklist_fixup(NULL, 0) != 0) { + LM_ERR("could not add global table when init the module"); + } + /* because we've added new sources during the fixup */ if (reload_sources() != 0) return -1; From fbc8598ffc4e3c9706c25ac9d5e608c86a2005be Mon Sep 17 00:00:00 2001 From: fsantulli Date: Mon, 6 Jan 2020 20:18:35 +0100 Subject: [PATCH 5/5] userblacklist: added missing pkg_free before returning ki_check_globalblacklist result. --- src/modules/userblacklist/userblacklist.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/modules/userblacklist/userblacklist.c b/src/modules/userblacklist/userblacklist.c index 469dfa2d0fe..c1b04e1747a 100644 --- a/src/modules/userblacklist/userblacklist.c +++ b/src/modules/userblacklist/userblacklist.c @@ -521,6 +521,7 @@ static int ki_check_globalblacklist(sip_msg_t *msg) { char * table = globalblacklist_table.s; struct check_blacklist_fs_t* arg = NULL; + int result; if (!table) { LM_ERR("no table name\n"); @@ -546,7 +547,10 @@ static int ki_check_globalblacklist(sip_msg_t *msg) memset(arg, 0, sizeof(struct check_blacklist_fs_t)); arg->dtrie_root = gnode; - return check_blacklist(msg, arg); + result = check_blacklist(msg, arg); + pkg_free(arg); + + return result; } static int check_globalblacklist(sip_msg_t* msg)