TT#81803 pv_headers rework

* remove pvh_remove_xavi()
* rework pvh_set_header():
  use core pv_get_spec_*
  use PV_IDX_NONE to detect no index case
  remove values instead of adding NULL if PV_IDX_ALL
* changes needed from upstream:
  https://github.com/kamailio/kamailio/pull/2341
  Introducing PV_IDX_NONE so we can know when idx == 0
  if $x_hdr(HEADER) or $x_hdr(HEADER[0])
  So we can append or set the value

Change-Id: I496d65cc7e0e92167967edfb592fff6a6b0d6e3b
changes/36/40336/16
Victor Seva 6 years ago
parent 68064ab3c4
commit 873255c538

@ -65,22 +65,23 @@ upstream/cfgt-fix-implicit-declaration-of-strcasestr.patch
upstream/core-str-helper-macro-to-set-ending-zero-with-backup.patch
upstream/core-str-fixed-wrong-undo-ed-version-of-STR_ZTOV-mac.patch
upstream/jansson-use-the-core-macros-for-ending-string-value-.patch
upstream/ndb_redis-fix-return-redis_cmd-function.patch
upstream/core-add-case-functions-for-str_hash-get-and-set.patch
upstream/core-xavi-api-like-xavp-but-with-insensitive-case-na.patch
upstream/pv-define-xavi-types.patch
upstream/core-receive-reset-xavi-list-after-message-processin.patch
upstream/tm-process-xavi-list-in-transaction-contexts.patch
upstream/pv-xavi-.-config-variables-implementation.patch
upstream/core-PV_IDX_NONE-to-point-that-pv-had-no-index.patch
upstream/pv-fix-for-new-PV_IDX_NONE-value.patch
## backport from kamailio trunk (5.3)
#
### relevant for upstream
## https://github.com/kamailio/kamailio/pull/2332
sipwise/core-add-case-functions-for-str_hash-get-and-set.patch
#
### active development
sipwise/pua_dialoginfo-refresh_pubruri_avps_flag.patch
sipwise/pua_dialoginfo-local_identity_dlg_var.patch
### active development
#
sipwise/ndb_redis-fix-return-redis_cmd-function.patch
### Don't just put stuff in any order
### use gbp pq import/export tooling to help maintain patches
###

