MT#58547 lcr_rate: use gw_id field from gw_uri_avp for load_peers()

* merge lcr_rate patches
* format code with kamailio clang definitions

Change-Id: Ic20e9e535ca0f904b5f497468ddcf26abcb9fa2a
(cherry picked from commit 8be5217b1f)
(cherry picked from commit 294dbd880c)
(cherry picked from commit 8d3188eec9)
(cherry picked from commit 74f8ce7601)
mr11.5.1
Victor Seva 10 months ago
parent e6676a5873
commit 366a7ad764

@ -11,7 +11,6 @@ sipwise/parallel_build.patch
## New Modules ## New Modules
sipwise/add_pcem_module.patch sipwise/add_pcem_module.patch
sipwise/add_lcr_rate_module.patch sipwise/add_lcr_rate_module.patch
sipwise/fix_lcr_rate_wrong_id.patch
sipwise/add_tcap_module.patch sipwise/add_tcap_module.patch
sipwise/add_presence_dfks_module.patch sipwise/add_presence_dfks_module.patch
sipwise/presence_dfks_null_ptr_fixes.patch sipwise/presence_dfks_null_ptr_fixes.patch

@ -7,8 +7,8 @@ Subject: add_lcr_rate_module
src/core/mod_fix.c | 3 + src/core/mod_fix.c | 3 +
src/core/mod_fix.h | 2 + src/core/mod_fix.h | 2 +
src/modules/lcr_rate/Makefile | 9 + src/modules/lcr_rate/Makefile | 9 +
src/modules/lcr_rate/lcr_rate_mod.c | 473 ++++++++++++++++++++++++++++++++++++ src/modules/lcr_rate/lcr_rate_mod.c | 517 ++++++++++++++++++++++++++++++++++++
5 files changed, 494 insertions(+), 2 deletions(-) 5 files changed, 538 insertions(+), 2 deletions(-)
create mode 100644 src/modules/lcr_rate/Makefile create mode 100644 src/modules/lcr_rate/Makefile
create mode 100644 src/modules/lcr_rate/lcr_rate_mod.c create mode 100644 src/modules/lcr_rate/lcr_rate_mod.c
@ -97,10 +97,10 @@ index 0000000..9a3cee1
+include ../../Makefile.modules +include ../../Makefile.modules
diff --git a/src/modules/lcr_rate/lcr_rate_mod.c b/src/modules/lcr_rate/lcr_rate_mod.c diff --git a/src/modules/lcr_rate/lcr_rate_mod.c b/src/modules/lcr_rate/lcr_rate_mod.c
new file mode 100644 new file mode 100644
index 0000000..f3a9ab2 index 0000000..5670871
--- /dev/null --- /dev/null
+++ b/src/modules/lcr_rate/lcr_rate_mod.c +++ b/src/modules/lcr_rate/lcr_rate_mod.c
@@ -0,0 +1,473 @@ @@ -0,0 +1,517 @@
+/* +/*
+ * call rating for least cost routing module + * call rating for least cost routing module
+ * + *
@ -138,7 +138,8 @@ index 0000000..f3a9ab2
+ +
+MODULE_VERSION +MODULE_VERSION
+ +
+struct peer { +struct peer
+{
+ int valid; + int valid;
+ unsigned int id; + unsigned int id;
+ double cost; + double cost;
@ -151,10 +152,25 @@ index 0000000..f3a9ab2
+static int child_init(int rank); +static int child_init(int rank);
+ +
+static int lcr_rate(sip_msg_t *msg, char *su, char *sq); +static int lcr_rate(sip_msg_t *msg, char *su, char *sq);
+static int lcr_get_prepaid_from_uuid(sip_msg_t *msg, char *uuid, char *avp, char *avp2); +static int lcr_get_prepaid_from_uuid(
+ sip_msg_t *msg, char *uuid, char *avp, char *avp2);
+static int lcr_get_prepaid_from_uuid2(sip_msg_t *msg, char *uuid, char *avp); +static int lcr_get_prepaid_from_uuid2(sip_msg_t *msg, char *uuid, char *avp);
+static int lcr_get_profile_id_from_uuid(sip_msg_t *msg, char *uuid, char *avp); +static int lcr_get_profile_id_from_uuid(sip_msg_t *msg, char *uuid, char *avp);
+ +
+static char *gw_uri_avp_param;
+static int gw_uri_avp_type;
+static int_str gw_uri_avp;
+
+static char *db_host;
+static unsigned int db_port;
+static char *db_user;
+static char *db_pass;
+static char *db_db;
+
+static int swrate_done;
+static SWRATE *swrate_ptr;
+
+/* clang-format off */
+static cmd_export_t cmds[] = { +static cmd_export_t cmds[] = {
+ {"lcr_rate", lcr_rate, 2, fixup_spve_spve, 0, + {"lcr_rate", lcr_rate, 2, fixup_spve_spve, 0,
+ REQUEST_ROUTE | FAILURE_ROUTE}, + REQUEST_ROUTE | FAILURE_ROUTE},
@ -167,16 +183,6 @@ index 0000000..f3a9ab2
+ {0,} + {0,}
+}; +};
+ +
+static char *gw_uri_avp_param;
+static int gw_uri_avp_type;
+static int_str gw_uri_avp;
+
+static char *db_host;
+static unsigned int db_port;
+static char *db_user;
+static char *db_pass;
+static char *db_db;
+
+static param_export_t params[] = { +static param_export_t params[] = {
+ {"gw_uri_avp", STR_PARAM, &gw_uri_avp_param}, + {"gw_uri_avp", STR_PARAM, &gw_uri_avp_param},
+ {"db_host", STR_PARAM, &db_host}, + {"db_host", STR_PARAM, &db_host},
@ -187,9 +193,6 @@ index 0000000..f3a9ab2
+ {0,}, + {0,},
+}; +};
+ +
+static int swrate_done;
+static SWRATE *swrate_ptr;
+
+struct module_exports exports = { +struct module_exports exports = {
+ "lcr_rate", /* module name */ + "lcr_rate", /* module name */
+ DEFAULT_DLFLAGS, /* dlopen flags */ + DEFAULT_DLFLAGS, /* dlopen flags */
@ -202,8 +205,10 @@ index 0000000..f3a9ab2
+ child_init, /* per-child init function */ + child_init, /* per-child init function */
+ mod_destroy /* module destroy function */ + mod_destroy /* module destroy function */
+}; +};
+/* clang-format on */
+ +
+static int mod_init() { +static int mod_init()
+{
+ pv_spec_t avp_spec; + pv_spec_t avp_spec;
+ str s; + str s;
+ unsigned short avp_flags; + unsigned short avp_flags;
@ -230,18 +235,22 @@ index 0000000..f3a9ab2
+ return 0; + return 0;
+} +}
+ +
+static int child_init(int rank) { +static int child_init(int rank)
+{
+ return 0; + return 0;
+} +}
+ +
+static void mod_destroy() { +static void mod_destroy()
+ ; +{
+ return;
+} +}
+ +
+static int check_swrate_init() { +static int check_swrate_init()
+{
+ if(swrate_done) + if(swrate_done)
+ return 0; + return 0;
+ swrate_ptr = swrate_new(db_host, db_port, db_db, db_user, db_pass, NULL, 0, 1, 0); + swrate_ptr = swrate_new(
+ db_host, db_port, db_db, db_user, db_pass, NULL, 0, 1, 0);
+ if(!swrate_ptr || !swrate_new_ok(swrate_ptr)) { + if(!swrate_ptr || !swrate_new_ok(swrate_ptr)) {
+ LM_ERR("failed to initialized libswrate\n"); + LM_ERR("failed to initialized libswrate\n");
+ if(swrate_ptr) + if(swrate_ptr)
@ -252,18 +261,20 @@ index 0000000..f3a9ab2
+ return 0; + return 0;
+} +}
+ +
+static struct peer *load_peers(int *num, char *src_user, char *src_domain, char *dst_user, char *dst_domain) { +static struct peer *load_peers(int *num, char *src_user, char *src_domain,
+ char *dst_user, char *dst_domain)
+{
+ struct usr_avp *avp; + struct usr_avp *avp;
+ int_str val; + int_str val;
+ struct peer *ret, *j; + struct peer *ret, *j;
+ int len, i; + int len, i, k;
+ char *c; + char *c;
+ str s; + str s;
+ swr_rate_t rate; + swr_rate_t rate;
+ time_t now; + time_t now;
+ +
+ LM_DBG("loading peers for user <%s>@<%s> -> <%s>@<%s> from avp\n", + LM_DBG("loading peers for user <%s>@<%s> -> <%s>@<%s> from avp\n", src_user,
+ src_user, src_domain, dst_user, dst_domain); + src_domain, dst_user, dst_domain);
+ +
+ len = 4; + len = 4;
+ ret = pkg_malloc(len * sizeof(*ret)); + ret = pkg_malloc(len * sizeof(*ret));
@ -301,15 +312,40 @@ index 0000000..f3a9ab2
+ return NULL; + return NULL;
+ } + }
+ memcpy(j->s.s, val.s.s, val.s.len); + memcpy(j->s.s, val.s.s, val.s.len);
+ c = memrchr(j->s.s, '|', val.s.len); +
+ /* lcr gw fields:
+ * 0: gw index
+ * 1: scheme
+ * 2: strip
+ * 3: prefix
+ * 4: tag
+ * 5: ip adr
+ * 6: hostname
+ * 7: port
+ * 8: params
+ * 9: transport
+ * 10: flags
+ * 11: rule id
+ * 12: gw id
+ */
+ c = j->s.s;
+ for(k = 0; k < 12; k++) {
+ c = memchr(c, '|', val.s.len - (c - j->s.s));
+ if(!c) { + if(!c) {
+ LM_ERR("separator not found in string <%.*s>\n", val.s.len, j->s.s); + LM_ERR("separator not found in string <%.*s> (field #%i)\n",
+ val.s.len, j->s.s, k);
+ goto next; + goto next;
+ } + }
+
+ c++; + c++;
+ }
+
+ s.s = c; + s.s = c;
+ s.len = val.s.len - (c - j->s.s); +
+ /* find terminator */
+ c = memchr(c, '|', val.s.len - (c - j->s.s));
+ if(!c)
+ c = j->s.s + val.s.len;
+ s.len = c - s.s;
+ if(str2int(&s, &j->id)) { + if(str2int(&s, &j->id)) {
+ LM_ERR("could not convert string <%.*s> to int\n", s.len, s.s); + LM_ERR("could not convert string <%.*s> to int\n", s.len, s.s);
+ goto next; + goto next;
@ -320,7 +356,8 @@ index 0000000..f3a9ab2
+ +
+ if(swrate_get_peer_ab_rate(&rate, swrate_ptr, j->id, src_user, + if(swrate_get_peer_ab_rate(&rate, swrate_ptr, j->id, src_user,
+ src_domain, dst_user, dst_domain, now)) { + src_domain, dst_user, dst_domain, now)) {
+ LM_ERR("failed to get rate for call, peer id %u, user <%s>@<%s> -> <%s>@<%s>\n", + LM_ERR("failed to get rate for call, peer id %u, user <%s>@<%s> -> "
+ "<%s>@<%s>\n",
+ j->id, src_user, src_domain, dst_user, dst_domain); + j->id, src_user, src_domain, dst_user, dst_domain);
+ goto next; + goto next;
+ } + }
@ -337,7 +374,8 @@ index 0000000..f3a9ab2
+ return ret; + return ret;
+} +}
+ +
+static int peers_cmp(const void *aa, const void *bb) { +static int peers_cmp(const void *aa, const void *bb)
+{
+ const struct peer *a = aa, *b = bb; + const struct peer *a = aa, *b = bb;
+ +
+ if(a->valid && !b->valid) + if(a->valid && !b->valid)
@ -360,7 +398,8 @@ index 0000000..f3a9ab2
+ return 0; + return 0;
+} +}
+ +
+static int save_peers(struct peer *peers, int num) { +static int save_peers(struct peer *peers, int num)
+{
+ int i; + int i;
+ int_str val; + int_str val;
+ +
@ -376,7 +415,8 @@ index 0000000..f3a9ab2
+ return 0; + return 0;
+} +}
+ +
+static void extract_ud(str *s, char **user, char **at, char **domain) { +static void extract_ud(str *s, char **user, char **at, char **domain)
+{
+ *user = *at = *domain = NULL; + *user = *at = *domain = NULL;
+ if(!s || !s->s || !*s->s) + if(!s || !s->s || !*s->s)
+ return; + return;
@ -390,7 +430,8 @@ index 0000000..f3a9ab2
+ *domain = NULL; + *domain = NULL;
+} +}
+ +
+static int lcr_rate(sip_msg_t *msg, char *su, char *sq) { +static int lcr_rate(sip_msg_t *msg, char *su, char *sq)
+{
+ struct peer *peers; + struct peer *peers;
+ int num_peers, ret; + int num_peers, ret;
+ str src, dst; + str src, dst;
@ -434,26 +475,24 @@ index 0000000..f3a9ab2
+ return ret; + return ret;
+} +}
+ +
+static int get_avp(unsigned short *avp_type, int_str *avp_name, char *avp_s) { +static int get_avp(unsigned short *avp_type, int_str *avp_name, char *avp_s)
+{
+ pv_spec_t *avp_spec = NULL; + pv_spec_t *avp_spec = NULL;
+ str *avp; + str *avp;
+ +
+ avp = (str *)avp_s; + avp = (str *)avp_s;
+ +
+ if (pv_locate_name(avp) != avp->len) + if(pv_locate_name(avp) != avp->len) {
+ {
+ LM_ERR("invalid AVP parameter\n"); + LM_ERR("invalid AVP parameter\n");
+ return -1; + return -1;
+ } + }
+ +
+ if (((avp_spec = pv_cache_get(avp)) == NULL) + if(((avp_spec = pv_cache_get(avp)) == NULL) || avp_spec->type != PVT_AVP) {
+ || avp_spec->type!=PVT_AVP) {
+ LM_ERR("malformed or non AVP %s AVP definition\n", avp->s); + LM_ERR("malformed or non AVP %s AVP definition\n", avp->s);
+ return -1; + return -1;
+ } + }
+ +
+ if(pv_get_avp_name(0, &avp_spec->pvp, avp_name, avp_type)!=0) + if(pv_get_avp_name(0, &avp_spec->pvp, avp_name, avp_type) != 0) {
+ {
+ LM_ERR("[%s]- invalid AVP definition\n", avp->s); + LM_ERR("[%s]- invalid AVP definition\n", avp->s);
+ return -1; + return -1;
+ } + }
@ -461,7 +500,9 @@ index 0000000..f3a9ab2
+ return 0; + return 0;
+} +}
+ +
+static int get_profile_from_uuid(swr_profile_t *prof, sip_msg_t *msg, char *uuid_s) { +static int get_profile_from_uuid(
+ swr_profile_t *prof, sip_msg_t *msg, char *uuid_s)
+{
+ char *pc, *ip; + char *pc, *ip;
+ str uuid; + str uuid;
+ +
@ -490,7 +531,8 @@ index 0000000..f3a9ab2
+ ip = pc + 1; + ip = pc + 1;
+ } + }
+ +
+ if (swrate_get_subscriber_billing_profile(prof, swrate_ptr, time(NULL), uuid.s, ip)) { + if(swrate_get_subscriber_billing_profile(
+ prof, swrate_ptr, time(NULL), uuid.s, ip)) {
+ LM_ERR("swrate call returned error\n"); + LM_ERR("swrate call returned error\n");
+ return -1; + return -1;
+ } + }
@ -498,11 +540,14 @@ index 0000000..f3a9ab2
+ return 0; + return 0;
+} +}
+ +
+static int lcr_get_prepaid_from_uuid2(sip_msg_t *msg, char *uuid_s, char *avp_s) { +static int lcr_get_prepaid_from_uuid2(sip_msg_t *msg, char *uuid_s, char *avp_s)
+{
+ return lcr_get_prepaid_from_uuid(msg, uuid_s, avp_s, NULL); + return lcr_get_prepaid_from_uuid(msg, uuid_s, avp_s, NULL);
+} +}
+ +
+static int lcr_get_prepaid_from_uuid(sip_msg_t *msg, char *uuid_s, char *avp_s, char *avp2_s) { +static int lcr_get_prepaid_from_uuid(
+ sip_msg_t *msg, char *uuid_s, char *avp_s, char *avp2_s)
+{
+ swr_profile_t *prof; + swr_profile_t *prof;
+ unsigned short avp_type = 0; + unsigned short avp_type = 0;
+ int_str avp_val; + int_str avp_val;
@ -527,8 +572,7 @@ index 0000000..f3a9ab2
+ avp_val.s.s = prof->prepaid ? "1" : "0"; + avp_val.s.s = prof->prepaid ? "1" : "0";
+ avp_val.s.len = 1; + avp_val.s.len = 1;
+ +
+ if (add_avp(AVP_VAL_STR | avp_type, avp_name, avp_val) != 0) + if(add_avp(AVP_VAL_STR | avp_type, avp_name, avp_val) != 0) {
+ {
+ LM_ERR("Failed to add result avp"); + LM_ERR("Failed to add result avp");
+ goto err; + goto err;
+ } + }
@ -537,8 +581,7 @@ index 0000000..f3a9ab2
+ avp2_val.s.s = prof->prepaid_library; + avp2_val.s.s = prof->prepaid_library;
+ avp2_val.s.len = strlen(prof->prepaid_library); + avp2_val.s.len = strlen(prof->prepaid_library);
+ +
+ if (add_avp(AVP_VAL_STR | avp2_type, avp2_name, avp2_val) != 0) + if(add_avp(AVP_VAL_STR | avp2_type, avp2_name, avp2_val) != 0) {
+ {
+ LM_ERR("Failed to add result avp"); + LM_ERR("Failed to add result avp");
+ goto err; + goto err;
+ } + }
@ -553,7 +596,9 @@ index 0000000..f3a9ab2
+ return -1; + return -1;
+} +}
+ +
+static int lcr_get_profile_id_from_uuid(sip_msg_t *msg, char *uuid_s, char *avp_s) { +static int lcr_get_profile_id_from_uuid(
+ sip_msg_t *msg, char *uuid_s, char *avp_s)
+{
+ swr_profile_t prof; + swr_profile_t prof;
+ unsigned short avp_type = 0; + unsigned short avp_type = 0;
+ int_str avp_val; + int_str avp_val;
@ -566,8 +611,7 @@ index 0000000..f3a9ab2
+ +
+ avp_val.s.s = int2str(prof.profile_id, &avp_val.s.len); + avp_val.s.s = int2str(prof.profile_id, &avp_val.s.len);
+ +
+ if (add_avp(AVP_VAL_STR | avp_type, avp_name, avp_val) != 0) + if(add_avp(AVP_VAL_STR | avp_type, avp_name, avp_val) != 0) {
+ {
+ LM_ERR("Failed to add result avp"); + LM_ERR("Failed to add result avp");
+ return -1; + return -1;
+ } + }

@ -1,67 +0,0 @@
From: Sipwise Development Team <support@sipwise.com>
Date: Thu, 26 Mar 2020 10:06:46 +0100
Subject: fix_lcr_rate_wrong_id
---
src/modules/lcr_rate/lcr_rate_mod.c | 38 ++++++++++++++++++++++++++++++-------
1 file changed, 31 insertions(+), 7 deletions(-)
diff --git a/src/modules/lcr_rate/lcr_rate_mod.c b/src/modules/lcr_rate/lcr_rate_mod.c
index f3a9ab2..f35e577 100644
--- a/src/modules/lcr_rate/lcr_rate_mod.c
+++ b/src/modules/lcr_rate/lcr_rate_mod.c
@@ -153,7 +153,7 @@ static struct peer *load_peers(int *num, char *src_user, char *src_domain, char
struct usr_avp *avp;
int_str val;
struct peer *ret, *j;
- int len, i;
+ int len, i, k;
char *c;
str s;
swr_rate_t rate;
@@ -198,15 +198,39 @@ static struct peer *load_peers(int *num, char *src_user, char *src_domain, char
return NULL;
}
memcpy(j->s.s, val.s.s, val.s.len);
- c = memrchr(j->s.s, '|', val.s.len);
- if (!c) {
- LM_ERR("separator not found in string <%.*s>\n", val.s.len, j->s.s);
- goto next;
+
+ /* lcr gw fields:
+ * 0: gw index
+ * 1: scheme
+ * 2: strip
+ * 3: prefix
+ * 4: tag
+ * 5: ip adr
+ * 6: hostname
+ * 7: port
+ * 8: params
+ * 9: transport
+ * 10: flags
+ * 11: rule id
+ */
+ c = j->s.s;
+ for (k = 0; k < 10; k++) {
+ c = memchr(c, '|', val.s.len - (c - j->s.s));
+ if (!c) {
+ LM_ERR("separator not found in string <%.*s> (field #%i)\n",
+ val.s.len, j->s.s, k);
+ goto next;
+ }
+ c++;
}
- c++;
s.s = c;
- s.len = val.s.len - (c - j->s.s);
+
+ /* find terminator */
+ c = memchr(c, '|', val.s.len - (c - j->s.s));
+ if (!c)
+ c = j->s.s + val.s.len;
+ s.len = c - s.s;
if (str2int(&s, &j->id)) {
LM_ERR("could not convert string <%.*s> to int\n", s.len, s.s);
goto next;
Loading…
Cancel
Save