|
|
|
|
@ -1,6 +1,8 @@
|
|
|
|
|
From: Sipwise Development Team <support@sipwise.com>
|
|
|
|
|
Date: Mon, 18 Nov 2019 10:36:39 +0100
|
|
|
|
|
Subject: add_pv_headers_module
|
|
|
|
|
|
|
|
|
|
Change-Id: I2e0dd0bd8ff2eaafeaf2114886f1b7ea0cf08470
|
|
|
|
|
---
|
|
|
|
|
src/Makefile.groups | 2 +-
|
|
|
|
|
src/modules/pv_headers/Makefile | 12 +
|
|
|
|
|
@ -10,8 +12,10 @@ Subject: add_pv_headers_module
|
|
|
|
|
src/modules/pv_headers/doc/params.xml | 186 ++++
|
|
|
|
|
src/modules/pv_headers/doc/pv_headers.xml | 39 +
|
|
|
|
|
src/modules/pv_headers/doc/pv_headers_admin.xml | 116 +++
|
|
|
|
|
src/modules/pv_headers/pv_headers.c | 668 ++++++++++++++
|
|
|
|
|
src/modules/pv_headers/pv_headers.h | 45 +
|
|
|
|
|
src/modules/pv_headers/pv_headers.c | 351 ++++++++
|
|
|
|
|
src/modules/pv_headers/pv_headers.h | 51 ++
|
|
|
|
|
src/modules/pv_headers/pvh_func.c | 388 +++++++++
|
|
|
|
|
src/modules/pv_headers/pvh_func.h | 38 +
|
|
|
|
|
src/modules/pv_headers/pvh_hash.c | 132 +++
|
|
|
|
|
src/modules/pv_headers/pvh_hash.h | 39 +
|
|
|
|
|
src/modules/pv_headers/pvh_hdr.c | 235 +++++
|
|
|
|
|
@ -20,7 +24,7 @@ Subject: add_pv_headers_module
|
|
|
|
|
src/modules/pv_headers/pvh_str.h | 38 +
|
|
|
|
|
src/modules/pv_headers/pvh_xavp.c | 1050 +++++++++++++++++++++++
|
|
|
|
|
src/modules/pv_headers/pvh_xavp.h | 64 ++
|
|
|
|
|
18 files changed, 3275 insertions(+), 1 deletion(-)
|
|
|
|
|
20 files changed, 3390 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
|
|
|
|
|
@ -30,6 +34,8 @@ Subject: add_pv_headers_module
|
|
|
|
|
create mode 100644 src/modules/pv_headers/doc/pv_headers_admin.xml
|
|
|
|
|
create mode 100644 src/modules/pv_headers/pv_headers.c
|
|
|
|
|
create mode 100644 src/modules/pv_headers/pv_headers.h
|
|
|
|
|
create mode 100644 src/modules/pv_headers/pvh_func.c
|
|
|
|
|
create mode 100644 src/modules/pv_headers/pvh_func.h
|
|
|
|
|
create mode 100644 src/modules/pv_headers/pvh_hash.c
|
|
|
|
|
create mode 100644 src/modules/pv_headers/pvh_hash.h
|
|
|
|
|
create mode 100644 src/modules/pv_headers/pvh_hdr.c
|
|
|
|
|
@ -420,7 +426,7 @@ index 0000000..b143109
|
|
|
|
|
+include $(docbook_dir)/Makefile.module
|
|
|
|
|
diff --git a/src/modules/pv_headers/doc/functions.xml b/src/modules/pv_headers/doc/functions.xml
|
|
|
|
|
new file mode 100644
|
|
|
|
|
index 0000000..d390061
|
|
|
|
|
index 0000000..ef7f133
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/src/modules/pv_headers/doc/functions.xml
|
|
|
|
|
@@ -0,0 +1,131 @@
|
|
|
|
|
@ -521,7 +527,7 @@ index 0000000..d390061
|
|
|
|
|
+ </section>
|
|
|
|
|
+ <section id="pv_headers.f.pvh_modify_header">
|
|
|
|
|
+ <title>
|
|
|
|
|
+ <function moreinfo="none">pvh_modify_header(hname, [idx], hvalue)</function>
|
|
|
|
|
+ <function moreinfo="none">pvh_modify_header(hname, hvalue, [idx])</function>
|
|
|
|
|
+ </title>
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Modifies an existing header in the XAVP <quote>hname</quote> with the value <quote>hvalue</quote> into the XAVP.
|
|
|
|
|
@ -917,10 +923,10 @@ index 0000000..9c5c009
|
|
|
|
|
+</chapter>
|
|
|
|
|
diff --git a/src/modules/pv_headers/pv_headers.c b/src/modules/pv_headers/pv_headers.c
|
|
|
|
|
new file mode 100644
|
|
|
|
|
index 0000000..3390e06
|
|
|
|
|
index 0000000..9730847
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/src/modules/pv_headers/pv_headers.c
|
|
|
|
|
@@ -0,0 +1,668 @@
|
|
|
|
|
@@ -0,0 +1,351 @@
|
|
|
|
|
+/*
|
|
|
|
|
+ * pv_headers
|
|
|
|
|
+ *
|
|
|
|
|
@ -946,16 +952,14 @@ index 0000000..3390e06
|
|
|
|
|
+
|
|
|
|
|
+#include "../../core/sr_module.h"
|
|
|
|
|
+#include "../../core/mod_fix.h"
|
|
|
|
|
+#include "../../core/dset.h"
|
|
|
|
|
+#include "../../core/script_cb.h"
|
|
|
|
|
+#include "../../modules/uac/api.h"
|
|
|
|
|
+#include "../../modules/tm/tm_load.h"
|
|
|
|
|
+#include "../../core/kemi.h"
|
|
|
|
|
+
|
|
|
|
|
+#include "pv_headers.h"
|
|
|
|
|
+#include "pvh_hash.h"
|
|
|
|
|
+#include "pvh_str.h"
|
|
|
|
|
+#include "pvh_func.h"
|
|
|
|
|
+#include "pvh_xavp.h"
|
|
|
|
|
+#include "pvh_hdr.h"
|
|
|
|
|
+#include "pvh_hash.h"
|
|
|
|
|
+
|
|
|
|
|
+MODULE_VERSION
|
|
|
|
|
+
|
|
|
|
|
@ -966,17 +970,15 @@ index 0000000..3390e06
|
|
|
|
|
+#define FL_NAME_PV_HDRS_COLLECTED "pv_headers_collected"
|
|
|
|
|
+#define FL_NAME_PV_HDRS_APPLIED "pv_headers_applied"
|
|
|
|
|
+
|
|
|
|
|
+static int FL_PV_HDRS_COLLECTED = 27;
|
|
|
|
|
+static int FL_PV_HDRS_APPLIED = 28;
|
|
|
|
|
+int FL_PV_HDRS_COLLECTED = 27;
|
|
|
|
|
+int FL_PV_HDRS_APPLIED = 28;
|
|
|
|
|
+
|
|
|
|
|
+static uac_api_t uac;
|
|
|
|
|
+uac_api_t uac;
|
|
|
|
|
+static tm_api_t tmb;
|
|
|
|
|
+
|
|
|
|
|
+str xavp_name = str_init(XAVP_NAME);
|
|
|
|
|
+
|
|
|
|
|
+static str xavp_helper_xname = str_init("modparam_pv_headers");
|
|
|
|
|
+str xavp_parsed_xname = str_init("parsed_pv_headers");
|
|
|
|
|
+static str xavp_helper_name = str_init("xavp_name");
|
|
|
|
|
+static str skip_headers_param =
|
|
|
|
|
+ str_init("Record-Route,Via,Route,Content-Length,Max-Forwards,CSeq");
|
|
|
|
|
+static str split_headers_param = STR_NULL;
|
|
|
|
|
@ -994,44 +996,111 @@ index 0000000..3390e06
|
|
|
|
|
+static void mod_destroy(void);
|
|
|
|
|
+static int mod_init(void);
|
|
|
|
|
+
|
|
|
|
|
+static int pvh_fixup_svalue(struct sip_msg *msg, char *src, str *dst);
|
|
|
|
|
+
|
|
|
|
|
+static void handle_tm_t(tm_cell_t *t, int type, struct tmcb_params *params);
|
|
|
|
|
+static int handle_msg_cb(struct sip_msg *msg, unsigned int flags, void *cb);
|
|
|
|
|
+
|
|
|
|
|
+static int pvh_collect_headers(struct sip_msg *msg, char *is_auto, char *_s2);
|
|
|
|
|
+static int pvh_apply_headers(struct sip_msg *msg, char *is_auto, char *_s2);
|
|
|
|
|
+static int pvh_reset_headers(struct sip_msg *_m, char *_s1, char *_s2);
|
|
|
|
|
+static int w_pvh_collect_headers(struct sip_msg *msg, char *p1, char *p2)
|
|
|
|
|
+{
|
|
|
|
|
+ return pvh_collect_headers(msg, 0);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static int ki_pvh_collect_headers(struct sip_msg *msg)
|
|
|
|
|
+{
|
|
|
|
|
+ return pvh_collect_headers(msg, 0);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static int w_pvh_apply_headers(struct sip_msg *msg, char *p1, char *p2)
|
|
|
|
|
+{
|
|
|
|
|
+ return pvh_apply_headers(msg, 0);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static int ki_pvh_apply_headers(struct sip_msg *msg)
|
|
|
|
|
+{
|
|
|
|
|
+ return pvh_apply_headers(msg, 0);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static int w_pvh_reset_headers(struct sip_msg *msg, char *p1, char *p2)
|
|
|
|
|
+{
|
|
|
|
|
+ return pvh_reset_headers(msg);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static int w_pvh_check_header(struct sip_msg *msg, char *p1, char *p2)
|
|
|
|
|
+{
|
|
|
|
|
+ str hname = STR_NULL;
|
|
|
|
|
+
|
|
|
|
|
+ if(fixup_get_svalue(msg, (gparam_p)p1, &hname) < 0)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+
|
|
|
|
|
+ return pvh_check_header(msg, &hname);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static int w_pvh_append_header(struct sip_msg *msg, char *p1, char *p2)
|
|
|
|
|
+{
|
|
|
|
|
+ str hname = STR_NULL, hvalue = STR_NULL;
|
|
|
|
|
+
|
|
|
|
|
+ if(fixup_get_svalue(msg, (gparam_p)p1, &hname) < 0)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+
|
|
|
|
|
+ if(p2 && fixup_get_svalue(msg, (gparam_p)p2, &hvalue) < 0)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+
|
|
|
|
|
+static int pvh_check_header(struct sip_msg *_m, char *hname, char *_s2);
|
|
|
|
|
+static int pvh_append_header(struct sip_msg *_m, char *hname, char *hvalue);
|
|
|
|
|
+static int pvh_modify_header(struct sip_msg *_m, char *hname, char *hvalue);
|
|
|
|
|
+static int pvh_modify_header_idx(
|
|
|
|
|
+ struct sip_msg *_m, char *hname, char *hidx, char *hvalue);
|
|
|
|
|
+static int pvh_remove_header(struct sip_msg *_m, char *hname, char *_s2);
|
|
|
|
|
+static int pvh_remove_header_idx(struct sip_msg *_m, char *hname, char *hidx);
|
|
|
|
|
+ return pvh_append_header(msg, &hname, &hvalue);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static int w_pvh_modify_header(
|
|
|
|
|
+ struct sip_msg *msg, char *p1, char *p2, char *p3)
|
|
|
|
|
+{
|
|
|
|
|
+ int indx = 0;
|
|
|
|
|
+ str hname = STR_NULL, hvalue = STR_NULL;
|
|
|
|
|
+
|
|
|
|
|
+ if(fixup_get_svalue(msg, (gparam_p)p1, &hname) < 0)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+
|
|
|
|
|
+ if(p2 && fixup_get_svalue(msg, (gparam_p)p2, &hvalue) < 0)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+
|
|
|
|
|
+ if(p3 && fixup_get_ivalue(msg, (gparam_p)p3, &indx) < 0)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+
|
|
|
|
|
+ return pvh_modify_header(msg, &hname, &hvalue, indx);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static int w_pvh_remove_header(
|
|
|
|
|
+ struct sip_msg *msg, char *p1, char *p2, char *p3)
|
|
|
|
|
+{
|
|
|
|
|
+ int indx = -1;
|
|
|
|
|
+ str hname = STR_NULL;
|
|
|
|
|
+
|
|
|
|
|
+ if(fixup_get_svalue(msg, (gparam_p)p1, &hname) < 0)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+
|
|
|
|
|
+ if(p2 && fixup_get_ivalue(msg, (gparam_p)p2, &indx) < 0)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+
|
|
|
|
|
+ return pvh_remove_header(msg, &hname, indx);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/*
|
|
|
|
|
+ * Exported functions
|
|
|
|
|
+ */
|
|
|
|
|
+static cmd_export_t cmds[] = {
|
|
|
|
|
+ {"pvh_collect_headers", (cmd_function)pvh_collect_headers, 0, 0, 0,
|
|
|
|
|
+ {"pvh_collect_headers", (cmd_function)w_pvh_collect_headers, 0, 0, 0,
|
|
|
|
|
+ ANY_ROUTE},
|
|
|
|
|
+ {"pvh_apply_headers", (cmd_function)pvh_apply_headers, 0, 0, 0,
|
|
|
|
|
+ {"pvh_apply_headers", (cmd_function)w_pvh_apply_headers, 0, 0, 0,
|
|
|
|
|
+ ANY_ROUTE},
|
|
|
|
|
+ {"pvh_reset_headers", (cmd_function)pvh_reset_headers, 0, 0, 0,
|
|
|
|
|
+ {"pvh_reset_headers", (cmd_function)w_pvh_reset_headers, 0, 0, 0,
|
|
|
|
|
+ ANY_ROUTE},
|
|
|
|
|
+ {"pvh_check_header", (cmd_function)pvh_check_header, 1, fixup_spve_null,
|
|
|
|
|
+ fixup_free_spve_null, ANY_ROUTE},
|
|
|
|
|
+ {"pvh_append_header", (cmd_function)pvh_append_header, 2,
|
|
|
|
|
+ {"pvh_check_header", (cmd_function)w_pvh_check_header, 1,
|
|
|
|
|
+ fixup_spve_null, fixup_free_spve_null, ANY_ROUTE},
|
|
|
|
|
+ {"pvh_append_header", (cmd_function)w_pvh_append_header, 2,
|
|
|
|
|
+ fixup_spve_spve, fixup_free_spve_spve, ANY_ROUTE},
|
|
|
|
|
+ {"pvh_modify_header", (cmd_function)pvh_modify_header, 2,
|
|
|
|
|
+ {"pvh_modify_header", (cmd_function)w_pvh_modify_header, 2,
|
|
|
|
|
+ fixup_spve_spve, fixup_free_spve_spve, ANY_ROUTE},
|
|
|
|
|
+ {"pvh_modify_header", (cmd_function)pvh_modify_header_idx, 3,
|
|
|
|
|
+ {"pvh_modify_header", (cmd_function)w_pvh_modify_header, 3,
|
|
|
|
|
+ fixup_spve_all, fixup_free_spve_all, ANY_ROUTE},
|
|
|
|
|
+ {"pvh_remove_header", (cmd_function)pvh_remove_header, 1,
|
|
|
|
|
+ {"pvh_remove_header", (cmd_function)w_pvh_remove_header, 1,
|
|
|
|
|
+ fixup_spve_null, fixup_free_spve_null, ANY_ROUTE},
|
|
|
|
|
+ {"pvh_remove_header", (cmd_function)pvh_remove_header_idx, 2,
|
|
|
|
|
+ {"pvh_remove_header", (cmd_function)w_pvh_remove_header, 2,
|
|
|
|
|
+ fixup_spve_spve, fixup_free_spve_spve, ANY_ROUTE},
|
|
|
|
|
+ {0, 0, 0, 0, 0, 0}};
|
|
|
|
|
+
|
|
|
|
|
@ -1137,8 +1206,8 @@ index 0000000..3390e06
|
|
|
|
|
+ if(type & TMCB_RESPONSE_IN) {
|
|
|
|
|
+ msg = params->rpl;
|
|
|
|
|
+ if(msg != NULL && msg != FAKED_REPLY) {
|
|
|
|
|
+ pvh_reset_headers(msg, NULL, NULL);
|
|
|
|
|
+ pvh_collect_headers(msg, "1", NULL);
|
|
|
|
|
+ pvh_reset_headers(msg);
|
|
|
|
|
+ pvh_collect_headers(msg, 1);
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if(type & TMCB_REQUEST_FWDED) {
|
|
|
|
|
+ msg = params->req;
|
|
|
|
|
@ -1150,7 +1219,7 @@ index 0000000..3390e06
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(msg != NULL && msg != FAKED_REPLY)
|
|
|
|
|
+ pvh_apply_headers(msg, "1", NULL);
|
|
|
|
|
+ pvh_apply_headers(msg, 1);
|
|
|
|
|
+
|
|
|
|
|
+ return;
|
|
|
|
|
+}
|
|
|
|
|
@ -1165,7 +1234,7 @@ index 0000000..3390e06
|
|
|
|
|
+ LM_ERR("cannot register TM callbacks\n");
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+ pvh_collect_headers(msg, "1", NULL);
|
|
|
|
|
+ pvh_collect_headers(msg, 1);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ LM_ERR("unknown callback: %d\n", flags);
|
|
|
|
|
+ }
|
|
|
|
|
@ -1173,7 +1242,140 @@ index 0000000..3390e06
|
|
|
|
|
+ return 1;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+int pvh_collect_headers(struct sip_msg *msg, char *is_auto, char *_s2)
|
|
|
|
|
+static sr_kemi_t pvh_kemi_exports[] = {
|
|
|
|
|
+ {str_init("pv_headers"), str_init("pvh_collect_headers"), SR_KEMIP_INT,
|
|
|
|
|
+ ki_pvh_collect_headers,
|
|
|
|
|
+ {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
|
|
|
|
|
+ SR_KEMIP_NONE, SR_KEMIP_NONE}},
|
|
|
|
|
+ {str_init("pv_headers"), str_init("pvh_apply_headers"), SR_KEMIP_INT,
|
|
|
|
|
+ ki_pvh_apply_headers,
|
|
|
|
|
+ {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
|
|
|
|
|
+ SR_KEMIP_NONE, SR_KEMIP_NONE}},
|
|
|
|
|
+ {str_init("pv_headers"), str_init("pvh_reset_headers"), SR_KEMIP_INT,
|
|
|
|
|
+ pvh_reset_headers,
|
|
|
|
|
+ {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
|
|
|
|
|
+ SR_KEMIP_NONE, SR_KEMIP_NONE}},
|
|
|
|
|
+ {str_init("pv_headers"), str_init("pvh_check_header"), SR_KEMIP_INT,
|
|
|
|
|
+ pvh_check_header,
|
|
|
|
|
+ {SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
|
|
|
|
|
+ SR_KEMIP_NONE, SR_KEMIP_NONE}},
|
|
|
|
|
+ {str_init("pv_headers"), str_init("pvh_append_header"), SR_KEMIP_INT,
|
|
|
|
|
+ pvh_check_header,
|
|
|
|
|
+ {SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
|
|
|
|
|
+ SR_KEMIP_NONE, SR_KEMIP_NONE}},
|
|
|
|
|
+ {str_init("pv_headers"), str_init("pvh_modify_header"), SR_KEMIP_INT,
|
|
|
|
|
+ pvh_modify_header,
|
|
|
|
|
+ {SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
|
|
|
|
|
+ SR_KEMIP_NONE, SR_KEMIP_NONE}},
|
|
|
|
|
+ {str_init("pv_headers"), str_init("pvh_remove_header"), SR_KEMIP_INT,
|
|
|
|
|
+ pvh_remove_header,
|
|
|
|
|
+ {SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
|
|
|
|
|
+ SR_KEMIP_NONE, SR_KEMIP_NONE}},
|
|
|
|
|
+ {{0, 0}, {0, 0}, 0, NULL, {0, 0, 0, 0, 0, 0}}};
|
|
|
|
|
+
|
|
|
|
|
+int mod_register(char *path, int *dlflags, void *p1, void *p2)
|
|
|
|
|
+{
|
|
|
|
|
+ sr_kemi_modules_add(pvh_kemi_exports);
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
diff --git a/src/modules/pv_headers/pv_headers.h b/src/modules/pv_headers/pv_headers.h
|
|
|
|
|
new file mode 100644
|
|
|
|
|
index 0000000..556b7bf
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/src/modules/pv_headers/pv_headers.h
|
|
|
|
|
@@ -0,0 +1,51 @@
|
|
|
|
|
+/*
|
|
|
|
|
+ * PV Headers
|
|
|
|
|
+ *
|
|
|
|
|
+ * Copyright (C) 2018 Kirill Solomko <ksolomko@sipwise.com>
|
|
|
|
|
+ *
|
|
|
|
|
+ * This file is part of SIP Router, a free SIP server.
|
|
|
|
|
+ *
|
|
|
|
|
+ * SIP Router is free software; you can redistribute it and/or modify
|
|
|
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
|
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
+ * (at your option) any later version
|
|
|
|
|
+ *
|
|
|
|
|
+ * SIP Router is distributed in the hope that it will be useful,
|
|
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
+ * GNU General Public License for more details.
|
|
|
|
|
+ *
|
|
|
|
|
+ * You should have received a copy of the GNU General Public License
|
|
|
|
|
+ * along with this program; if not, write to the Free Software
|
|
|
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
|
+ *
|
|
|
|
|
+ */
|
|
|
|
|
+
|
|
|
|
|
+#ifndef PV_HEADERS_H
|
|
|
|
|
+#define PV_HEADERS_H
|
|
|
|
|
+
|
|
|
|
|
+#include "../../core/parser/parse_addr_spec.h"
|
|
|
|
|
+#include "../../modules/uac/api.h"
|
|
|
|
|
+
|
|
|
|
|
+typedef struct _xavp_c_data
|
|
|
|
|
+{
|
|
|
|
|
+ struct to_body to_b;
|
|
|
|
|
+ struct to_param *to_params;
|
|
|
|
|
+ str value;
|
|
|
|
|
+} xavp_c_data_t;
|
|
|
|
|
+
|
|
|
|
|
+extern uac_api_t uac;
|
|
|
|
|
+
|
|
|
|
|
+extern str xavp_name;
|
|
|
|
|
+extern str xavp_parsed_xname;
|
|
|
|
|
+
|
|
|
|
|
+extern unsigned int header_name_size;
|
|
|
|
|
+extern unsigned int header_value_size;
|
|
|
|
|
+
|
|
|
|
|
+extern str _hdr_from;
|
|
|
|
|
+extern str _hdr_to;
|
|
|
|
|
+
|
|
|
|
|
+extern int FL_PV_HDRS_COLLECTED;
|
|
|
|
|
+extern int FL_PV_HDRS_APPLIED;
|
|
|
|
|
+
|
|
|
|
|
+#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..1340500
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/src/modules/pv_headers/pvh_func.c
|
|
|
|
|
@@ -0,0 +1,388 @@
|
|
|
|
|
+/*
|
|
|
|
|
+ * pv_headers
|
|
|
|
|
+ *
|
|
|
|
|
+ * Copyright (C) 2018 Kirill Solomko <ksolomko@sipwise.com>
|
|
|
|
|
+ *
|
|
|
|
|
+ * This file is part of SIP Router, a free SIP server.
|
|
|
|
|
+ *
|
|
|
|
|
+ * SIP Router is free software; you can redistribute it and/or modify
|
|
|
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
|
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
+ * (at your option) any later version
|
|
|
|
|
+ *
|
|
|
|
|
+ * SIP Router is distributed in the hope that it will be useful,
|
|
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
+ * GNU General Public License for more details.
|
|
|
|
|
+ *
|
|
|
|
|
+ * You should have received a copy of the GNU General Public License
|
|
|
|
|
+ * along with this program; if not, write to the Free Software
|
|
|
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
|
+ *
|
|
|
|
|
+ */
|
|
|
|
|
+
|
|
|
|
|
+#include "../../core/dset.h"
|
|
|
|
|
+
|
|
|
|
|
+#include "pv_headers.h"
|
|
|
|
|
+#include "pvh_str.h"
|
|
|
|
|
+#include "pvh_hdr.h"
|
|
|
|
|
+#include "pvh_hash.h"
|
|
|
|
|
+#include "pvh_xavp.h"
|
|
|
|
|
+
|
|
|
|
|
+static str xavp_helper_xname = str_init("modparam_pv_headers");
|
|
|
|
|
+static str xavp_helper_name = str_init("xavp_name");
|
|
|
|
|
+
|
|
|
|
|
+int pvh_collect_headers(struct sip_msg *msg, int is_auto)
|
|
|
|
|
+{
|
|
|
|
|
+ struct hdr_field *hf = NULL;
|
|
|
|
|
+ str name = STR_NULL;
|
|
|
|
|
@ -1185,14 +1387,18 @@ index 0000000..3390e06
|
|
|
|
|
+
|
|
|
|
|
+ pvh_get_branch_index(msg, &br_idx);
|
|
|
|
|
+ LM_DBG("br_idx: %d\n", br_idx);
|
|
|
|
|
+ if(!(is_auto && strcmp(is_auto, "1") == 0)
|
|
|
|
|
+ && ((msg->first_line.type == SIP_REPLY
|
|
|
|
|
+ && isflagset(msg, FL_PV_HDRS_COLLECTED) == 1)
|
|
|
|
|
+ || (msg->first_line.type != SIP_REPLY
|
|
|
|
|
+ && isbflagset(br_idx, FL_PV_HDRS_COLLECTED)
|
|
|
|
|
+ == 1))) {
|
|
|
|
|
+ LM_ERR("headers are already collected\n");
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ if(!is_auto) {
|
|
|
|
|
+ if(msg->first_line.type == SIP_REPLY) {
|
|
|
|
|
+ if(isflagset(msg, FL_PV_HDRS_COLLECTED) == 1) {
|
|
|
|
|
+ LM_ERR("headers are already collected\n");
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if(isbflagset(br_idx, FL_PV_HDRS_COLLECTED)) {
|
|
|
|
|
+ LM_ERR("headers are already collected\n");
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(parse_headers(msg, HDR_EOH_F, 0) < 0) {
|
|
|
|
|
@ -1268,7 +1474,7 @@ index 0000000..3390e06
|
|
|
|
|
+ return -1;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+int pvh_apply_headers(struct sip_msg *msg, char *is_auto, char *_s2)
|
|
|
|
|
+int pvh_apply_headers(struct sip_msg *msg, int is_auto)
|
|
|
|
|
+{
|
|
|
|
|
+ sr_xavp_t *xavp = NULL;
|
|
|
|
|
+ sr_xavp_t *sub = NULL;
|
|
|
|
|
@ -1284,14 +1490,18 @@ index 0000000..3390e06
|
|
|
|
|
+
|
|
|
|
|
+ pvh_get_branch_index(msg, &br_idx);
|
|
|
|
|
+
|
|
|
|
|
+ if(!(is_auto && strcmp(is_auto, "1") == 0)
|
|
|
|
|
+ && ((msg->first_line.type == SIP_REPLY
|
|
|
|
|
+ && isflagset(msg, FL_PV_HDRS_APPLIED) == 1)
|
|
|
|
|
+ || (msg->first_line.type != SIP_REPLY
|
|
|
|
|
+ && isbflagset(br_idx, FL_PV_HDRS_APPLIED)
|
|
|
|
|
+ == 1))) {
|
|
|
|
|
+ LM_ERR("headers are already applied\n");
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ if(!is_auto) {
|
|
|
|
|
+ if(msg->first_line.type == SIP_REPLY) {
|
|
|
|
|
+ if(isflagset(msg, FL_PV_HDRS_APPLIED) == 1) {
|
|
|
|
|
+ LM_ERR("headers are already applied\n");
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if(isbflagset(br_idx, FL_PV_HDRS_APPLIED) == 1) {
|
|
|
|
|
+ LM_ERR("headers are already applied\n");
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(parse_headers(msg, HDR_EOH_F, 0) < 0) {
|
|
|
|
|
@ -1448,7 +1658,7 @@ index 0000000..3390e06
|
|
|
|
|
+ return res;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+int pvh_reset_headers(struct sip_msg *msg, char *_s1, char *_s2)
|
|
|
|
|
+int pvh_reset_headers(struct sip_msg *msg)
|
|
|
|
|
+{
|
|
|
|
|
+ str br_xname = STR_NULL;
|
|
|
|
|
+ int br_idx;
|
|
|
|
|
@ -1476,125 +1686,55 @@ index 0000000..3390e06
|
|
|
|
|
+ return 1;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+int pvh_check_header(struct sip_msg *msg, char *hname, char *_s2)
|
|
|
|
|
+int pvh_check_header(struct sip_msg *msg, str *hname)
|
|
|
|
|
+{
|
|
|
|
|
+ str hname_s = STR_NULL;
|
|
|
|
|
+
|
|
|
|
|
+ if(hname == NULL || pvh_fixup_svalue(msg, hname, &hname_s) < 0)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+
|
|
|
|
|
+ if(pvh_xavp_get_child(msg, &xavp_name, &hname_s) == NULL)
|
|
|
|
|
+ if(pvh_xavp_get_child(msg, &xavp_name, hname) == NULL)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+
|
|
|
|
|
+ return 1;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+int pvh_append_header(struct sip_msg *msg, char *hname, char *hvalue)
|
|
|
|
|
+int pvh_append_header(struct sip_msg *msg, str *hname, str *hvalue)
|
|
|
|
|
+{
|
|
|
|
|
+ str hname_s = STR_NULL, hvalue_s = STR_NULL;
|
|
|
|
|
+
|
|
|
|
|
+ if(hname == NULL || pvh_fixup_svalue(msg, hname, &hname_s) < 0)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+
|
|
|
|
|
+ if(hvalue != NULL)
|
|
|
|
|
+ if(pvh_fixup_svalue(msg, hvalue, &hvalue_s) < 0)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+
|
|
|
|
|
+ return pvh_set_xavp(
|
|
|
|
|
+ msg, &xavp_name, &hname_s, &hvalue_s, SR_XTYPE_STR, 0, 1);
|
|
|
|
|
+ return pvh_set_xavp(msg, &xavp_name, hname, hvalue, SR_XTYPE_STR, 0, 1);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+int pvh_modify_header(struct sip_msg *msg, char *hname, char *hvalue)
|
|
|
|
|
+int pvh_modify_header(struct sip_msg *msg, str *hname, str *hvalue, int indx)
|
|
|
|
|
+{
|
|
|
|
|
+ str hname_s = STR_NULL, hvalue_s = STR_NULL;
|
|
|
|
|
+
|
|
|
|
|
+ if(hname == NULL || pvh_fixup_svalue(msg, hname, &hname_s) < 0)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+
|
|
|
|
|
+ if(hvalue != NULL)
|
|
|
|
|
+ if(pvh_fixup_svalue(msg, hvalue, &hvalue_s) < 0)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+
|
|
|
|
|
+ return pvh_set_xavp(
|
|
|
|
|
+ msg, &xavp_name, &hname_s, &hvalue_s, SR_XTYPE_STR, 0, 0);
|
|
|
|
|
+ return pvh_set_xavp(msg, &xavp_name, hname, hvalue, SR_XTYPE_STR, indx, 0);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+int pvh_modify_header_idx(
|
|
|
|
|
+ struct sip_msg *msg, char *hname, char *hidx, char *hvalue)
|
|
|
|
|
+int pvh_remove_header(struct sip_msg *msg, str *hname, int indx)
|
|
|
|
|
+{
|
|
|
|
|
+ str hname_s = STR_NULL, hidx_s = STR_NULL, hvalue_s = STR_NULL;
|
|
|
|
|
+ int idx = 0;
|
|
|
|
|
+
|
|
|
|
|
+ if(hname == NULL || pvh_fixup_svalue(msg, hname, &hname_s) < 0)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+
|
|
|
|
|
+ if(hidx == NULL || pvh_fixup_svalue(msg, hidx, &hidx_s) < 0)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ idx = atoi(hidx_s.s);
|
|
|
|
|
+
|
|
|
|
|
+ if(hvalue != NULL)
|
|
|
|
|
+ if(pvh_fixup_svalue(msg, hvalue, &hvalue_s) < 0)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+
|
|
|
|
|
+ return pvh_set_xavp(
|
|
|
|
|
+ msg, &xavp_name, &hname_s, &hvalue_s, SR_XTYPE_STR, idx, 0);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+int pvh_remove_header(struct sip_msg *msg, char *hname, char *_s2)
|
|
|
|
|
+{
|
|
|
|
|
+ str hname_s = STR_NULL;
|
|
|
|
|
+ sr_xavp_t *avp = NULL;
|
|
|
|
|
+ int idx = 0;
|
|
|
|
|
+ int count = 0;
|
|
|
|
|
+
|
|
|
|
|
+ if(hname == NULL || pvh_fixup_svalue(msg, hname, &hname_s) < 0)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+
|
|
|
|
|
+ if((avp = pvh_xavp_get_child(msg, &xavp_name, &hname_s)) == NULL)
|
|
|
|
|
+ if((avp = pvh_xavp_get_child(msg, &xavp_name, hname)) == NULL)
|
|
|
|
|
+ return 1;
|
|
|
|
|
+
|
|
|
|
|
+ count = xavp_count(&hname_s, &avp);
|
|
|
|
|
+
|
|
|
|
|
+ while(idx < count) {
|
|
|
|
|
+ if(pvh_set_xavp(msg, &xavp_name, &hname_s, NULL, SR_XTYPE_STR, idx++, 0)
|
|
|
|
|
+ if(indx < 0) {
|
|
|
|
|
+ count = xavp_count(hname, &avp);
|
|
|
|
|
+ do {
|
|
|
|
|
+ if(pvh_set_xavp(
|
|
|
|
|
+ msg, &xavp_name, hname, NULL, SR_XTYPE_STR, indx++, 0)
|
|
|
|
|
+ < 1)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ } while(indx < count);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if(pvh_set_xavp(msg, &xavp_name, hname, NULL, SR_XTYPE_STR, indx, 0)
|
|
|
|
|
+ < 1)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return 1;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+int pvh_remove_header_idx(struct sip_msg *msg, char *hname, char *hidx)
|
|
|
|
|
+{
|
|
|
|
|
+ str hname_s = STR_NULL;
|
|
|
|
|
+ str hidx_s = STR_NULL;
|
|
|
|
|
+ int idx = 0;
|
|
|
|
|
+
|
|
|
|
|
+ if(hname == NULL || pvh_fixup_svalue(msg, hname, &hname_s) < 0)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+
|
|
|
|
|
+ if(hidx == NULL || pvh_fixup_svalue(msg, hidx, &hidx_s) < 0)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ idx = atoi(hidx_s.s);
|
|
|
|
|
+
|
|
|
|
|
+ return pvh_set_xavp(msg, &xavp_name, &hname_s, NULL, SR_XTYPE_STR, idx, 0);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+int pvh_fixup_svalue(struct sip_msg *msg, char *src, str *dst)
|
|
|
|
|
+{
|
|
|
|
|
+ if(fixup_get_svalue(msg, (gparam_p)src, dst) < 0) {
|
|
|
|
|
+ LM_ERR("unable to parse param value\n");
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+ return 1;
|
|
|
|
|
+}
|
|
|
|
|
diff --git a/src/modules/pv_headers/pv_headers.h b/src/modules/pv_headers/pv_headers.h
|
|
|
|
|
diff --git a/src/modules/pv_headers/pvh_func.h b/src/modules/pv_headers/pvh_func.h
|
|
|
|
|
new file mode 100644
|
|
|
|
|
index 0000000..83cc845
|
|
|
|
|
index 0000000..0fe5524
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/src/modules/pv_headers/pv_headers.h
|
|
|
|
|
@@ -0,0 +1,45 @@
|
|
|
|
|
+++ b/src/modules/pv_headers/pvh_func.h
|
|
|
|
|
@@ -0,0 +1,38 @@
|
|
|
|
|
+/*
|
|
|
|
|
+ * PV Headers
|
|
|
|
|
+ *
|
|
|
|
|
@ -1618,28 +1758,21 @@ index 0000000..83cc845
|
|
|
|
|
+ *
|
|
|
|
|
+ */
|
|
|
|
|
+
|
|
|
|
|
+#ifndef PV_HEADERS_H
|
|
|
|
|
+#define PV_HEADERS_H
|
|
|
|
|
+
|
|
|
|
|
+#include "../../core/parser/parse_addr_spec.h"
|
|
|
|
|
+
|
|
|
|
|
+typedef struct _xavp_c_data
|
|
|
|
|
+{
|
|
|
|
|
+ struct to_body to_b;
|
|
|
|
|
+ struct to_param *to_params;
|
|
|
|
|
+ str value;
|
|
|
|
|
+} xavp_c_data_t;
|
|
|
|
|
+#ifndef PV_FUNC_H
|
|
|
|
|
+#define PV_FUNC_H
|
|
|
|
|
+
|
|
|
|
|
+extern str xavp_name;
|
|
|
|
|
+extern str xavp_parsed_xname;
|
|
|
|
|
+#include "../../core/parser/msg_parser.h"
|
|
|
|
|
+
|
|
|
|
|
+extern unsigned int header_name_size;
|
|
|
|
|
+extern unsigned int header_value_size;
|
|
|
|
|
+int pvh_collect_headers(struct sip_msg *msg, int is_auto);
|
|
|
|
|
+int pvh_apply_headers(struct sip_msg *msg, int is_auto);
|
|
|
|
|
+int pvh_reset_headers(struct sip_msg *msg);
|
|
|
|
|
+
|
|
|
|
|
+extern str _hdr_from;
|
|
|
|
|
+extern str _hdr_to;
|
|
|
|
|
+int pvh_check_header(struct sip_msg *msg, str *hname);
|
|
|
|
|
+int pvh_append_header(struct sip_msg *msg, str *hname, str *hvalue);
|
|
|
|
|
+int pvh_modify_header(struct sip_msg *msg, str *hname, str *hvalue, int indx);
|
|
|
|
|
+int pvh_remove_header(struct sip_msg *msg, str *hname, int indx);
|
|
|
|
|
+
|
|
|
|
|
+#endif /* PV_HEADERS_H */
|
|
|
|
|
+#endif /* PV_FUNC_H */
|
|
|
|
|
diff --git a/src/modules/pv_headers/pvh_hash.c b/src/modules/pv_headers/pvh_hash.c
|
|
|
|
|
new file mode 100644
|
|
|
|
|
index 0000000..f269868
|
|
|
|
|
|