@ -21,9 +21,9 @@ Subject: add_pv_headers_module
src/modules/pv_headers/pvh_hdr.h | 47 +
src/modules/pv_headers/pvh_str.c | 146 +++
src/modules/pv_headers/pvh_str.h | 40 +
src/modules/pv_headers/pvh_xavp.c | 1173 +++++++++++++++++++++++
src/modules/pv_headers/pvh_xavp.h | 63 ++
20 files changed, 3773 insertions(+), 1 deletion(-)
src/modules/pv_headers/pvh_xavp.c | 1155 +++++++++++++++++++++++
src/modules/pv_headers/pvh_xavp.h | 62 ++
20 files changed, 3754 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/doc/Makefile
@ -1545,7 +1545,7 @@ index 0000000..5ee4efc
+#endif /* PV_HEADERS_H */
diff --git a/src/modules/pv_headers/pvh_func.c b/src/modules/pv_headers/pvh_func.c
new file mode 100644
index 0000000..1e1a9cc
index 0000000..749275e
--- /dev/null
+++ b/src/modules/pv_headers/pvh_func.c
@@ -0,0 +1,360 @@
@ -1856,10 +1856,10 @@ index 0000000..1e1a9cc
+
+ pvh_get_branch_xname(msg, &xavi_name, &br_xname);
+ LM_DBG("clean xavi:%.*s\n", br_xname.len, br_xname.s);
+ pvh_free_xavi(&br_xname);
+ xavi_rm_by_name(&br_xname, 1, NULL);
+ pvh_get_branch_xname(msg, &xavi_parsed_xname, &br_xname);
+ LM_DBG("clean xavi:%.*s\n", br_xname.len, br_xname.s);
+ pvh_free_xavi(&br_xname);
+ xavi_rm_by_name(&br_xname, 1, NULL);
+
+ pvh_hdrs_reset_flags(msg);
+
@ -2701,10 +2701,10 @@ index 0000000..10aa216
\ No newline at end of file
diff --git a/src/modules/pv_headers/pvh_xavp.c b/src/modules/pv_headers/pvh_xavp.c
new file mode 100644
index 0000000..3c0950a
index 0000000..03bcaf1
--- /dev/null
+++ b/src/modules/pv_headers/pvh_xavp.c
@@ -0,0 +1,1173 @@
@@ -0,0 +1,1155 @@
+/*
+ * pv_headers
+ *
@ -2912,18 +2912,6 @@ index 0000000..3c0950a
+/**
+ *
+ */
+int pvh_free_xavi(str *xname)
+{
+ sr_xavp_t *xavi = NULL;
+ xavi_rm_by_name(xname, 1, NULL);
+ if((xavi = xavi_get(xname, NULL)) != NULL)
+ xavi_rm(xavi, NULL);
+ return 1;
+}
+
+/**
+ *
+ */
+static void pvh_free_to_params(struct to_param *param, sr_xavp_sfree_f sfree)
+{
+ struct to_param *n = NULL;
@ -2960,13 +2948,12 @@ index 0000000..3c0950a
+ return -1;
+ }
+ if(pv_parse_spec(hname, psp) == NULL) {
+ LM_ERR("invalid avp name [%.*s]\n", hname->len, hname->s);
+ LM_ERR("invalid name [%.*s]\n", hname->len, hname->s);
+ pv_spec_free(psp);
+ return -1;
+ }
+ sp->pvp.pvn.type = PV_NAME_PVAR;
+ sp->pvp.pvn.u.dname = (void *)psp;
+ sp->pvp.pvn.u.isname.name.s = *hname;
+ return 0;
+ }
+
@ -3091,8 +3078,8 @@ index 0000000..3c0950a
+ }
+
+ pvh_get_branch_xname(msg, xname, &br_xname);
+ LM_DBG("br_xname: %.*s name: %.*s\n", br_xname.len, br_xname.s, name->len,
+ name->s);
+ LM_DBG("br_xname: %.*s name: %.*s append:%d\n",
+ br_xname.len, br_xname.s, name->len, name->s, append);
+ memset(&xval, 0, sizeof(sr_xval_t));
+ if(data == NULL || SR_XTYPE_NULL) {
+ xval.type = SR_XTYPE_NULL;
@ -3303,53 +3290,52 @@ index 0000000..3c0950a
+int pvh_set_header(
+ struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val)
+{
+ sr_xavp_t *xavi = NULL;
+ sr_xavp_t *xavi = NULL, *avi = NULL;
+ pv_elem_p pv_format = NULL;
+ pv_value_t tv;
+ str hname = STR_NULL;
+ str orig_hname = STR_NULL;
+ str fval;
+ int idx = 0;
+ int cnt = 0;
+ int itype;
+
+ idx = param->pvi.u.ival;
+ itype = param->pvi.type;
+ str *hname = NULL;
+ str fval = STR_NULL;
+ int idxf, idx, hname_cnt, cnt;
+
+ if(param->pvn.type == PV_NAME_PVAR) {
+ if(pv_get_spec_value(msg, (pv_spec_p)(param->pvn.u.dname), &tv) != 0) {
+ LM_ERR("cannot get avp value\n");
+ return -1;
+ }
+ if(!(tv.flags & PV_VAL_STR)) {
+ LM_ERR("invalid avp value, must be a string\n");
+ return -1;
+ }
+ hname = tv.rs;
+ orig_hname = param->pvn.u.isname.name.s;
+ } else if(param->pvn.u.isname.type == AVP_NAME_STR) {
+ hname = param->pvn.u.isname.name.s;
+ orig_hname = hname;
+ } else {
+ if(pv_get_spec_name(msg, param, &tv) != 0 || (!(tv.flags & PV_VAL_STR))) {
+ LM_ERR("invalid header name, must be a string\n");
+ return -1;
+ }
+ hname = &tv.rs;
+
+ /* get the index */
+ if(pv_get_spec_index(msg, param, &idx, &idxf)!=0)
+ {
+ LM_ERR("invalid index\n");
+ return -1;
+ }
+
+ if((xavi = pvh_xavi_get_child(msg, &xavi_name, &hname)) == NULL)
+ xavi = pvh_get_xavi(msg, &xavi_name);
+ avi = xavi->val.v.xavp;
+ hname_cnt = xavi_count(hname, &avi);
+ if(hname_cnt == 0) {
+ idx = 0;
+ else if(idx < 0)
+ idx = idx + xavi_count(&hname, &xavi);
+ } else if(idx < 0) {
+ idx = idx + hname_cnt;
+ }
+ if(idx < 0) {
+ LM_ERR("invalid index\n");
+ return -1;
+ }
+ LM_DBG("xavi:%.*s hname:%.*s hname_cnt:%d idx:%d idxf:%d\n",
+ xavi->name.len, xavi->name.s, hname->len, hname->s,
+ hname_cnt, idx, idxf);
+
+ if(val == NULL || (val->flags & PV_VAL_NULL)) {
+ if(itype == PV_IDX_ALL) {
+ for(idx = xavi_count(&hname, &xavi) - 1; idx >= 0; idx--) {
+ if(pvh_set_xavi(
+ msg, &xavi_name, &hname, NULL, SR_XTYPE_STR, idx, 0)
+ < 0)
+ goto err;
+ }
+ if(idxf == PV_IDX_ALL) {
+ cnt = xavi_rm_by_name(hname, 1, &xavi);
+ LM_DBG("removed %d values of %.*s=>%.*s, set $null\n",
+ cnt, xavi->name.len, xavi->name.s, hname->len, hname->s);
+ if(pvh_set_xavi(msg, &xavi_name, hname, NULL, SR_XTYPE_NULL, 0, 0)
+ < 0)
+ goto err;
+ } else {
+ if(pvh_set_xavi(msg, &xavi_name, &hname, NULL, SR_XTYPE_STR, idx, 0)
+ if(pvh_set_xavi(msg, &xavi_name, hname, NULL, SR_XTYPE_NULL, idx, 0)
+ < 0)
+ goto err;
+ }
@ -3367,27 +3353,23 @@ index 0000000..3c0950a
+ LM_ERR("cannot parse format: %.*s\n", val->rs.len, val->rs.s);
+ goto err;
+ }
+ if(strlen(orig_hname.s) > 1
+ && strcmp(orig_hname.s + strlen(orig_hname.s) - 2, "])") != 0) {
+ if(pvh_set_xavi(msg, &xavi_name, &hname, &fval, SR_XTYPE_STR, 0, 1)
+ if( idx == 0 && idxf == PV_IDX_NONE) {
+ if(pvh_set_xavi(msg, &xavi_name, hname, &fval, SR_XTYPE_STR, 0, 1)
+ < 0)
+ goto err;
+ } else if(itype == PV_IDX_ALL) {
+ idx = 0;
+ cnt = xavi_count(&hname, &xavi);
+ while(idx < cnt) {
+ if(pvh_set_xavi(msg, &xavi_name, &hname, NULL, SR_XTYPE_STR,
+ idx++, 0)
+ < 1)
+ goto err;
+ } else if(idxf == PV_IDX_ALL) {
+ if(hname_cnt > 1) {
+ cnt = xavi_rm_by_name(hname, 1, &xavi);
+ LM_DBG("removed %d values of %.*s=>%.*s\n",
+ cnt, xavi->name.len, xavi->name.s, hname->len, hname->s);
+ }
+ if(pvh_set_xavi(msg, &xavi_name, &hname, &fval, SR_XTYPE_STR, 0,
+ cnt ? 0 : 1)
+ if(pvh_set_xavi(msg, &xavi_name, hname, &fval, SR_XTYPE_STR, 0,
+ hname_cnt ? 0 : 1)
+ < 0)
+ goto err;
+ } else {
+ if(pvh_set_xavi(
+ msg, &xavi_name, &hname, &fval, SR_XTYPE_STR, idx, 0)
+ msg, &xavi_name, hname, &fval, SR_XTYPE_STR, idx, 0)
+ < 0)
+ goto err;
+ }
@ -3395,7 +3377,7 @@ index 0000000..3c0950a
+ pv_elem_free_all(pv_format);
+ } else {
+ LM_ERR("x_hdr %.*s value can be either string, integer or null\n",
+ hname.len, hname.s);
+ hname->len, hname->s);
+ goto err;
+ }
+ return 1;
@ -3880,10 +3862,10 @@ index 0000000..3c0950a
+}
diff --git a/src/modules/pv_headers/pvh_xavp.h b/src/modules/pv_headers/pvh_xavp.h
new file mode 100644
index 0000000..c3bc978
index 0000000..646ebd7
--- /dev/null
+++ b/src/modules/pv_headers/pvh_xavp.h
@@ -0,0 +1,63 @@
@@ -0,0 +1,62 @@
+/*
+ * pv_headers
+ *
@ -3921,7 +3903,6 @@ index 0000000..c3bc978
+
+int pvh_set_xavi(struct sip_msg *msg, str *xname, str *name, void *data,
+ sr_xtype_t type, int idx, int append);
+int pvh_free_xavi(str *xname);
+int pvh_xavi_keys_count(sr_xavp_t **start);
+sr_xavp_t *pvh_xavi_get_child(struct sip_msg *msg, str *xname, str *name);
+int pvh_avp_is_null(sr_xavp_t *avp);

@ -1,4 +1,3 @@
From 361542a953ceaab1894f790e21eecf74008b749a Mon Sep 17 00:00:00 2001
From: Victor Seva <linuxmaniac@torreviejawireless.org>
Date: Mon, 11 May 2020 15:06:26 +0200
Subject: [PATCH] cfgt: fix implicit declaration of 'strcasestr'
@ -13,7 +12,7 @@ Subject: [PATCH] cfgt: fix implicit declaration of 'strcasestr'
1 file changed, 1 insertion(+)
diff --git a/src/modules/cfgt/cfgt_int.c b/src/modules/cfgt/cfgt_int.c
index 382d696f53..c47a1cecc0 100644
index 382d696..c47a1ce 100644
--- a/src/modules/cfgt/cfgt_int.c
+++ b/src/modules/cfgt/cfgt_int.c
@@ -19,6 +19,7 @@
@ -24,6 +23,3 @@ index 382d696f53..c47a1cecc0 100644
#include <stdio.h>
#include <sys/stat.h>
#include <dirent.h>
--
2.20.1

@ -0,0 +1,53 @@
From: Victor Seva <linuxmaniac@torreviejawireless.org>
Date: Fri, 29 May 2020 15:31:28 +0200
Subject: [PATCH] core: PV_IDX_NONE to point that pv had no index
if index is 0 there were no way to know if the index was there
$x_hdr(A) = "value" needs to append a value
$(x_hdr(A)[0]) = "value" needs to set the value
pv_parse_spec(str *s, pv_spec_p p) was always setting p->pvp.pvi.type
to 0 == PV_IDX_INT
---
src/core/pvapi.c | 7 +++++++
src/core/pvar.h | 1 +
2 files changed, 8 insertions(+)
diff --git a/src/core/pvapi.c b/src/core/pvapi.c
index 0148578..30b2a7c 100644
--- a/src/core/pvapi.c
+++ b/src/core/pvapi.c
@@ -857,6 +857,7 @@ char* pv_parse_spec2(str *in, pv_spec_p e, int silent)
tr = 0;
pvstate = 0;
memset(e, 0, sizeof(pv_spec_t));
+ e->pvp.pvi.type = PV_IDX_NONE;
p = in->s;
p++;
if(*p==PV_LNBRACKET)
@@ -1369,6 +1370,12 @@ int pv_get_spec_index(struct sip_msg* msg, pv_param_p ip, int *idx, int *flags)
*idx = ip->pvi.u.ival;
return 0;
}
+ if(ip->pvi.type == PV_IDX_NONE)
+ {
+ *flags = PV_IDX_NONE;
+ *idx = ip->pvi.u.ival;
+ return 0;
+ }
/* pvar */
if(pv_get_spec_value(msg, (pv_spec_p)ip->pvi.u.dval, &tv)!=0)
diff --git a/src/core/pvar.h b/src/core/pvar.h
index c1dd9f3..ff18e45 100644
--- a/src/core/pvar.h
+++ b/src/core/pvar.h
@@ -61,6 +61,7 @@
#define PV_IDX_PVAR 1
#define PV_IDX_ALL 2
#define PV_IDX_ITR 3
+#define PV_IDX_NONE 4
/*! if PV name is dynamic, integer, or str */
#define pv_has_dname(pv) ((pv)->pvp.pvn.type==PV_NAME_PVAR)

@ -0,0 +1,30 @@
From: Victor Seva <linuxmaniac@torreviejawireless.org>
Date: Mon, 1 Jun 2020 12:08:38 +0200
Subject: [PATCH] pv: fix for new PV_IDX_NONE value
---
src/modules/pv/pv_core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/modules/pv/pv_core.c b/src/modules/pv/pv_core.c
index 9087fe0..1e2eb91 100644
--- a/src/modules/pv/pv_core.c
+++ b/src/modules/pv/pv_core.c
@@ -1791,7 +1791,7 @@ int pv_get_avp(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
if ((avp=search_first_avp(name_type, avp_name, &avp_value, &state))==0)
return pv_get_null(msg, param, res);
res->flags = PV_VAL_STR;
- if(idxf==0 && idx==0)
+ if(idx==0 && (idxf==PV_IDX_INT || idxf==PV_IDX_NONE))
{
if(avp->flags & AVP_VAL_STR)
{
@@ -1949,7 +1949,7 @@ int pv_get_hdr(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
/* get the value */
res->flags = PV_VAL_STR;
- if(idxf==0 && idx==0)
+ if(idx==0 && (idxf==PV_IDX_INT || idxf==PV_IDX_NONE))
{
res->rs = hf->body;
return 0;
Loading…
Cancel
Save