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
mr13.0
Victor Seva 9 months ago
parent 7508181031
commit 8be5217b1f

@ -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