From 95e0773605d4970eb76a7a6da279ecb75f0cfeb0 Mon Sep 17 00:00:00 2001 From: Victor Seva Date: Tue, 17 Dec 2019 15:29:38 +0100 Subject: [PATCH] TT#71821 pv_headers: fix missing $x_tt on replies Change-Id: I95ac0b2be4ca377883d3de08c9fa4ad8fe3fae30 (cherry picked from commit 1ba66d5bc7f70a50a62473dce27f90564d6e92cf) --- .../sipwise/add_pv_headers_module.patch | 183 +++++++++++------- 1 file changed, 113 insertions(+), 70 deletions(-) diff --git a/debian/patches/sipwise/add_pv_headers_module.patch b/debian/patches/sipwise/add_pv_headers_module.patch index 5c1457807..32e3cad6e 100644 --- a/debian/patches/sipwise/add_pv_headers_module.patch +++ b/debian/patches/sipwise/add_pv_headers_module.patch @@ -5,9 +5,9 @@ Subject: add_pv_headers_module src/Makefile.groups | 2 +- src/modules/pv_headers/Makefile | 12 + src/modules/pv_headers/README | 488 ++++++++ - src/modules/pv_headers/pv_headers.c | 2083 +++++++++++++++++++++++++++++++++++ + src/modules/pv_headers/pv_headers.c | 2126 +++++++++++++++++++++++++++++++++++ src/modules/pv_headers/pv_headers.h | 30 + - 5 files changed, 2614 insertions(+), 1 deletion(-) + 5 files changed, 2657 insertions(+), 1 deletion(-) create mode 100644 src/modules/pv_headers/Makefile create mode 100644 src/modules/pv_headers/README create mode 100644 src/modules/pv_headers/pv_headers.c @@ -540,10 +540,10 @@ index 0000000..30bd1da + $var(test) = $x_rr; diff --git a/src/modules/pv_headers/pv_headers.c b/src/modules/pv_headers/pv_headers.c new file mode 100644 -index 0000000..f3b90e4 +index 0000000..f3c8a83 --- /dev/null +++ b/src/modules/pv_headers/pv_headers.c -@@ -0,0 +1,2083 @@ +@@ -0,0 +1,2126 @@ +/* + * pv_headers + * @@ -585,6 +585,7 @@ index 0000000..f3b90e4 +#include "../../core/parser/parse_uri.h" +#include "../../core/parser/msg_parser.h" +#include "../../core/script_cb.h" ++#include "../../core/strutils.h" +#include "../../modules/uac/api.h" +#include "../../modules/tm/tm_load.h" + @@ -666,6 +667,7 @@ index 0000000..f3b90e4 +static sr_xavp_t * pv_xavp_new_value(str *name, sr_xval_t *val); +static int pv_xavp_append_value(str *name, sr_xval_t *val, sr_xavp_t **start); +static int pv_xavp_set_value(str *name, sr_xval_t *val, int idx, sr_xavp_t **start); ++static sr_xavp_t *pv_xavp_get(struct sip_msg *msg, str *xname); +static sr_xval_t * pv_xavp_get_value(struct sip_msg *msg, str *xname, str *name, int idx); +static sr_xavp_t * pv_xavp_get_child(struct sip_msg *msg, str *xname, str *name); +static int pv_xavp_is_null(sr_xavp_t * xavp); @@ -684,6 +686,7 @@ index 0000000..f3b90e4 +static int pv_parse_header_name(pv_spec_p sp, str *hname); +static int pv_get_header(struct sip_msg *msg, pv_param_t *param, pv_value_t *res); +static int pv_set_header(struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val); ++xavp_c_data_t *pv_set_parsed(struct sip_msg *msg, str *hname, str *cur, str *new); +static int pv_get_uri(struct sip_msg *msg, pv_param_t *param, pv_value_t *res); +static int pv_set_uri(struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val); +static int pv_merge_uri(struct sip_msg *msg, enum action_type type, str *cur, str *new, xavp_c_data_t *c_data); @@ -692,7 +695,7 @@ index 0000000..f3b90e4 + +static int pv_get_branch_index(struct sip_msg *msg, int *br_idx); +static int pv_get_branch_xname(struct sip_msg *msg, str *xname, str *dst); -+static int pv_clone_branch_xavp(struct sip_msg *msg, str *xname); ++static int pv_clone_branch_xavp(struct sip_msg *msg, str *xname, str *br_xname); + +/* + * Exported functions @@ -926,7 +929,7 @@ index 0000000..f3b90e4 + 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; + + rm_hdrs.size = 0; @@ -947,17 +950,10 @@ index 0000000..f3b90e4 + + if (pv_str_new(&display, header_value_size) < 0) goto err; + if (pv_str_new(&uri, header_value_size) < 0) goto err; -+ if (pv_str_new(&br_xname, header_value_size) < 0) goto err; -+ -+ pv_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 = pv_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; + } + @@ -970,19 +966,29 @@ index 0000000..f3b90e4 + LM_ERR("memory allocation error\n"); + 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(pv_set_parsed(msg, &_hdr_to, &msg->to->body, NULL) == NULL) ++ LM_ERR("can't store To info in parsed\n"); ++ } ++ } ++ + do { + if (pv_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; + } @@ -1013,10 +1019,7 @@ index 0000000..f3b90e4 + } + + 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; + } @@ -1077,7 +1080,6 @@ index 0000000..f3b90e4 + + pv_str_free(&display); + pv_str_free(&uri); -+ pv_str_free(&br_xname); + if (rm_hdrs.size) + pv_str_hash_free(&rm_hdrs); + @@ -1086,7 +1088,6 @@ index 0000000..f3b90e4 +err: + pv_str_free(&display); + pv_str_free(&uri); -+ pv_str_free(&br_xname); + if (rm_hdrs.size) + pv_str_hash_free(&rm_hdrs); + return -1; @@ -1260,7 +1261,9 @@ index 0000000..f3b90e4 + root = xavp_get(&br_xname, NULL); + + if (root == NULL && br_idx > 0) { -+ pv_clone_branch_xavp(msg, xname); ++ LM_DBG("clone xavp:%.*s br_xname:%.*s\n", xname->len, xname->s, ++ br_xname.len, br_xname.s); ++ pv_clone_branch_xavp(msg, xname, &br_xname); + root = xavp_get(&br_xname, NULL); + } + @@ -1711,41 +1714,55 @@ index 0000000..f3b90e4 + if (idx < 0) + return -1; + } -+ LM_DBG("xavp name: %.s\n", name->len, name->s); ++ LM_DBG("xavp name: %.*s\n", name->len, name->s); + if (xavp_set_value(name, idx, val, start) == NULL) + return -1; + + return 1; +} + -+sr_xval_t * pv_xavp_get_value(struct sip_msg *msg, str *xname, str *name, int idx) ++sr_xavp_t *pv_xavp_get(struct sip_msg *msg, str *xname) +{ + sr_xavp_t *xavp = NULL; -+ sr_xavp_t *sub = NULL; + str br_xname = STR_NULL; + + if (pv_str_new(&br_xname, header_name_size) < 0) + return NULL; + + pv_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: + pv_str_free(&br_xname); -+ return sub ? &sub->val : NULL; ++ return xavp; ++} + -+err: -+ pv_str_free(&br_xname); -+ return NULL; ++sr_xval_t *pv_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 = pv_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 * pv_xavp_get_child(struct sip_msg *msg, str *xname, str *name) @@ -1758,8 +1775,16 @@ index 0000000..f3b90e4 + + pv_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); ++ } */ ++ } ++ } + + pv_str_free(&br_xname); + return xavp; @@ -2103,6 +2128,34 @@ index 0000000..f3b90e4 + return -1; +} + ++xavp_c_data_t *pv_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(pv_merge_uri(msg, SET_URI_T, cur, val, c_data) < 0) ++ goto err; ++ if(pv_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 pv_get_uri(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) +{ + sr_xval_t *xval = NULL; @@ -2123,8 +2176,11 @@ index 0000000..f3b90e4 + pv_str_copy(&hname, &_hdr_to, header_name_size); + + xval = pv_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 = pv_xavp_get_value(msg, &xavp_parsed_xname, &hname, 0); + @@ -2133,20 +2189,14 @@ index 0000000..f3b90e4 + + 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) { -+ LM_ERR("out of shared memory\n"); ++ if((c_data = pv_set_parsed(msg, &hname, &xval->v.s, NULL)) == NULL) + goto err; -+ } -+ memset(c_data, 0, sizeof(xavp_c_data_t)); -+ if (pv_merge_uri(msg, SET_URI_T, &xval->v.s, &xval->v.s, c_data) < 0) -+ goto err; -+ if (pv_set_xavp(msg, &xavp_parsed_xname, &hname, c_data, SR_XTYPE_DATA, 0, 0) < 0) -+ goto err; + } + + switch (p_no) { @@ -2174,6 +2224,7 @@ index 0000000..f3b90e4 + LM_ERR("unknown get uri op\n"); + } + ++ /* LM_DBG("p_no:%d sval:%.*s\n", p_no, sval.len, sval.s); */ + pv_str_free(&hname); + return sval.s ? is_strint ? pv_get_strintval(msg, param, res, &sval, ival) + : pv_get_strval(msg, param, res, &sval) @@ -2251,6 +2302,8 @@ index 0000000..f3b90e4 + if (pv_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 (pv_set_xavp(msg, &xavp_name, &hname, &c_data->value, SR_XTYPE_STR, 0, 0) < 0) + goto err; + @@ -2568,13 +2621,12 @@ index 0000000..f3b90e4 + return 1; +} + -+static int pv_clone_branch_xavp(struct sip_msg *msg, str *xname) ++static int pv_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); @@ -2591,21 +2643,17 @@ index 0000000..f3b90e4 + return -1; + } + -+ if (pv_str_new(&br_xname, header_name_size) < 0) -+ return -1; -+ pv_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) { -+ pv_str_free(&br_xname); ++ LM_DBG("skip clone\n"); + return 1; + } + @@ -2616,16 +2664,11 @@ index 0000000..f3b90e4 + continue; + if (pv_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); + -+ pv_str_free(&br_xname); + return 1; -+ -+err: -+ pv_str_free(&br_xname); -+ return -1; +} diff --git a/src/modules/pv_headers/pv_headers.h b/src/modules/pv_headers/pv_headers.h new file mode 100644