diff --git a/debian/patches/series b/debian/patches/series index a18218071..19a7652ed 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -70,6 +70,7 @@ upstream/cfgt-use-snprintf-instead-of-sprintf.patch upstream/tm_add_proportional_load_contacts_by_q_value.patch ### relevant for upstream sipwise/fix_error_in_cfgt_module.patch +sipwise/pv_headers-store-To-info-in-xavp_parsed_name.r-on-re.patch # ### Don't just put stuff in any order ### use gbp pq import/export tooling to help maintain patches diff --git a/debian/patches/sipwise/pv_headers-store-To-info-in-xavp_parsed_name.r-on-re.patch b/debian/patches/sipwise/pv_headers-store-To-info-in-xavp_parsed_name.r-on-re.patch new file mode 100644 index 000000000..6bab3fee6 --- /dev/null +++ b/debian/patches/sipwise/pv_headers-store-To-info-in-xavp_parsed_name.r-on-re.patch @@ -0,0 +1,411 @@ +From: Victor Seva +Date: Tue, 17 Dec 2019 15:27:35 +0100 +Subject: pv_headers: store To info in xavp_parsed_name.r on replies + +pvh_get_uri was using xavp_parsed_name since xavp_parsed_name.r didn't +exist so $x_tt was not there + +* some refactoring to reduce duplication +* skip trying to get the same xavp when br_xname and xname are the same +* add more debug, some commented just in case We needed it later + +Change-Id: I961d176204ddb5d4f726061c413be765187b27ac +--- + src/modules/pv_headers/pvh_func.c | 48 +++++++------- + src/modules/pv_headers/pvh_xavp.c | 135 +++++++++++++++++++++++++------------- + src/modules/pv_headers/pvh_xavp.h | 5 +- + 3 files changed, 115 insertions(+), 73 deletions(-) + +diff --git a/src/modules/pv_headers/pvh_func.c b/src/modules/pv_headers/pvh_func.c +index 1340500..7fafa40 100644 +--- a/src/modules/pv_headers/pvh_func.c ++++ b/src/modules/pv_headers/pvh_func.c +@@ -139,7 +139,7 @@ int pvh_apply_headers(struct sip_msg *msg, int is_auto) + str uri = STR_NULL; + struct str_hash_table rm_hdrs; + int from_cnt = 0, to_cnt = 0; +- str br_xname = STR_NULL; ++ int skip_from_to = 0; + int br_idx, keys_count; + int res = -1; + +@@ -170,19 +170,10 @@ int pvh_apply_headers(struct sip_msg *msg, int is_auto) + goto err; + if(pvh_str_new(&uri, header_value_size) < 0) + goto err; +- if(pvh_str_new(&br_xname, header_value_size) < 0) +- goto err; +- +- pvh_get_branch_xname(msg, &xavp_name, &br_xname); + +- if((xavp = xavp_get(&br_xname, NULL)) == NULL +- && (xavp = xavp_get(&xavp_name, NULL)) == NULL) { +- LM_ERR("missing xavp %s, run pv_collect_headers() first\n", +- xavp_name.s); +- goto err; +- } +- if(xavp->val.type != SR_XTYPE_XAVP) { +- LM_ERR("not xavp child type %s\n", xavp_name.s); ++ if((xavp = pvh_xavp_get(msg, &xavp_name)) == NULL) { ++ LM_ERR("missing xavp %.*s, run pv_collect_headers() first\n", ++ xavp_name.len, xavp_name.s); + goto err; + } + +@@ -195,19 +186,29 @@ int pvh_apply_headers(struct sip_msg *msg, int is_auto) + PKG_MEM_ERROR; + goto err; + } +- LM_DBG("xavp->name:%.*s br_xname:%.*s keys_count: %d\n", xavp->name.len, +- xavp->name.s, br_xname.len, br_xname.s, keys_count); ++ LM_DBG("xavp->name:%.*s keys_count: %d\n", xavp->name.len, xavp->name.s, ++ keys_count); + str_hash_init(&rm_hdrs); + ++ if(msg->first_line.type == SIP_REPLY ++ || msg->first_line.u.request.method_value == METHOD_ACK ++ || msg->first_line.u.request.method_value == METHOD_PRACK ++ || msg->first_line.u.request.method_value == METHOD_BYE) { ++ skip_from_to = 1; ++ if(msg->to == NULL) { ++ LM_DBG("no To header, can't store To info in parsed\n"); ++ } else { ++ if(pvh_set_parsed(msg, &_hdr_to, &msg->to->body, NULL) == NULL) ++ LM_ERR("can't store To info in parsed\n"); ++ } ++ } ++ + do { + if(pvh_skip_header(&sub->name)) + continue; + + if(strncasecmp(sub->name.s, _hdr_from.s, sub->name.len) == 0) { +- if(msg->first_line.type == SIP_REPLY +- || msg->first_line.u.request.method_value == METHOD_ACK +- || msg->first_line.u.request.method_value == METHOD_PRACK +- || msg->first_line.u.request.method_value == METHOD_BYE) { ++ if(skip_from_to) { + LM_DBG("skip From header change in reply messages\n"); + continue; + } +@@ -240,10 +241,7 @@ int pvh_apply_headers(struct sip_msg *msg, int is_auto) + } + + if(strncasecmp(sub->name.s, _hdr_to.s, sub->name.len) == 0) { +- if(msg->first_line.type == SIP_REPLY +- || msg->first_line.u.request.method_value == METHOD_ACK +- || msg->first_line.u.request.method_value == METHOD_PRACK +- || msg->first_line.u.request.method_value == METHOD_BYE) { ++ if(skip_from_to) { + LM_DBG("skip To header change in reply messages\n"); + continue; + } +@@ -309,7 +307,6 @@ int pvh_apply_headers(struct sip_msg *msg, int is_auto) + err: + pvh_str_free(&display); + pvh_str_free(&uri); +- pvh_str_free(&br_xname); + if(rm_hdrs.size) + pvh_str_hash_free(&rm_hdrs); + return res; +@@ -325,9 +322,10 @@ int pvh_reset_headers(struct sip_msg *msg) + + pvh_get_branch_index(msg, &br_idx); + pvh_get_branch_xname(msg, &xavp_name, &br_xname); +- ++ /* LM_DBG("clean xavp:%.*s\n", br_xname.len, br_xname.s); */ + pvh_free_xavp(&br_xname); + pvh_get_branch_xname(msg, &xavp_parsed_xname, &br_xname); ++ /* LM_DBG("clean xavp:%.*s\n", br_xname.len, br_xname.s); */ + pvh_free_xavp(&br_xname); + + if(msg->first_line.type == SIP_REPLY) { +diff --git a/src/modules/pv_headers/pvh_xavp.c b/src/modules/pv_headers/pvh_xavp.c +index de296b4..db2192c 100644 +--- a/src/modules/pv_headers/pvh_xavp.c ++++ b/src/modules/pv_headers/pvh_xavp.c +@@ -26,6 +26,7 @@ + + #include "../../core/hashes.h" + #include "../../core/route_struct.h" ++#include "../../core/strutils.h" + + #include "pvh_xavp.h" + #include "pvh_str.h" +@@ -105,35 +106,48 @@ int pvh_xavp_set_value(str *name, sr_xval_t *val, int idx, sr_xavp_t **start) + return 1; + } + +-sr_xval_t *pvh_xavp_get_value( +- struct sip_msg *msg, str *xname, str *name, int idx) ++sr_xavp_t *pvh_xavp_get(struct sip_msg *msg, str *xname) + { + sr_xavp_t *xavp = NULL; +- sr_xavp_t *sub = NULL; + str br_xname = STR_NULL; + + if(pvh_str_new(&br_xname, header_name_size) < 0) + return NULL; + + pvh_get_branch_xname(msg, xname, &br_xname); +- if((xavp = xavp_get(&br_xname, NULL)) == NULL +- && (xavp = xavp_get(xname, NULL)) == NULL) { +- goto err; ++ if((xavp = xavp_get(&br_xname, NULL)) == NULL) { ++ if(cmp_str(xname, &br_xname) == 0) ++ goto end; ++ if((xavp = xavp_get(xname, NULL)) == NULL) ++ goto end; ++ /* LM_DBG("br_xname:%.*s is not there, using xname:%.*s\n", br_xname.len, ++ br_xname.s, xname->len, xname->s); */ + } + + if(xavp->val.type != SR_XTYPE_XAVP) { + LM_ERR("not xavp child type %s\n", br_xname.s); +- goto err; ++ xavp = NULL; ++ goto end; + } + +- sub = xavp_get_by_index(name, idx, &xavp->val.v.xavp); +- ++end: + pvh_str_free(&br_xname); +- return sub ? &sub->val : NULL; ++ return xavp; ++} + +-err: +- pvh_str_free(&br_xname); +- return NULL; ++sr_xval_t *pvh_xavp_get_value( ++ struct sip_msg *msg, str *xname, str *name, int idx) ++{ ++ sr_xavp_t *xavp = NULL; ++ sr_xavp_t *sub = NULL; ++ ++ if((xavp = pvh_xavp_get(msg, xname)) != NULL) { ++ /* LM_DBG("xavp:%.*s name:%.*s idx:%d\n", xavp->name.len, xavp->name.s, ++ name->len, name->s, idx); */ ++ sub = xavp_get_by_index(name, idx, &xavp->val.v.xavp); ++ } ++ ++ return sub ? &sub->val : NULL; + } + + sr_xavp_t *pvh_xavp_get_child(struct sip_msg *msg, str *xname, str *name) +@@ -146,8 +160,16 @@ sr_xavp_t *pvh_xavp_get_child(struct sip_msg *msg, str *xname, str *name) + + pvh_get_branch_xname(msg, xname, &br_xname); + xavp = xavp_get_child(&br_xname, name); +- if(xavp == NULL) +- xavp = xavp_get_child(xname, name); ++ if(xavp == NULL) { ++ if(cmp_str(xname, &br_xname) != 0) { ++ xavp = xavp_get_child(xname, name); ++ /* ++ if(xavp) { ++ LM_DBG("br_xname:%.*s is not there, using xname:%.*s\n", ++ br_xname.len, br_xname.s, xname->len, xname->s); ++ } */ ++ } ++ } + + pvh_str_free(&br_xname); + return xavp; +@@ -290,7 +312,9 @@ int pvh_set_xavp(struct sip_msg *msg, str *xname, str *name, void *data, + root = xavp_get(&br_xname, NULL); + + if(root == NULL && br_idx > 0) { +- pvh_clone_branch_xavp(msg, xname); ++ LM_DBG("clone xavp:%.*s br_xname:%.*s\n", xname->len, xname->s, ++ br_xname.len, br_xname.s); ++ pvh_clone_branch_xavp(msg, xname, &br_xname); + root = xavp_get(&br_xname, NULL); + } + +@@ -401,13 +425,12 @@ int pvh_get_branch_xname(struct sip_msg *msg, str *xname, str *dst) + return 1; + } + +-int pvh_clone_branch_xavp(struct sip_msg *msg, str *xname) ++int pvh_clone_branch_xavp(struct sip_msg *msg, str *xname, str *br_xname) + { + sr_xavp_t *xavp = NULL; + sr_xavp_t *br_xavp = NULL; + sr_xavp_t *sub = NULL; + sr_xval_t root_xval; +- str br_xname = STR_NULL; + + if((xavp = xavp_get(xname, NULL)) == NULL) { + LM_ERR("cannot clone xavp from non existing %s\n", xname->s); +@@ -424,21 +447,17 @@ int pvh_clone_branch_xavp(struct sip_msg *msg, str *xname) + return -1; + } + +- if(pvh_str_new(&br_xname, header_name_size) < 0) +- return -1; +- pvh_get_branch_xname(msg, xname, &br_xname); +- + memset(&root_xval, 0, sizeof(sr_xval_t)); + root_xval.type = SR_XTYPE_XAVP; + root_xval.v.xavp = NULL; + +- if((br_xavp = xavp_add_value(&br_xname, &root_xval, NULL)) == NULL) { +- LM_ERR("error create xavp %s\n", br_xname.s); +- goto err; ++ if((br_xavp = xavp_add_value(br_xname, &root_xval, NULL)) == NULL) { ++ LM_ERR("error create xavp %s\n", br_xname->s); ++ return -1; + } + + if(strncmp(xname->s, xavp_parsed_xname.s, xname->len) == 0) { +- pvh_str_free(&br_xname); ++ LM_DBG("skip clone\n"); + return 1; + } + +@@ -450,16 +469,11 @@ int pvh_clone_branch_xavp(struct sip_msg *msg, str *xname) + if(pvh_xavp_append_value(&sub->name, &sub->val, &br_xavp->val.v.xavp) + < 0) { + LM_ERR("cannot clone xavp %s\n", sub->name.s); +- goto err; ++ return -1; + } + } while((sub = sub->next) != NULL); + +- pvh_str_free(&br_xname); + return 1; +- +-err: +- pvh_str_free(&br_xname); +- return -1; + } + + int pvh_get_header(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) +@@ -612,6 +626,34 @@ err: + return -1; + } + ++xavp_c_data_t *pvh_set_parsed( ++ struct sip_msg *msg, str *hname, str *cur, str *new) ++{ ++ xavp_c_data_t *c_data = NULL; ++ str *val = new; ++ ++ c_data = (xavp_c_data_t *)shm_malloc(sizeof(xavp_c_data_t)); ++ if(c_data == NULL) { ++ SHM_MEM_ERROR; ++ return NULL; ++ } ++ memset(c_data, 0, sizeof(xavp_c_data_t)); ++ if(val == NULL) ++ val = cur; ++ if(pvh_merge_uri(msg, SET_URI_T, cur, val, c_data) < 0) ++ goto err; ++ if(pvh_set_xavp(msg, &xavp_parsed_xname, hname, c_data, SR_XTYPE_DATA, 0, 0) ++ < 0) ++ goto err; ++ LM_DBG("c_data from pvh_merge_uri hname:%.*s\n", hname->len, hname->s); ++ ++ return c_data; ++ ++err: ++ // how can I call?? pvh_xavp_free_data(c_data, shm_free); ++ return NULL; ++} ++ + int pvh_get_uri(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) + { + sr_xval_t *xval = NULL; +@@ -633,31 +675,29 @@ int pvh_get_uri(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) + pvh_str_copy(&hname, &_hdr_to, header_name_size); + + xval = pvh_xavp_get_value(msg, &xavp_name, &hname, 0); +- if(xval == NULL || !xval->v.s.s) ++ if(xval == NULL || !xval->v.s.s) { ++ /* LM_DBG("xavp:%.*s hname:%.*s is null\n", xavp_name.len, xavp_name.s, ++ hname.len, hname.s); */ + goto err; ++ } + + xval_pd = pvh_xavp_get_value(msg, &xavp_parsed_xname, &hname, 0); + +- if(xval_pd) ++ if(xval_pd) { ++ /* LM_DBG("p_no:%d c_data from xavp_parsed_xname hname:%.*s\n", p_no, ++ hname.len, hname.s); */ + c_data = (xavp_c_data_t *)xval_pd->v.data->p; ++ } + + if(c_data != NULL + && strncmp(xval->v.s.s, c_data->value.s, c_data->value.len) != 0) { ++ /* LM_DBG("xval:%.*s != c_data->value:%.*s\n", xval->v.s.len, xval->v.s.s, ++ c_data->value.len, c_data->value.s); */ + c_data = NULL; + } + + if(c_data == NULL) { +- c_data = (xavp_c_data_t *)shm_malloc(sizeof(xavp_c_data_t)); +- if(c_data == NULL) { +- SHM_MEM_ERROR; +- goto err; +- } +- memset(c_data, 0, sizeof(xavp_c_data_t)); +- if(pvh_merge_uri(msg, SET_URI_T, &xval->v.s, &xval->v.s, c_data) < 0) +- goto err; +- if(pvh_set_xavp( +- msg, &xavp_parsed_xname, &hname, c_data, SR_XTYPE_DATA, 0, 0) +- < 0) ++ if((c_data = pvh_set_parsed(msg, &hname, &xval->v.s, NULL)) == NULL) + goto err; + } + +@@ -685,7 +725,7 @@ int pvh_get_uri(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) + default: + LM_ERR("unknown get uri op\n"); + } +- ++ /* LM_DBG("p_no:%d sval:%.*s\n", p_no, sval.len, sval.s); */ + pvh_str_free(&hname); + return sval.s ? is_strint ? pv_get_strintval(msg, param, res, &sval, ival) + : pv_get_strval(msg, param, res, &sval) +@@ -763,7 +803,8 @@ int pvh_set_uri(struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val) + memset(c_data, 0, sizeof(xavp_c_data_t)); + if(pvh_merge_uri(msg, a_type, &xval->v.s, &fval, c_data) < 0) + goto err; +- ++ /* LM_DBG("xavp:%.*s hname:%.*s value:%.*s\n", xavp_name.len, xavp_name.s, ++ hname.len, hname.s, c_data->value.len, c_data->value.s); */ + if(pvh_set_xavp(msg, &xavp_name, &hname, &c_data->value, SR_XTYPE_STR, 0, 0) + < 0) + goto err; +diff --git a/src/modules/pv_headers/pvh_xavp.h b/src/modules/pv_headers/pvh_xavp.h +index 1245a1a..d9e9299 100644 +--- a/src/modules/pv_headers/pvh_xavp.h ++++ b/src/modules/pv_headers/pvh_xavp.h +@@ -33,6 +33,7 @@ + sr_xavp_t *pvh_xavp_new_value(str *name, sr_xval_t *val); + int pvh_xavp_append_value(str *name, sr_xval_t *val, sr_xavp_t **start); + int pvh_xavp_set_value(str *name, sr_xval_t *val, int idx, sr_xavp_t **start); ++sr_xavp_t *pvh_xavp_get(struct sip_msg *msg, str *xname); + sr_xval_t *pvh_xavp_get_value( + struct sip_msg *msg, str *xname, str *name, int idx); + sr_xavp_t *pvh_xavp_get_child(struct sip_msg *msg, str *xname, str *name); +@@ -48,6 +49,8 @@ int pvh_parse_header_name(pv_spec_p sp, str *hname); + int pvh_get_header(struct sip_msg *msg, pv_param_t *param, pv_value_t *res); + int pvh_set_header( + struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val); ++xavp_c_data_t *pvh_set_parsed( ++ struct sip_msg *msg, str *hname, str *cur, str *new); + int pvh_get_uri(struct sip_msg *msg, pv_param_t *param, pv_value_t *res); + int pvh_set_uri( + struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val); +@@ -59,6 +62,6 @@ int pvh_set_reply_sr( + + int pvh_get_branch_index(struct sip_msg *msg, int *br_idx); + int pvh_get_branch_xname(struct sip_msg *msg, str *xname, str *dst); +-int pvh_clone_branch_xavp(struct sip_msg *msg, str *xname); ++int pvh_clone_branch_xavp(struct sip_msg *msg, str *xname, str *br_xname); + + #endif /* PV_XAVP_H */