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
sipwise/add_pcem_module.patch
sipwise/add_lcr_rate_module.patch
sipwise/fix_lcr_rate_wrong_id.patch
sipwise/add_tcap_module.patch
sipwise/add_presence_dfks_module.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.h | 2 +
src/modules/lcr_rate/Makefile | 9 +
src/modules/lcr_rate/lcr_rate_mod.c | 473 ++++++++++++++++++++++++++++++++++++
5 files changed, 494 insertions(+), 2 deletions(-)
src/modules/lcr_rate/lcr_rate_mod.c | 517 ++++++++++++++++++++++++++++++++++++
5 files changed, 538 insertions(+), 2 deletions(-)
create mode 100644 src/modules/lcr_rate/Makefile
create mode 100644 src/modules/lcr_rate/lcr_rate_mod.c
@ -97,10 +97,10 @@ index 0000000..9a3cee1
+include ../../Makefile.modules
diff --git a/src/modules/lcr_rate/lcr_rate_mod.c b/src/modules/lcr_rate/lcr_rate_mod.c
new file mode 100644
index 0000000..f3a9ab2
index 0000000..5670871
--- /dev/null
+++ b/src/modules/lcr_rate/lcr_rate_mod.c
@@ -0,0 +1,473 @@
@@ -0,0 +1,517 @@
+/*
+ * call rating for least cost routing module
+ *
@ -138,7 +138,8 @@ index 0000000..f3a9ab2
+
+MODULE_VERSION
+
+struct peer {
+struct peer
+{
+ int valid;
+ unsigned int id;
+ double cost;
@ -151,10 +152,25 @@ index 0000000..f3a9ab2
+static int child_init(int rank);
+
+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_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[] = {
+ {"lcr_rate", lcr_rate, 2, fixup_spve_spve, 0,
+ REQUEST_ROUTE | FAILURE_ROUTE},
@ -167,16 +183,6 @@ index 0000000..f3a9ab2
+ {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[] = {
+ {"gw_uri_avp", STR_PARAM, &gw_uri_avp_param},
+ {"db_host", STR_PARAM, &db_host},
@ -187,9 +193,6 @@ index 0000000..f3a9ab2
+ {0,},
+};
+
+static int swrate_done;
+static SWRATE *swrate_ptr;
+
+struct module_exports exports = {
+ "lcr_rate", /* module name */
+ DEFAULT_DLFLAGS, /* dlopen flags */
@ -202,8 +205,10 @@ index 0000000..f3a9ab2
+ child_init, /* per-child init function */
+ mod_destroy /* module destroy function */
+};
+/* clang-format on */
+
+static int mod_init() {
+static int mod_init()
+{
+ pv_spec_t avp_spec;
+ str s;
+ unsigned short avp_flags;
@ -230,18 +235,22 @@ index 0000000..f3a9ab2
+ return 0;
+}
+
+static int child_init(int rank) {
+static int child_init(int rank)
+{
+ return 0;
+}
+
+static void mod_destroy() {
+ ;
+static void mod_destroy()
+{
+ return;
+}
+
+static int check_swrate_init() {
+static int check_swrate_init()
+{
+ if(swrate_done)
+ 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)) {
+ LM_ERR("failed to initialized libswrate\n");
+ if(swrate_ptr)
@ -252,18 +261,20 @@ index 0000000..f3a9ab2
+ 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;
+ int_str val;
+ struct peer *ret, *j;
+ int len, i;
+ int len, i, k;
+ char *c;
+ str s;
+ swr_rate_t rate;
+ time_t now;
+
+ LM_DBG("loading peers for user <%s>@<%s> -> <%s>@<%s> from avp\n",
+ src_user, src_domain, dst_user, dst_domain);
+ LM_DBG("loading peers for user <%s>@<%s> -> <%s>@<%s> from avp\n", src_user,
+ src_domain, dst_user, dst_domain);
+
+ len = 4;
+ ret = pkg_malloc(len * sizeof(*ret));
@ -301,15 +312,40 @@ index 0000000..f3a9ab2
+ return NULL;
+ }
+ 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) {
+ 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;
+ }
+
+ 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;
@ -320,7 +356,8 @@ index 0000000..f3a9ab2
+
+ if(swrate_get_peer_ab_rate(&rate, swrate_ptr, j->id, src_user,
+ 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);
+ goto next;
+ }
@ -337,7 +374,8 @@ index 0000000..f3a9ab2
+ 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;
+
+ if(a->valid && !b->valid)
@ -360,7 +398,8 @@ index 0000000..f3a9ab2
+ return 0;
+}
+
+static int save_peers(struct peer *peers, int num) {
+static int save_peers(struct peer *peers, int num)
+{
+ int i;
+ int_str val;
+
@ -376,7 +415,8 @@ index 0000000..f3a9ab2
+ 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;
+ if(!s || !s->s || !*s->s)
+ return;
@ -390,7 +430,8 @@ index 0000000..f3a9ab2
+ *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;
+ int num_peers, ret;
+ str src, dst;
@ -434,26 +475,24 @@ index 0000000..f3a9ab2
+ 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;
+ str *avp;
+
+ avp = (str *)avp_s;
+
+ if (pv_locate_name(avp) != avp->len)
+ {
+ if(pv_locate_name(avp) != avp->len) {
+ LM_ERR("invalid AVP parameter\n");
+ return -1;
+ }
+
+ if (((avp_spec = pv_cache_get(avp)) == NULL)
+ || avp_spec->type!=PVT_AVP) {
+ if(((avp_spec = pv_cache_get(avp)) == NULL) || avp_spec->type != PVT_AVP) {
+ LM_ERR("malformed or non AVP %s AVP definition\n", avp->s);
+ 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);
+ return -1;
+ }
@ -461,7 +500,9 @@ index 0000000..f3a9ab2
+ 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;
+ str uuid;
+
@ -490,7 +531,8 @@ index 0000000..f3a9ab2
+ 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");
+ return -1;
+ }
@ -498,11 +540,14 @@ index 0000000..f3a9ab2
+ 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);
+}
+
+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;
+ unsigned short avp_type = 0;
+ int_str avp_val;
@ -527,8 +572,7 @@ index 0000000..f3a9ab2
+ avp_val.s.s = prof->prepaid ? "1" : "0";
+ 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");
+ goto err;
+ }
@ -537,8 +581,7 @@ index 0000000..f3a9ab2
+ avp2_val.s.s = 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");
+ goto err;
+ }
@ -553,7 +596,9 @@ index 0000000..f3a9ab2
+ 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;
+ unsigned short avp_type = 0;
+ int_str avp_val;
@ -566,8 +611,7 @@ index 0000000..f3a9ab2
+
+ 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");
+ 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