Browse code

textopsx: added functions and variables to iterate headers list

Daniel-Constantin Mierla authored on 07/07/2021 10:11:04
Showing 1 changed files
... ...
@@ -73,12 +73,31 @@ static int assign_hf_value_fixup(void **param, int param_no);
73 73
 static int remove_hf_value2_fixup(void **param, int param_no);
74 74
 static int assign_hf_value2_fixup(void **param, int param_no);
75 75
 
76
+static int w_hf_iterator_start(sip_msg_t *msg, char *piname, char *p2);
77
+static int w_hf_iterator_next(sip_msg_t *msg, char *piname, char *p2);
78
+static int w_hf_iterator_end(sip_msg_t *msg, char *piname, char *p2);
79
+
76 80
 static int bind_textopsx(textopsx_api_t *tob);
77 81
 
78 82
 static int mod_init(void);
79 83
 
80 84
 extern select_row_t sel_declaration[];
81 85
 
86
+void hf_iterator_init(void);
87
+static int pv_parse_hf_iterator_name(pv_spec_t *sp, str *in);
88
+static int pv_get_hf_iterator_hname(sip_msg_t *msg, pv_param_t *param,
89
+		pv_value_t *res);
90
+static int pv_get_hf_iterator_hbody(sip_msg_t *msg, pv_param_t *param,
91
+		pv_value_t *res);
92
+
93
+static pv_export_t mod_pvs[] = {
94
+	{ {"hfitname", sizeof("hfitname")-1}, PVT_OTHER, pv_get_hf_iterator_hname, 0,
95
+		pv_parse_hf_iterator_name, 0, 0, 0 },
96
+	{ {"hfitbody", sizeof("hfitname")-1}, PVT_OTHER, pv_get_hf_iterator_hbody, 0,
97
+		pv_parse_hf_iterator_name, 0, 0, 0 },
98
+	{ {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
99
+};
100
+
82 101
 /* cfg functions */
83 102
 /* clag-format off */
84 103
 static cmd_export_t cmds[] = {
... ...
@@ -111,6 +130,12 @@ static cmd_export_t cmds[] = {
111 130
 			REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE},
112 131
 	{"hf_value_exists", incexc_hf_value_f, 2, hf_value_exists_fixup, 0,
113 132
 			REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE},
133
+	{"hf_iterator_start", w_hf_iterator_start, 1, fixup_spve_null,
134
+			fixup_free_spve_null, ANY_ROUTE},
135
+	{"hf_iterator_next", w_hf_iterator_next, 1, fixup_spve_null,
136
+			fixup_free_spve_null, ANY_ROUTE},
137
+	{"hf_iterator_end", w_hf_iterator_end, 1, fixup_spve_null,
138
+			fixup_free_spve_null, ANY_ROUTE},
114 139
 
115 140
 	{"bind_textopsx", (cmd_function)bind_textopsx, 1, 0, 0, ANY_ROUTE},
116 141
 
... ...
@@ -124,7 +149,7 @@ struct module_exports exports = {
124 149
 	cmds,			/* exported cfg functions */
125 150
 	0,				/* exported cfg parameters */
126 151
 	0,				/* exported RPC methods */
127
-	0,				/* exported pseudo-variables */
152
+	mod_pvs,		/* exported pseudo-variables */
128 153
 	0,				/* response handling function */
129 154
 	mod_init,		/* module init function */
130 155
 	0,				/* per-child init function */
... ...
@@ -142,6 +167,8 @@ static int mod_init(void)
142 167
 	tcp_set_clone_rcvbuf(1);
143 168
 #endif
144 169
 	register_select_table(sel_declaration);
170
+	hf_iterator_init();
171
+
145 172
 	return 0;
146 173
 }
147 174
 
... ...
@@ -1793,6 +1820,253 @@ static int ki_assign_hf_value2(sip_msg_t *msg, str *hexp, str *val)
1793 1820
 			insupddel_hf_value_f);
1794 1821
 }
1795 1822
 
1823
+#define HF_ITERATOR_SIZE	4
1824
+#define HF_ITERATOR_NAME_SIZE	32
1825
+
1826
+typedef struct hf_iterator {
1827
+	str name;
1828
+	char bname[HF_ITERATOR_NAME_SIZE];
1829
+	hdr_field_t *it;
1830
+	int eoh;
1831
+} hf_iterator_t;
1832
+
1833
+static hf_iterator_t _hf_iterators[HF_ITERATOR_SIZE];
1834
+
1835
+/**
1836
+ *
1837
+ */
1838
+void hf_iterator_init(void)
1839
+{
1840
+	memset(_hf_iterators, 0, HF_ITERATOR_SIZE*sizeof(hf_iterator_t));
1841
+}
1842
+
1843
+/**
1844
+ *
1845
+ */
1846
+static int ki_hf_iterator_start(sip_msg_t *msg, str *iname)
1847
+{
1848
+	int i;
1849
+	int k;
1850
+
1851
+	k = -1;
1852
+	for(i=0; i<HF_ITERATOR_SIZE; i++) {
1853
+		if(_hf_iterators[i].name.len>0) {
1854
+			if(_hf_iterators[i].name.len==iname->len
1855
+					&& strncmp(_hf_iterators[i].name.s, iname->s, iname->len)==0) {
1856
+				k = i;
1857
+				break;
1858
+			}
1859
+		} else {
1860
+			if(k==-1) k = i;
1861
+		}
1862
+	}
1863
+	if(k==-1) {
1864
+		LM_ERR("no iterator available - max number is %d\n", HF_ITERATOR_SIZE);
1865
+		return -1;
1866
+	}
1867
+	if(_hf_iterators[k].name.len<=0) {
1868
+		if(iname->len>=HF_ITERATOR_NAME_SIZE)
1869
+		{
1870
+			LM_ERR("iterator name is too big [%.*s] (max %d)\n",
1871
+					iname->len, iname->s, HF_ITERATOR_NAME_SIZE);
1872
+			return -1;
1873
+		}
1874
+		strncpy(_hf_iterators[k].bname, iname->s, iname->len);
1875
+		_hf_iterators[k].bname[iname->len] = '\0';
1876
+		_hf_iterators[k].name.len = iname->len;
1877
+		_hf_iterators[k].name.s = _hf_iterators[k].bname;
1878
+	}
1879
+	_hf_iterators[k].it = NULL;
1880
+	_hf_iterators[k].eoh = 0;
1881
+	if(parse_headers(msg, HDR_EOH_F, 0) == -1) {
1882
+		LM_ERR("failed parsing message\n");
1883
+		return -1;
1884
+	}
1885
+	if(msg->headers==NULL) {
1886
+		LM_ERR("no headers for iterator [%.*s]\n", iname->len, iname->s);
1887
+		return -1;
1888
+	}
1889
+	return 1;
1890
+}
1891
+
1892
+/**
1893
+ *
1894
+ */
1895
+static int w_hf_iterator_start(sip_msg_t *msg, char *piname, char *p2)
1896
+{
1897
+	str iname = STR_NULL;
1898
+	if(fixup_get_svalue(msg, (gparam_t*)piname, &iname)<0) {
1899
+		LM_ERR("failed to get iterator name\n");
1900
+		return -1;
1901
+	}
1902
+	return ki_hf_iterator_start(msg, &iname);
1903
+}
1904
+
1905
+/**
1906
+ *
1907
+ */
1908
+static int ki_hf_iterator_next(sip_msg_t *msg, str *iname)
1909
+{
1910
+	int i;
1911
+	int k;
1912
+
1913
+	k = -1;
1914
+	for(i=0; i<HF_ITERATOR_SIZE; i++) {
1915
+		if(_hf_iterators[i].name.len>0) {
1916
+			if(_hf_iterators[i].name.len==iname->len
1917
+					&& strncmp(_hf_iterators[i].name.s, iname->s, iname->len)==0) {
1918
+				k = i;
1919
+				break;
1920
+			}
1921
+		}
1922
+	}
1923
+	if(k==-1) {
1924
+		LM_ERR("iterator not available [%.*s]\n", iname->len, iname->s);
1925
+		return -1;
1926
+	}
1927
+	if(_hf_iterators[k].it == NULL) {
1928
+		_hf_iterators[k].it = msg->headers;
1929
+	} else {
1930
+		_hf_iterators[k].it = _hf_iterators[k].it->next;
1931
+	}
1932
+	if(_hf_iterators[k].it == NULL) {
1933
+		_hf_iterators[k].eoh = 1;
1934
+	}
1935
+	return 1;
1936
+}
1937
+
1938
+/**
1939
+ *
1940
+ */
1941
+static int w_hf_iterator_next(sip_msg_t *msg, char *piname, char *p2)
1942
+{
1943
+	str iname = STR_NULL;
1944
+	if(fixup_get_svalue(msg, (gparam_t*)piname, &iname)<0) {
1945
+		LM_ERR("failed to get iterator name\n");
1946
+		return -1;
1947
+	}
1948
+	return ki_hf_iterator_next(msg, &iname);
1949
+}
1950
+
1951
+/**
1952
+ *
1953
+ */
1954
+static int ki_hf_iterator_end(sip_msg_t *msg, str *iname)
1955
+{
1956
+	int i;
1957
+	int k;
1958
+
1959
+	k = -1;
1960
+	for(i=0; i<HF_ITERATOR_SIZE; i++) {
1961
+		if(_hf_iterators[i].name.len>0) {
1962
+			if(_hf_iterators[i].name.len==iname->len
1963
+					&& strncmp(_hf_iterators[i].name.s, iname->s, iname->len)==0) {
1964
+				k = i;
1965
+				break;
1966
+			}
1967
+		}
1968
+	}
1969
+	if(k==-1) {
1970
+		LM_ERR("iterator not available [%.*s]\n", iname->len, iname->s);
1971
+		return -1;
1972
+	}
1973
+	_hf_iterators[k].it = NULL;
1974
+	_hf_iterators[k].eoh = 0;
1975
+	return 1;
1976
+}
1977
+
1978
+/**
1979
+ *
1980
+ */
1981
+static int w_hf_iterator_end(sip_msg_t *msg, char *piname, char *p2)
1982
+{
1983
+	str iname = STR_NULL;
1984
+	if(fixup_get_svalue(msg, (gparam_t*)piname, &iname)<0) {
1985
+		LM_ERR("failed to get iterator name\n");
1986
+		return -1;
1987
+	}
1988
+	return ki_hf_iterator_end(msg, &iname);
1989
+}
1990
+
1991
+/**
1992
+ *
1993
+ */
1994
+static int pv_parse_hf_iterator_name(pv_spec_t *sp, str *in)
1995
+{
1996
+	if(in->len<=0) {
1997
+		return -1;
1998
+	}
1999
+
2000
+	sp->pvp.pvn.u.isname.name.s.s = in->s;
2001
+	sp->pvp.pvn.u.isname.name.s.len = in->len;
2002
+	sp->pvp.pvn.u.isname.type = 0;
2003
+	sp->pvp.pvn.type = PV_NAME_INTSTR;
2004
+
2005
+	return 0;
2006
+}
2007
+
2008
+/**
2009
+ *
2010
+ */
2011
+static int pv_get_hf_iterator_hname(sip_msg_t *msg, pv_param_t *param, pv_value_t *res)
2012
+{
2013
+	int i;
2014
+	int k;
2015
+	str *iname;
2016
+
2017
+	iname = &param->pvn.u.isname.name.s;
2018
+	k = -1;
2019
+	for(i=0; i<HF_ITERATOR_SIZE; i++) {
2020
+		if(_hf_iterators[i].name.len>0) {
2021
+			if(_hf_iterators[i].name.len==iname->len
2022
+					&& strncmp(_hf_iterators[i].name.s, iname->s, iname->len)==0) {
2023
+				k = i;
2024
+				break;
2025
+			}
2026
+		}
2027
+	}
2028
+	if(k==-1) {
2029
+		LM_ERR("iterator not available [%.*s]\n", iname->len, iname->s);
2030
+		return pv_get_null(msg, param, res);
2031
+	}
2032
+
2033
+	if(_hf_iterators[i].it==NULL) {
2034
+		return pv_get_null(msg, param, res);
2035
+	}
2036
+	return pv_get_strval(msg, param, res, &_hf_iterators[i].it->name);
2037
+}
2038
+
2039
+/**
2040
+ *
2041
+ */
2042
+static int pv_get_hf_iterator_hbody(sip_msg_t *msg, pv_param_t *param, pv_value_t *res)
2043
+{
2044
+	int i;
2045
+	int k;
2046
+	str *iname;
2047
+
2048
+	iname = &param->pvn.u.isname.name.s;
2049
+	k = -1;
2050
+	for(i=0; i<HF_ITERATOR_SIZE; i++) {
2051
+		if(_hf_iterators[i].name.len>0) {
2052
+			if(_hf_iterators[i].name.len==iname->len
2053
+					&& strncmp(_hf_iterators[i].name.s, iname->s, iname->len)==0) {
2054
+				k = i;
2055
+				break;
2056
+			}
2057
+		}
2058
+	}
2059
+	if(k==-1) {
2060
+		LM_ERR("iterator not available [%.*s]\n", iname->len, iname->s);
2061
+		return pv_get_null(msg, param, res);
2062
+	}
2063
+
2064
+	if(_hf_iterators[i].it==NULL) {
2065
+		return pv_get_null(msg, param, res);
2066
+	}
2067
+	return pv_get_strval(msg, param, res, &_hf_iterators[i].it->body);
2068
+}
2069
+
1796 2070
 /* select implementation */
1797 2071
 static int sel_hf_value(str *res, select_t *s, struct sip_msg *msg)
1798 2072
 { /* dummy */