MT#57542 pua_dialoginfo: dlg_var fixes

Change-Id: I915459f2a6d0cb26e4da8415ef7a0181de723f7f
mr11.4
Victor Seva 2 years ago
parent e31257606c
commit 96ac3dcd01

@ -50,6 +50,7 @@ sipwise/dialog-support-profile_get_size-for-all-profiles.patch
### active development
sipwise/pv_headers-rework-pvh_remove_header_param-take-two.patch
sipwise/cfgt-route-log.patch
sipwise/pua_dialoginfo-fix-dlg_var-store-and-retrieval.patch
#
### Don't just put stuff in any order
### use gbp pq import/export tooling to help maintain patches

@ -0,0 +1,279 @@
From: Victor Seva <vseva@sipwise.com>
Date: Fri, 9 Jun 2023 13:56:33 +0200
Subject: pua_dialoginfo: fix dlg_var store and retrieval
* dlg_var can have more than one value
* store values as comma separate strings
* alloc string values always for str_list
---
src/modules/pua_dialoginfo/pua_dialoginfo.c | 183 +++++++++++++++++++---------
1 file changed, 123 insertions(+), 60 deletions(-)
diff --git a/src/modules/pua_dialoginfo/pua_dialoginfo.c b/src/modules/pua_dialoginfo/pua_dialoginfo.c
index 4fe5212..dab4755 100644
--- a/src/modules/pua_dialoginfo/pua_dialoginfo.c
+++ b/src/modules/pua_dialoginfo/pua_dialoginfo.c
@@ -83,6 +83,7 @@ unsigned short pubruri_callee_avp_type;
int_str pubruri_callee_avp_name;
sruid_t _puadi_sruid;
+static char *DLG_VAR_SEP = ",";
static str caller_dlg_var = {0, 0}; /* pubruri_caller */
static str callee_dlg_var = {0, 0}; /* pubruri_callee */
static str caller_entity_when_publish_disabled = {0, 0}; /* pubruri_caller */
@@ -533,7 +534,6 @@ __dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_para
struct str_list* get_str_list(unsigned short avp_flags, int_str avp_name) {
int_str avp_value;
- unsigned int len;
struct str_list* list_first = 0;
struct str_list* list_current = 0 ;
struct search_state st;
@@ -543,42 +543,121 @@ struct str_list* get_str_list(unsigned short avp_flags, int_str avp_name) {
}
do {
-
LM_DBG("AVP found '%.*s'\n", avp_value.s.len, avp_value.s.s);
-
- len = sizeof(struct str_list) + avp_value.s.len;
-
if(list_current) {
- list_current->next = (struct str_list*) shm_malloc( len);
+ list_current->next = (struct str_list*) shm_malloc(sizeof(struct str_list));
list_current=list_current->next;
} else {
- list_current=list_first= (struct str_list*) shm_malloc( len);
+ list_current=list_first= (struct str_list*) shm_malloc(sizeof(struct str_list));
}
-
- if (list_current==0) {
+ if (!list_current) {
SHM_MEM_ERROR;
- return 0;
+ free_str_list_all(list_first);
+ return NULL;
+ }
+ memset( list_current, 0, sizeof(struct str_list));
+ list_current->s.s = shm_str2char_dup(&avp_value.s);
+ if(!list_current->s.s) {
+ free_str_list_all(list_first);
+ return NULL;
}
+ list_current->s.len = avp_value.s.len;
+ } while(search_next_avp(&st, &avp_value));
- memset( list_current, 0, len);
+ return list_first;
+}
- list_current->s.s = (char*)list_current + sizeof(struct str_list);
- list_current->s.len = avp_value.s.len;
- memcpy(list_current->s.s,avp_value.s.s,avp_value.s.len);
+/**
+ * @brief set dlg_var value from str_list as comma separated values
+ *
+ * @param dlg dialog
+ * @param key dlg_var keyname
+ * @param lst list of str values
+ * @return int
+ */
+static int set_dlg_var(struct dlg_cell *dlg, str *key, struct str_list *lst)
+{
+ str buf = STR_NULL;
+ struct str_list *it = lst;
+ int num = -1;
+ int res;
+ if(!lst) return -1;
+ while(it) {
+ buf.len += it->s.len + ++num;
+ it = it->next;
+ }
+ buf.s = (char*) pkg_malloc( sizeof(char) * buf.len);
+
+ it = lst;
+ num = 0;
+ while(it) {
+ memcpy(buf.s + num, it->s.s, it->s.len);
+ if(it->next) {
+ num += it->s.len;
+ buf.s[num++] = *DLG_VAR_SEP;
+ }
+ it = it->next;
+ }
+ res = dlg_api.set_dlg_var(dlg, key, &buf);
+ pkg_free(buf.s);
- } while(search_next_avp(&st, &avp_value));
+ return res;
+}
- return list_first;
+static int get_dlg_var(struct dlg_cell *dlg, str *key, struct str_list **lst)
+{
+ str dval = STR_NULL;
+ str val = STR_NULL;
+ struct str_list *it, *prev;
+ char *sep, *ini, *end;
+ if (dlg_api.get_dlg_varval(dlg, &caller_dlg_var, &dval)!=0 || dval.s == NULL)
+ return 0;
+
+ if(*lst) {
+ free_str_list_all(*lst);
+ }
+ *lst = prev = NULL;
+ ini = dval.s;
+ end = dval.s + dval.len - 1;
+ sep = stre_search_strz(ini, end, DLG_VAR_SEP);
+ if(!sep) sep = end;
+ do {
+ val.s = ini;
+ val.len = sep - ini + 1;
+ ini = sep + 1;
+ it = (struct str_list*)shm_malloc(sizeof(struct str_list));
+ if (!it) {
+ SHM_MEM_ERROR;
+ return -1;
+ }
+ memset(it, 0, sizeof(struct str_list));
+ it->s.s = shm_str2char_dup(&val);
+ if(!it->s.s) {
+ free_str_list_all(*lst);
+ return -1;
+ }
+ it->s.len = val.len;
+ LM_DBG("Found uri '%.*s' in dlg_var:'%.*s'\n",
+ val.len, val.s, key->len, key->s);
+ if(!*lst) {
+ *lst = prev = it;
+ } else {
+ prev->next = it;
+ }
+ if(ini < end) sep = stre_search_strz(ini, end, DLG_VAR_SEP);
+ else sep = NULL;
+ } while(sep);
+
+ return 0;
}
struct dlginfo_cell* get_dialog_data(struct dlg_cell *dlg, int type, int disable_caller_publish, int disable_callee_publish)
{
struct dlginfo_cell *dlginfo;
int len;
- str dval = {0};
// generate new random uuid
if(sruid_next_safe(&_puadi_sruid) < 0) {
@@ -644,53 +723,31 @@ struct dlginfo_cell* get_dialog_data(struct dlg_cell *dlg, int type, int disable
dlginfo->pubruris_callee = get_str_list(pubruri_callee_avp_type,
pubruri_callee_avp_name);
- if(dlginfo->pubruris_callee!=NULL && callee_dlg_var.len>0)
- dlg_api.set_dlg_var(dlg, &callee_dlg_var,
- &dlginfo->pubruris_callee->s);
-
- if(dlginfo->pubruris_caller!=NULL && caller_dlg_var.len>0)
- dlg_api.set_dlg_var(dlg, &caller_dlg_var,
- &dlginfo->pubruris_caller->s);
-
+ if(dlginfo->pubruris_callee!=NULL && callee_dlg_var.len>0) {
+ if(set_dlg_var(dlg, &callee_dlg_var, dlginfo->pubruris_callee) < 0) {
+ free_str_list_all(dlginfo->pubruris_callee);
+ dlginfo->pubruris_callee = NULL;
+ }
+ }
+ if(dlginfo->pubruris_caller!=NULL && caller_dlg_var.len>0) {
+ if(set_dlg_var(dlg, &caller_dlg_var, dlginfo->pubruris_caller) < 0) {
+ free_str_list_all(dlginfo->pubruris_caller);
+ dlginfo->pubruris_caller = NULL;
+ }
+ }
} else {
- if(caller_dlg_var.len>0
- && (dlg_api.get_dlg_varval(dlg, &caller_dlg_var, &dval)==0)
- && dval.s!=NULL) {
- dlginfo->pubruris_caller =
- (struct str_list*)shm_malloc(sizeof(struct str_list) + dval.len + 1);
- if (dlginfo->pubruris_caller==0) {
- SHM_MEM_ERROR;
+ if(caller_dlg_var.len>0) {
+ if(get_dlg_var(dlg, &caller_dlg_var, &dlginfo->pubruris_caller) <0) {
free_dlginfo_cell(dlginfo);
return NULL;
}
- memset(dlginfo->pubruris_caller, 0, sizeof(struct str_list));
- dlginfo->pubruris_caller->s.s = (char*)dlginfo->pubruris_caller
- + sizeof(sizeof(struct str_list));
- memcpy(dlginfo->pubruris_caller->s.s, dval.s, dval.len);
- dlginfo->pubruris_caller->s.s[dval.len] = '\0';
- dlginfo->pubruris_caller->s.len = dval.len;
- LM_DBG("Found pubruris_caller in dialog '%.*s'\n",
- dlginfo->pubruris_caller->s.len, dlginfo->pubruris_caller->s.s);
}
- if(callee_dlg_var.len>0
- && (dlg_api.get_dlg_varval(dlg, &callee_dlg_var, &dval)==0)
- && dval.s!=NULL) {
- dlginfo->pubruris_callee =
- (struct str_list*)shm_malloc(sizeof(struct str_list) + dval.len + 1);
- if (dlginfo->pubruris_callee==0) {
- SHM_MEM_ERROR;
+ if(callee_dlg_var.len>0) {
+ if(get_dlg_var(dlg, &callee_dlg_var, &dlginfo->pubruris_callee) <0) {
free_dlginfo_cell(dlginfo);
return NULL;
}
- memset(dlginfo->pubruris_callee, 0, sizeof(struct str_list));
- dlginfo->pubruris_callee->s.s = (char*)dlginfo->pubruris_callee
- + sizeof(sizeof(struct str_list));
- memcpy(dlginfo->pubruris_callee->s.s, dval.s, dval.len);
- dlginfo->pubruris_callee->s.s[dval.len] = '\0';
- dlginfo->pubruris_callee->s.len = dval.len;
- LM_DBG("Found pubruris_callee in dialog '%.*s'\n",
- dlginfo->pubruris_callee->s.len, dlginfo->pubruris_callee->s.s);
}
}
@@ -709,7 +766,12 @@ struct dlginfo_cell* get_dialog_data(struct dlg_cell *dlg, int type, int disable
return NULL;
}
memset( dlginfo->pubruris_caller, 0, sizeof(struct str_list));
- dlginfo->pubruris_caller->s=dlginfo->from_uri;
+ dlginfo->pubruris_caller->s.s = shm_str2char_dup(&dlginfo->from_uri);
+ if(!dlginfo->pubruris_caller->s.s) {
+ free_dlginfo_cell(dlginfo);
+ return NULL;
+ }
+ dlginfo->pubruris_caller->s.len = dlginfo->from_uri.len;
dlginfo->pubruris_callee =
(struct str_list*)shm_malloc( sizeof(struct str_list) );
@@ -721,9 +783,11 @@ struct dlginfo_cell* get_dialog_data(struct dlg_cell *dlg, int type, int disable
memset( dlginfo->pubruris_callee, 0, sizeof(struct str_list));
if(include_req_uri) {
- dlginfo->pubruris_callee->s = dlginfo->req_uri;
+ dlginfo->pubruris_callee->s.s = shm_str2char_dup(&dlginfo->req_uri);
+ dlginfo->pubruris_callee->s.len = dlginfo->req_uri.len;
} else {
- dlginfo->pubruris_callee->s = dlginfo->to_uri;
+ dlginfo->pubruris_callee->s.s = shm_str2char_dup(&dlginfo->to_uri);
+ dlginfo->pubruris_callee->s.len = dlginfo->to_uri.len;
}
}
@@ -1009,10 +1073,9 @@ void free_str_list_all(struct str_list * del_current) {
struct str_list* del_next;
while(del_current) {
-
del_next = del_current->next;
+ if(del_current->s.s) shm_free(del_current->s.s);
shm_free(del_current);
-
del_current=del_next;
}
Loading…
Cancel
Save