Browse code

dispatcher: use xavps instead of avps

- removed avp names parameters
- new parameters:
- xavp_dst - name of the xavp to store destination records
- xavp_dst_mode - control the fields added to xavp_dst
- xavp_ctx - name of the xavp to store context attributes
- xavp_ctx_mode - control the fields added to xavp_ctx

Daniel-Constantin Mierla authored on 12/06/2018 06:35:15
Showing 3 changed files
... ...
@@ -44,7 +44,7 @@
44 44
 #include "../../core/parser/parse_uri.h"
45 45
 #include "../../core/parser/parse_from.h"
46 46
 #include "../../core/parser/parse_param.h"
47
-#include "../../core/usr_avp.h"
47
+#include "../../core/xavp.h"
48 48
 #include "../../core/parser/digest/digest.h"
49 49
 #include "../../core/resolve.h"
50 50
 #include "../../core/lvalue.h"
... ...
@@ -1645,19 +1645,16 @@ int ds_load_update(struct sip_msg *msg)
1645 1645
  */
1646 1646
 int ds_load_unset(struct sip_msg *msg)
1647 1647
 {
1648
-	struct search_state st;
1649
-	struct usr_avp *prev_avp;
1650
-	int_str avp_value;
1648
+	sr_xavp_t *rxavp = NULL;
1651 1649
 
1652
-	if(dstid_avp_name.n == 0)
1650
+	if(ds_xavp_dst.len <= 0)
1653 1651
 		return 0;
1654 1652
 
1655 1653
 	/* for INVITE requests should be called after dst list is built */
1656 1654
 	if(msg->first_line.type == SIP_REQUEST
1657 1655
 			&& msg->first_line.u.request.method_value == METHOD_INVITE) {
1658
-		prev_avp = search_first_avp(
1659
-				dstid_avp_type, dstid_avp_name, &avp_value, &st);
1660
-		if(prev_avp == NULL)
1656
+		rxavp = xavp_get_child_with_sval(&ds_xavp_dst, &ds_xavp_dst_dstid);
1657
+		if(rxavp == NULL)
1661 1658
 			return 0;
1662 1659
 	}
1663 1660
 	return ds_load_remove(msg);
... ...
@@ -1791,6 +1788,89 @@ int ds_add_branches(sip_msg_t *msg, ds_set_t *idx, unsigned int hash, int mode)
1791 1788
 	return 0;
1792 1789
 }
1793 1790
 
1791
+/**
1792
+ *
1793
+ */
1794
+int ds_add_xavp_record(ds_set_t *dsidx, int pos, int set, int alg)
1795
+{
1796
+	sr_xavp_t *nxavp=NULL;
1797
+	sr_xval_t nxval;
1798
+	char buf[2 + 16 + 1];
1799
+
1800
+	/* add destination uri field */
1801
+	memset(&nxval, 0, sizeof(sr_xval_t));
1802
+	nxval.type = SR_XTYPE_STR;
1803
+	nxval.v.s = dsidx->dlist[pos].uri;
1804
+	if(xavp_add_value(&ds_xavp_dst_addr, &nxval, &nxavp)==NULL) {
1805
+		LM_ERR("failed to add destination uri xavp field\n");
1806
+		return -1;
1807
+	}
1808
+
1809
+	/* add setid field */
1810
+	memset(&nxval, 0, sizeof(sr_xval_t));
1811
+	nxval.type = SR_XTYPE_INT;
1812
+	nxval.v.i = set;
1813
+	if(xavp_add_value(&ds_xavp_dst_grp, &nxval, &nxavp)==NULL) {
1814
+		xavp_destroy_list(&nxavp);
1815
+		LM_ERR("failed to add destination setid xavp field\n");
1816
+		return -1;
1817
+	}
1818
+
1819
+	if(((ds_xavp_dst_mode & DS_XAVP_DST_SKIP_ATTRS) == 0)
1820
+			&& (dsidx->dlist[pos].attrs.body.len > 0)) {
1821
+		memset(&nxval, 0, sizeof(sr_xval_t));
1822
+		nxval.type = SR_XTYPE_STR;
1823
+		nxval.v.s = dsidx->dlist[pos].attrs.body;
1824
+		if(xavp_add_value(&ds_xavp_dst_attrs, &nxval, &nxavp)==NULL) {
1825
+			xavp_destroy_list(&nxavp);
1826
+			LM_ERR("failed to add destination attrs xavp field\n");
1827
+			return -1;
1828
+		}
1829
+	}
1830
+
1831
+	if(dsidx->dlist[pos].sock) {
1832
+		memset(&nxval, 0, sizeof(sr_xval_t));
1833
+		nxval.type = SR_XTYPE_STR;
1834
+		nxval.v.s.len = 1 + sprintf(buf, "%p", dsidx->dlist[pos].sock);
1835
+		nxval.v.s.s = buf;
1836
+		if(xavp_add_value(&ds_xavp_dst_sock, &nxval, &nxavp)==NULL) {
1837
+			xavp_destroy_list(&nxavp);
1838
+			LM_ERR("failed to add destination sock xavp field\n");
1839
+			return -1;
1840
+		}
1841
+	}
1842
+
1843
+	if(alg == DS_ALG_CALLLOAD) {
1844
+		if(dsidx->dlist[pos].attrs.duid.len <= 0) {
1845
+			LM_ERR("no uid for destination: %d %.*s\n", set,
1846
+					dsidx->dlist[pos].uri.len,
1847
+					dsidx->dlist[pos].uri.s);
1848
+			xavp_destroy_list(&nxavp);
1849
+			return -1;
1850
+		}
1851
+		memset(&nxval, 0, sizeof(sr_xval_t));
1852
+		nxval.type = SR_XTYPE_STR;
1853
+		nxval.v.s = dsidx->dlist[pos].attrs.duid;
1854
+		if(xavp_add_value(&ds_xavp_dst_dstid, &nxval, &nxavp)==NULL) {
1855
+			xavp_destroy_list(&nxavp);
1856
+			LM_ERR("failed to add destination dst uid xavp field\n");
1857
+			return -1;
1858
+		}
1859
+	}
1860
+
1861
+	/* add xavp in root list */
1862
+	memset(&nxval, 0, sizeof(sr_xval_t));
1863
+	nxval.type = SR_XTYPE_XAVP;
1864
+	nxval.v.xavp = nxavp;
1865
+	if(xavp_add_value(&ds_xavp_dst, &nxval, NULL)==NULL) {
1866
+		LM_ERR("cannot add dst xavp to root list\n");
1867
+		xavp_destroy_list(&nxavp);
1868
+		return -1;
1869
+	}
1870
+
1871
+	return 0;
1872
+}
1873
+
1794 1874
 /**
1795 1875
  *
1796 1876
  */
... ...
@@ -1810,10 +1890,10 @@ int ds_select_dst_limit(
1810 1890
 		sip_msg_t *msg, int set, int alg, unsigned int limit, int mode)
1811 1891
 {
1812 1892
 	int i, cnt;
1813
-	unsigned int hash, lhash;
1814
-	int_str avp_val;
1893
+	int crt_added;
1894
+	unsigned int hash;
1815 1895
 	ds_set_t *idx = NULL;
1816
-	char buf[2 + 16 + 1];
1896
+	sr_xval_t nxval;
1817 1897
 
1818 1898
 	if(msg == NULL) {
1819 1899
 		LM_ERR("bad parameters\n");
... ...
@@ -1917,8 +1997,8 @@ int ds_select_dst_limit(
1917 1997
 				alg = 0;
1918 1998
 				break;
1919 1999
 			}
1920
-			if(dstid_avp_name.n == 0) {
1921
-				LM_ERR("no dst ID avp for load distribution"
2000
+			if(ds_xavp_dst.len <= 0) {
2001
+				LM_ERR("no dst xavp for load distribution"
1922 2002
 					   " - using first entry...\n");
1923 2003
 				hash = 0;
1924 2004
 				alg = 0;
... ...
@@ -2003,185 +2083,81 @@ int ds_select_dst_limit(
2003 2083
 	if(!(ds_flags & DS_FAILOVER_ON))
2004 2084
 		return 1;
2005 2085
 
2006
-	if(dst_avp_name.n != 0) {
2007
-		/* add default dst to last position in AVP list */
2008
-		if(ds_use_default != 0 && hash != idx->nr - 1 && cnt < limit) {
2009
-			avp_val.s = idx->dlist[idx->nr - 1].uri;
2010
-			if(add_avp(AVP_VAL_STR | dst_avp_type, dst_avp_name, avp_val) != 0)
2011
-				return -1;
2012
-
2013
-			if(attrs_avp_name.n != 0
2014
-					&& idx->dlist[idx->nr - 1].attrs.body.len > 0) {
2015
-				avp_val.s = idx->dlist[idx->nr - 1].attrs.body;
2016
-				if(add_avp(AVP_VAL_STR | attrs_avp_type, attrs_avp_name,
2017
-						   avp_val)
2018
-						!= 0)
2019
-					return -1;
2020
-			}
2021
-
2022
-			/* only add sock_avp if dst_avp is set */
2023
-			if(sock_avp_name.n != 0 && idx->dlist[idx->nr - 1].sock) {
2024
-				avp_val.s.len =
2025
-						1 + sprintf(buf, "%p", idx->dlist[idx->nr - 1].sock);
2026
-				avp_val.s.s = buf;
2027
-				if(add_avp(AVP_VAL_STR | sock_avp_type, sock_avp_name, avp_val)
2028
-						!= 0)
2029
-					return -1;
2030
-			}
2031
-
2032
-			if(alg == DS_ALG_CALLLOAD) {
2033
-				if(idx->dlist[idx->nr - 1].attrs.duid.len <= 0) {
2034
-					LM_ERR("no uid for destination: %d %.*s\n", set,
2035
-							idx->dlist[idx->nr - 1].uri.len,
2036
-							idx->dlist[idx->nr - 1].uri.s);
2037
-					return -1;
2038
-				}
2039
-				avp_val.s = idx->dlist[idx->nr - 1].attrs.duid;
2040
-				if(add_avp(AVP_VAL_STR | dstid_avp_type, dstid_avp_name,
2041
-						   avp_val)
2042
-						!= 0)
2043
-					return -1;
2044
-			}
2045
-			cnt++;
2046
-		}
2047
-
2048
-		/* add to avp in reverse order */
2049
-		for(i = hash - 1; i >= 0 && cnt < limit; i--) {
2050
-			if(ds_skip_dst(idx->dlist[i].flags)
2051
-					|| (ds_use_default != 0 && i == (idx->nr - 1)))
2052
-				continue;
2053
-			/* max load exceeded per destination */
2054
-			if(alg == DS_ALG_CALLLOAD
2055
-					&& idx->dlist[i].dload >= idx->dlist[i].attrs.maxload)
2056
-				continue;
2057
-			LM_DBG("using entry [%d/%d]\n", set, i);
2058
-			avp_val.s = idx->dlist[i].uri;
2059
-			if(add_avp(AVP_VAL_STR | dst_avp_type, dst_avp_name, avp_val) != 0)
2060
-				return -1;
2061
-
2062
-			if(attrs_avp_name.n != 0 && idx->dlist[i].attrs.body.len > 0) {
2063
-				avp_val.s = idx->dlist[i].attrs.body;
2064
-				if(add_avp(AVP_VAL_STR | attrs_avp_type, attrs_avp_name,
2065
-						   avp_val)
2066
-						!= 0)
2067
-					return -1;
2068
-			}
2069
-
2070
-			if(sock_avp_name.n != 0 && idx->dlist[i].sock) {
2071
-				avp_val.s.len = 1 + sprintf(buf, "%p", idx->dlist[i].sock);
2072
-				avp_val.s.s = buf;
2073
-				if(add_avp(AVP_VAL_STR | sock_avp_type, sock_avp_name, avp_val)
2074
-						!= 0)
2075
-					return -1;
2076
-			}
2077
-
2078
-			if(alg == DS_ALG_CALLLOAD) {
2079
-				if(idx->dlist[i].attrs.duid.len <= 0) {
2080
-					LM_ERR("no uid for destination: %d %.*s\n", set,
2081
-							idx->dlist[i].uri.len, idx->dlist[i].uri.s);
2082
-					return -1;
2083
-				}
2084
-				avp_val.s = idx->dlist[i].attrs.duid;
2085
-				if(add_avp(AVP_VAL_STR | dstid_avp_type, dstid_avp_name,
2086
-						   avp_val)
2087
-						!= 0)
2088
-					return -1;
2089
-			}
2090
-			cnt++;
2091
-		}
2092
-
2093
-		lhash = hash;
2094
-		/* if addr was not set to dst/uri, add it via last operation */
2095
-		if(mode == 2)
2096
-			lhash--;
2097
-		for(i = idx->nr - 1; i > lhash && cnt < limit; i--) {
2098
-			if(ds_skip_dst(idx->dlist[i].flags)
2099
-					|| (ds_use_default != 0 && i == (idx->nr - 1)))
2100
-				continue;
2101
-			/* max load exceeded per destination */
2102
-			if(alg == DS_ALG_CALLLOAD
2103
-					&& idx->dlist[i].dload >= idx->dlist[i].attrs.maxload)
2104
-				LM_DBG("using entry [%d/%d]\n", set, i);
2105
-			avp_val.s = idx->dlist[i].uri;
2106
-			if(add_avp(AVP_VAL_STR | dst_avp_type, dst_avp_name, avp_val) != 0)
2107
-				return -1;
2108
-
2109
-			if(attrs_avp_name.n != 0 && idx->dlist[i].attrs.body.len > 0) {
2110
-				avp_val.s = idx->dlist[i].attrs.body;
2111
-				if(add_avp(AVP_VAL_STR | attrs_avp_type, attrs_avp_name,
2112
-						   avp_val)
2113
-						!= 0)
2114
-					return -1;
2115
-			}
2116
-
2117
-			if(sock_avp_name.n != 0 && idx->dlist[i].sock) {
2118
-				avp_val.s.len = 1 + sprintf(buf, "%p", idx->dlist[i].sock);
2119
-				avp_val.s.s = buf;
2120
-				if(add_avp(AVP_VAL_STR | sock_avp_type, sock_avp_name, avp_val)
2121
-						!= 0)
2122
-					return -1;
2123
-			}
2086
+	if(ds_xavp_dst.len<=0) {
2087
+		/* no xavp name to store the rest of the records */
2088
+		return 1;
2089
+	}
2124 2090
 
2125
-			if(alg == DS_ALG_CALLLOAD) {
2126
-				if(idx->dlist[i].attrs.duid.len <= 0) {
2127
-					LM_ERR("no uid for destination: %d %.*s\n", set,
2128
-							idx->dlist[i].uri.len, idx->dlist[i].uri.s);
2129
-					return -1;
2130
-				}
2131
-				avp_val.s = idx->dlist[i].attrs.duid;
2132
-				if(add_avp(AVP_VAL_STR | dstid_avp_type, dstid_avp_name,
2133
-						   avp_val)
2134
-						!= 0)
2135
-					return -1;
2136
-			}
2137
-			cnt++;
2091
+	/* add default dst to last position in XAVP list */
2092
+	if(ds_use_default != 0 && hash != idx->nr - 1 && cnt < limit) {
2093
+		if(ds_add_xavp_record(idx, idx->nr - 1, set, alg)<0) {
2094
+			LM_ERR("failed to add default destination in the xavp\n");
2095
+			return -1;
2138 2096
 		}
2097
+		cnt++;
2098
+	}
2139 2099
 
2140
-		/* add to avp the first used dst */
2141
-		avp_val.s = idx->dlist[hash].uri;
2142
-		if(add_avp(AVP_VAL_STR | dst_avp_type, dst_avp_name, avp_val) != 0)
2100
+	/* add to xavp in reverse order - index from hash-1 to 0 */
2101
+	for(i = hash - 1; i >= 0 && cnt < limit; i--) {
2102
+		if(ds_skip_dst(idx->dlist[i].flags)
2103
+				|| (ds_use_default != 0 && i == (idx->nr - 1))) {
2104
+			continue;
2105
+		}
2106
+		/* max load exceeded per destination */
2107
+		if(alg == DS_ALG_CALLLOAD
2108
+				&& idx->dlist[i].dload >= idx->dlist[i].attrs.maxload) {
2109
+			continue;
2110
+		}
2111
+		LM_DBG("using entry [%d/%d]\n", set, i);
2112
+		if(ds_add_xavp_record(idx, i, set, alg)<0) {
2113
+			LM_ERR("failed to add destination in the xavp (%d/%d)\n", i, set);
2143 2114
 			return -1;
2144
-
2145
-		if(attrs_avp_name.n != 0 && idx->dlist[hash].attrs.body.len > 0) {
2146
-			avp_val.s = idx->dlist[hash].attrs.body;
2147
-			if(add_avp(AVP_VAL_STR | attrs_avp_type, attrs_avp_name, avp_val)
2148
-					!= 0)
2149
-				return -1;
2150 2115
 		}
2151
-		if(sock_avp_name.n != 0 && idx->dlist[hash].sock) {
2152
-			avp_val.s.len = 1 + sprintf(buf, "%p", idx->dlist[hash].sock);
2153
-			avp_val.s.s = buf;
2154
-			if(add_avp(AVP_VAL_STR | sock_avp_type, sock_avp_name, avp_val)
2155
-					!= 0)
2156
-				return -1;
2116
+		cnt++;
2117
+	}
2118
+	/* add to xavp in reverse order - index from idx->nr-1 to hash
2119
+	 * top selected destination is at index hash
2120
+	 * -- added last to be first in xavp list */
2121
+	crt_added = 0;
2122
+	for(i = idx->nr - 1; i >= hash && cnt < limit; i--) {
2123
+		if(ds_skip_dst(idx->dlist[i].flags)
2124
+				|| (ds_use_default != 0 && i == (idx->nr - 1))) {
2125
+			continue;
2157 2126
 		}
2158
-
2159
-		if(alg == DS_ALG_CALLLOAD) {
2160
-			if(idx->dlist[hash].attrs.duid.len <= 0) {
2161
-				LM_ERR("no uid for destination: %d %.*s\n", set,
2162
-						idx->dlist[hash].uri.len, idx->dlist[hash].uri.s);
2163
-				return -1;
2164
-			}
2165
-			avp_val.s = idx->dlist[hash].attrs.duid;
2166
-			if(add_avp(AVP_VAL_STR | dstid_avp_type, dstid_avp_name, avp_val)
2167
-					!= 0)
2168
-				return -1;
2127
+		/* max load exceeded per destination - skip */
2128
+		if(alg == DS_ALG_CALLLOAD
2129
+				&& idx->dlist[i].dload >= idx->dlist[i].attrs.maxload) {
2130
+			continue;
2131
+		}
2132
+		LM_DBG("using entry [%d/%d]\n", set, i);
2133
+		if(ds_add_xavp_record(idx, i, set, alg)<0) {
2134
+			LM_ERR("failed to add destination in the xavp (%d/%d)\n", i, set);
2135
+			return -1;
2136
+		}
2137
+		if(i == hash) {
2138
+			crt_added = 1;
2169 2139
 		}
2170 2140
 		cnt++;
2171 2141
 	}
2172 2142
 
2173
-	if(grp_avp_name.n != 0) {
2174
-		/* add to avp the group id */
2175
-		avp_val.n = set;
2176
-		if(add_avp(grp_avp_type, grp_avp_name, avp_val) != 0)
2143
+	if(crt_added==0 && mode!=2) {
2144
+		LM_DBG("using entry [%d/%d]\n", set, hash);
2145
+		if(ds_add_xavp_record(idx, hash, set, alg)<0) {
2146
+			LM_ERR("failed to add destination in the xavp (%d/%d)\n", hash, set);
2177 2147
 			return -1;
2148
+		}
2178 2149
 	}
2179 2150
 
2180
-	if(cnt_avp_name.n != 0) {
2181
-		/* add to avp the number of dst */
2182
-		avp_val.n = cnt;
2183
-		if(add_avp(cnt_avp_type, cnt_avp_name, avp_val) != 0)
2151
+	if(((ds_xavp_ctx_mode & DS_XAVP_CTX_SKIP_CNT)==0)
2152
+			&& (ds_xavp_ctx.len >= 0)) {
2153
+		/* add to xavp the number of selected dst records */
2154
+		memset(&nxval, 0, sizeof(sr_xval_t));
2155
+		nxval.type = SR_XTYPE_INT;
2156
+		nxval.v.i = cnt;
2157
+		if(xavp_add_xavp_value(&ds_xavp_ctx, &ds_xavp_ctx_cnt, &nxval, NULL)==NULL) {
2158
+			LM_ERR("failed to add cnt value to xavp\n");
2184 2159
 			return -1;
2160
+		}
2185 2161
 	}
2186 2162
 
2187 2163
 	return 1;
... ...
@@ -2189,70 +2165,65 @@ int ds_select_dst_limit(
2189 2165
 
2190 2166
 int ds_next_dst(struct sip_msg *msg, int mode)
2191 2167
 {
2192
-	struct search_state st;
2193
-	struct usr_avp *avp;
2194
-	struct usr_avp *prev_avp;
2195
-	struct socket_info *sock = NULL;
2196
-	int_str avp_value;
2197
-	int_str sock_avp_value;
2168
+
2169
+	socket_info_t *sock = NULL;
2170
+	sr_xavp_t *rxavp = NULL;
2171
+	sr_xavp_t *lxavp = NULL;
2198 2172
 	int alg = 0;
2199 2173
 
2200
-	if(!(ds_flags & DS_FAILOVER_ON) || dst_avp_name.n == 0) {
2174
+	if(!(ds_flags & DS_FAILOVER_ON) || ds_xavp_dst.len <= 0) {
2201 2175
 		LM_WARN("failover support disabled\n");
2202 2176
 		return -1;
2203 2177
 	}
2204 2178
 
2205
-	if(dstid_avp_name.n != 0) {
2206
-		prev_avp = search_first_avp(
2207
-				dstid_avp_type, dstid_avp_name, &avp_value, &st);
2208
-		if(prev_avp != NULL) {
2209
-			/* load based dispatching */
2210
-			alg = DS_ALG_CALLLOAD;
2211
-			/* off-load destination id */
2212
-			destroy_avp(prev_avp);
2213
-		}
2179
+	rxavp = xavp_get(&ds_xavp_dst, NULL);
2180
+	if(rxavp == NULL) {
2181
+		LM_DBG("no xavp with previous destination record\n");
2182
+		return -1;
2214 2183
 	}
2215 2184
 
2216
-	if(attrs_avp_name.n != 0) {
2217
-		prev_avp = search_first_avp(
2218
-				attrs_avp_type, attrs_avp_name, &avp_value, &st);
2219
-		if(prev_avp != NULL) {
2220
-			destroy_avp(prev_avp);
2221
-		}
2185
+	lxavp = xavp_get(&ds_xavp_dst_dstid, rxavp);
2186
+	if(lxavp!=NULL) {
2187
+		LM_DBG("call load distribution algorithm was used\n");
2188
+		alg = DS_ALG_CALLLOAD;
2222 2189
 	}
2223 2190
 
2224
-	if(sock_avp_name.n != 0) {
2225
-		prev_avp = search_first_avp(
2226
-				sock_avp_type, sock_avp_name, &sock_avp_value, &st);
2227
-		if(prev_avp != NULL) {
2228
-			if(sscanf(sock_avp_value.s.s, "%p", (void **)&sock) != 1)
2229
-				sock = NULL;
2230
-			destroy_avp(prev_avp);
2231
-		}
2191
+	xavp_rm(rxavp, NULL);
2192
+
2193
+	rxavp = xavp_get(&ds_xavp_dst, NULL);
2194
+	if(rxavp == NULL) {
2195
+		LM_DBG("no xavp with next destination record\n");
2196
+		return -1;
2232 2197
 	}
2233 2198
 
2234
-	prev_avp = search_first_avp(dst_avp_type, dst_avp_name, &avp_value, &st);
2235
-	if(prev_avp == NULL)
2236
-		return -1; /* used avp deleted -- strange */
2199
+	lxavp = xavp_get(&ds_xavp_dst_sock, rxavp);
2200
+	if(lxavp!=NULL && lxavp->val.type==SR_XTYPE_STR) {
2201
+		LM_DBG("socket enforced in next destination record\n");
2202
+		if(sscanf(lxavp->val.v.s.s, "%p", (void **)&sock) != 1) {
2203
+			sock = NULL;
2204
+		}
2205
+	}
2237 2206
 
2238
-	avp = search_next_avp(&st, &avp_value);
2239
-	destroy_avp(prev_avp);
2240
-	if(avp == NULL || !(avp->flags & AVP_VAL_STR))
2241
-		return -1; /* no more avps or value is int */
2207
+	lxavp = xavp_get(&ds_xavp_dst_addr, rxavp);
2208
+	if(lxavp==NULL || lxavp->val.type!=SR_XTYPE_STR) {
2209
+		LM_WARN("no xavp uri field in next destination record\n");
2210
+		return -1;
2211
+	}
2242 2212
 
2243
-	if(ds_update_dst(msg, &avp_value.s, sock, mode) != 0) {
2244
-		LM_ERR("cannot set dst addr\n");
2213
+	if(ds_update_dst(msg, &lxavp->val.v.s, sock, mode) != 0) {
2214
+		LM_ERR("cannot set dst addr: %.*s\n", lxavp->val.v.s.len,
2215
+				lxavp->val.v.s.s);
2245 2216
 		return -1;
2246 2217
 	}
2247
-	LM_DBG("using [%.*s]\n", avp_value.s.len, avp_value.s.s);
2218
+	LM_DBG("using next dst uri [%.*s]\n", lxavp->val.v.s.len,
2219
+				lxavp->val.v.s.s);
2248 2220
 	if(alg == DS_ALG_CALLLOAD) {
2249
-		prev_avp = search_first_avp(
2250
-				dstid_avp_type, dstid_avp_name, &avp_value, &st);
2251
-		if(prev_avp == NULL) {
2252
-			LM_ERR("cannot find uid avp for destination address\n");
2221
+		lxavp = xavp_get(&ds_xavp_dst_dstid, rxavp);
2222
+		if(lxavp!=NULL || lxavp->val.type!=SR_XTYPE_STR) {
2223
+			LM_ERR("cannot find uid xavp for current destination address\n");
2253 2224
 			return -1;
2254 2225
 		}
2255
-		if(ds_load_replace(msg, &avp_value.s) < 0) {
2226
+		if(ds_load_replace(msg, &lxavp->val.v.s) < 0) {
2256 2227
 			LM_ERR("cannot update load distribution\n");
2257 2228
 			return -1;
2258 2229
 		}
... ...
@@ -2263,30 +2234,34 @@ int ds_next_dst(struct sip_msg *msg, int mode)
2263 2234
 
2264 2235
 int ds_mark_dst(struct sip_msg *msg, int state)
2265 2236
 {
2266
-	int group, ret;
2267
-	struct usr_avp *prev_avp;
2268
-	int_str avp_value;
2237
+	sr_xavp_t *rxavp = NULL;
2238
+	int group;
2239
+	int ret;
2269 2240
 
2270 2241
 	if(!(ds_flags & DS_FAILOVER_ON)) {
2271 2242
 		LM_WARN("failover support disabled\n");
2272 2243
 		return -1;
2273 2244
 	}
2274 2245
 
2275
-	prev_avp = search_first_avp(grp_avp_type, grp_avp_name, &avp_value, 0);
2246
+	if(ds_xavp_dst.len<=0) {
2247
+		LM_WARN("no xavp name to store dst records\n");
2248
+		return -1;
2249
+	}
2250
+	rxavp = xavp_get_child_with_ival(&ds_xavp_dst, &ds_xavp_dst_grp);
2276 2251
 
2277
-	if(prev_avp == NULL || prev_avp->flags & AVP_VAL_STR)
2278
-		return -1; /* grp avp deleted -- strange */
2279
-	group = avp_value.n;
2252
+	if(rxavp == NULL)
2253
+		return -1; /* grp xavp not available */
2254
+	group = rxavp->val.v.i;
2280 2255
 
2281
-	prev_avp = search_first_avp(dst_avp_type, dst_avp_name, &avp_value, 0);
2256
+	rxavp = xavp_get_child_with_sval(&ds_xavp_dst, &ds_xavp_dst_addr);
2282 2257
 
2283
-	if(prev_avp == NULL || !(prev_avp->flags & AVP_VAL_STR))
2284
-		return -1; /* dst avp deleted -- strange */
2258
+	if(rxavp == NULL )
2259
+		return -1; /* dst addr uri not available */
2285 2260
 
2286
-	ret = ds_update_state(msg, group, &avp_value.s, state);
2261
+	ret = ds_update_state(msg, group, &rxavp->val.v.s, state);
2287 2262
 
2288
-	LM_DBG("state [%d] grp [%d] dst [%.*s]\n", state, group, avp_value.s.len,
2289
-			avp_value.s.s);
2263
+	LM_DBG("state [%d] grp [%d] dst [%.*s]\n", state, group, rxavp->val.v.s.len,
2264
+			rxavp->val.v.s.s);
2290 2265
 
2291 2266
 	return (ret == 0) ? 1 : -1;
2292 2267
 }
... ...
@@ -55,6 +55,10 @@
55 55
 #define DS_MATCH_ALL		0
56 56
 #define DS_MATCH_NOPORT		1
57 57
 #define DS_MATCH_NOPROTO	2
58
+
59
+#define DS_XAVP_DST_SKIP_ATTRS	1
60
+#define DS_XAVP_CTX_SKIP_CNT	1
61
+
58 62
 /* clang-format on */
59 63
 
60 64
 extern str ds_db_url;
... ...
@@ -68,18 +72,18 @@ extern str ds_dest_attrs_col;
68 72
 extern int ds_flags;
69 73
 extern int ds_use_default;
70 74
 
71
-extern int_str dst_avp_name;
72
-extern unsigned short dst_avp_type;
73
-extern int_str grp_avp_name;
74
-extern unsigned short grp_avp_type;
75
-extern int_str cnt_avp_name;
76
-extern unsigned short cnt_avp_type;
77
-extern int_str dstid_avp_name;
78
-extern unsigned short dstid_avp_type;
79
-extern int_str attrs_avp_name;
80
-extern unsigned short attrs_avp_type;
81
-extern int_str sock_avp_name;
82
-extern unsigned short sock_avp_type;
75
+extern str ds_xavp_dst;
76
+extern int ds_xavp_dst_mode;
77
+extern str ds_xavp_ctx;
78
+extern int ds_xavp_ctx_mode;
79
+
80
+extern str ds_xavp_dst_addr;
81
+extern str ds_xavp_dst_grp;
82
+extern str ds_xavp_dst_dstid;
83
+extern str ds_xavp_dst_attrs;
84
+extern str ds_xavp_dst_sock;
85
+
86
+extern str ds_xavp_ctx_cnt;
83 87
 
84 88
 extern pv_elem_t *hash_param_model;
85 89
 
... ...
@@ -73,26 +73,21 @@ char *dslistfile = CFG_DIR"dispatcher.list";
73 73
 int  ds_force_dst   = 1;
74 74
 int  ds_flags       = 0;
75 75
 int  ds_use_default = 0;
76
-static str dst_avp_param = STR_NULL;
77
-static str grp_avp_param = STR_NULL;
78
-static str cnt_avp_param = STR_NULL;
79
-static str dstid_avp_param = STR_NULL;
80
-static str attrs_avp_param = STR_NULL;
81
-static str sock_avp_param = STR_NULL;
76
+str ds_xavp_dst = str_init("_dsdst_");
77
+int ds_xavp_dst_mode = 0;
78
+str ds_xavp_ctx = str_init("_dsctx_");
79
+int ds_xavp_ctx_mode = 0;
80
+
82 81
 str hash_pvar_param = STR_NULL;
83 82
 
84
-int_str dst_avp_name;
85
-unsigned short dst_avp_type;
86
-int_str grp_avp_name;
87
-unsigned short grp_avp_type;
88
-int_str cnt_avp_name;
89
-unsigned short cnt_avp_type;
90
-int_str dstid_avp_name;
91
-unsigned short dstid_avp_type;
92
-int_str attrs_avp_name;
93
-unsigned short attrs_avp_type;
94
-int_str sock_avp_name;
95
-unsigned short sock_avp_type;
83
+str ds_xavp_dst_addr = str_init("uri");
84
+str ds_xavp_dst_grp = str_init("grp");
85
+str ds_xavp_dst_dstid = str_init("dstid");
86
+str ds_xavp_dst_attrs = str_init("attrs");
87
+str ds_xavp_dst_sock = str_init("sock");
88
+
89
+str ds_xavp_ctx_cnt = str_init("cnt");
90
+
96 91
 
97 92
 pv_elem_t * hash_param_model = NULL;
98 93
 
... ...
@@ -234,12 +229,10 @@ static param_export_t params[]={
234 229
 	{"force_dst",       INT_PARAM, &ds_force_dst},
235 230
 	{"flags",           INT_PARAM, &ds_flags},
236 231
 	{"use_default",     INT_PARAM, &ds_use_default},
237
-	{"dst_avp",         PARAM_STR, &dst_avp_param},
238
-	{"grp_avp",         PARAM_STR, &grp_avp_param},
239
-	{"cnt_avp",         PARAM_STR, &cnt_avp_param},
240
-	{"dstid_avp",       PARAM_STR, &dstid_avp_param},
241
-	{"attrs_avp",       PARAM_STR, &attrs_avp_param},
242
-	{"sock_avp",        PARAM_STR, &sock_avp_param},
232
+	{"xavp_dst",        PARAM_STR, &ds_xavp_dst},
233
+	{"xavp_dst_mode",   PARAM_INT, &ds_xavp_dst_mode},
234
+	{"xavp_ctx",        PARAM_STR, &ds_xavp_ctx},
235
+	{"xavp_ctx_mode",   PARAM_INT, &ds_xavp_ctx_mode},
243 236
 	{"hash_pvar",       PARAM_STR, &hash_pvar_param},
244 237
 	{"setid_pvname",    PARAM_STR, &ds_setid_pvname},
245 238
 	{"attrs_pvname",    PARAM_STR, &ds_attrs_pvname},
... ...
@@ -287,7 +280,6 @@ struct module_exports exports= {
287 280
  */
288 281
 static int mod_init(void)
289 282
 {
290
-	pv_spec_t avp_spec;
291 283
 	str host;
292 284
 	int port, proto;
293 285
 
... ...
@@ -359,117 +351,6 @@ static int mod_init(void)
359 351
 		}
360 352
 	}
361 353
 
362
-	if(dst_avp_param.s && dst_avp_param.len > 0) {
363
-		if(pv_parse_spec(&dst_avp_param, &avp_spec) == 0
364
-				|| avp_spec.type != PVT_AVP) {
365
-			LM_ERR("malformed or non AVP %.*s AVP definition\n",
366
-					dst_avp_param.len, dst_avp_param.s);
367
-			return -1;
368
-		}
369
-
370
-		if(pv_get_avp_name(0, &(avp_spec.pvp), &dst_avp_name, &dst_avp_type)
371
-				!= 0) {
372
-			LM_ERR("[%.*s]- invalid AVP definition\n", dst_avp_param.len,
373
-					dst_avp_param.s);
374
-			return -1;
375
-		}
376
-	} else {
377
-		dst_avp_name.n = 0;
378
-		dst_avp_type = 0;
379
-	}
380
-	if(grp_avp_param.s && grp_avp_param.len > 0) {
381
-		if(pv_parse_spec(&grp_avp_param, &avp_spec) == 0
382
-				|| avp_spec.type != PVT_AVP) {
383
-			LM_ERR("malformed or non AVP %.*s AVP definition\n",
384
-					grp_avp_param.len, grp_avp_param.s);
385
-			return -1;
386
-		}
387
-
388
-		if(pv_get_avp_name(0, &(avp_spec.pvp), &grp_avp_name, &grp_avp_type)
389
-				!= 0) {
390
-			LM_ERR("[%.*s]- invalid AVP definition\n", grp_avp_param.len,
391
-					grp_avp_param.s);
392
-			return -1;
393
-		}
394
-	} else {
395
-		grp_avp_name.n = 0;
396
-		grp_avp_type = 0;
397
-	}
398
-	if(cnt_avp_param.s && cnt_avp_param.len > 0) {
399
-		if(pv_parse_spec(&cnt_avp_param, &avp_spec) == 0
400
-				|| avp_spec.type != PVT_AVP) {
401
-			LM_ERR("malformed or non AVP %.*s AVP definition\n",
402
-					cnt_avp_param.len, cnt_avp_param.s);
403
-			return -1;
404
-		}
405
-
406
-		if(pv_get_avp_name(0, &(avp_spec.pvp), &cnt_avp_name, &cnt_avp_type)
407
-				!= 0) {
408
-			LM_ERR("[%.*s]- invalid AVP definition\n", cnt_avp_param.len,
409
-					cnt_avp_param.s);
410
-			return -1;
411
-		}
412
-	} else {
413
-		cnt_avp_name.n = 0;
414
-		cnt_avp_type = 0;
415
-	}
416
-	if(dstid_avp_param.s && dstid_avp_param.len > 0) {
417
-		if(pv_parse_spec(&dstid_avp_param, &avp_spec) == 0
418
-				|| avp_spec.type != PVT_AVP) {
419
-			LM_ERR("malformed or non AVP %.*s AVP definition\n",
420
-					dstid_avp_param.len, dstid_avp_param.s);
421
-			return -1;
422
-		}
423
-
424
-		if(pv_get_avp_name(0, &(avp_spec.pvp), &dstid_avp_name, &dstid_avp_type)
425
-				!= 0) {
426
-			LM_ERR("[%.*s]- invalid AVP definition\n", dstid_avp_param.len,
427
-					dstid_avp_param.s);
428
-			return -1;
429
-		}
430
-	} else {
431
-		dstid_avp_name.n = 0;
432
-		dstid_avp_type = 0;
433
-	}
434
-
435
-	if(attrs_avp_param.s && attrs_avp_param.len > 0) {
436
-		if(pv_parse_spec(&attrs_avp_param, &avp_spec) == 0
437
-				|| avp_spec.type != PVT_AVP) {
438
-			LM_ERR("malformed or non AVP %.*s AVP definition\n",
439
-					attrs_avp_param.len, attrs_avp_param.s);
440
-			return -1;
441
-		}
442
-
443
-		if(pv_get_avp_name(0, &(avp_spec.pvp), &attrs_avp_name, &attrs_avp_type)
444
-				!= 0) {
445
-			LM_ERR("[%.*s]- invalid AVP definition\n", attrs_avp_param.len,
446
-					attrs_avp_param.s);
447
-			return -1;
448
-		}
449
-	} else {
450
-		attrs_avp_name.n = 0;
451
-		attrs_avp_type = 0;
452
-	}
453
-
454
-	if(sock_avp_param.s && sock_avp_param.len > 0) {
455
-		if(pv_parse_spec(&sock_avp_param, &avp_spec) == 0
456
-				|| avp_spec.type != PVT_AVP) {
457
-			LM_ERR("malformed or non AVP %.*s AVP definition\n",
458
-					sock_avp_param.len, sock_avp_param.s);
459
-			return -1;
460
-		}
461
-
462
-		if(pv_get_avp_name(0, &(avp_spec.pvp), &sock_avp_name, &sock_avp_type)
463
-				!= 0) {
464
-			LM_ERR("[%.*s]- invalid AVP definition\n", sock_avp_param.len,
465
-					sock_avp_param.s);
466
-			return -1;
467
-		}
468
-	} else {
469
-		sock_avp_name.n = 0;
470
-		sock_avp_type = 0;
471
-	}
472
-
473 354
 	if(hash_pvar_param.s && *hash_pvar_param.s) {
474 355
 		if(pv_parse_format(&hash_pvar_param, &hash_param_model) < 0
475 356
 				|| hash_param_model == NULL) {
... ...
@@ -496,26 +377,21 @@ static int mod_init(void)
496 377
 		}
497 378
 	}
498 379
 
499
-	if(dstid_avp_param.s && dstid_avp_param.len > 0) {
500
-		if(ds_hash_size > 0) {
501
-			if(ds_hash_load_init(
502
-					   1 << ds_hash_size, ds_hash_expire, ds_hash_initexpire)
503
-					< 0)
380
+	if(ds_hash_size > 0) {
381
+		if(ds_hash_load_init(
382
+					1 << ds_hash_size, ds_hash_expire, ds_hash_initexpire)
383
+				< 0)
384
+			return -1;
385
+		if(ds_timer_mode == 1) {
386
+			if(sr_wtimer_add(ds_ht_timer, NULL, ds_hash_check_interval) < 0)
504 387
 				return -1;
505
-			if(ds_timer_mode == 1) {
506
-				if(sr_wtimer_add(ds_ht_timer, NULL, ds_hash_check_interval) < 0)
507
-					return -1;
508
-			} else {
509
-				if(register_timer(ds_ht_timer, NULL, ds_hash_check_interval)
510
-						< 0)
511
-					return -1;
512
-			}
513 388
 		} else {
514
-			LM_ERR("call load dispatching DSTID_AVP set but no size"
515
-				   " for hash table (see ds_hash_size parameter)\n");
516
-			return -1;
389
+			if(register_timer(ds_ht_timer, NULL, ds_hash_check_interval)
390
+					< 0)
391
+				return -1;
517 392
 		}
518 393
 	}
394
+
519 395
 	/* Only, if the Probing-Timer is enabled the TM-API needs to be loaded: */
520 396
 	if(ds_ping_interval > 0) {
521 397
 		/*****************************************************
... ...
@@ -812,9 +688,8 @@ static int w_ds_load_update(struct sip_msg *msg, char *str1, char *str2)
812 688
  */
813 689
 static int ds_warn_fixup(void **param, int param_no)
814 690
 {
815
-	if(!dst_avp_param.s || !grp_avp_param.s || !cnt_avp_param.s
816
-			|| !sock_avp_param.s) {
817
-		LM_ERR("failover functions used, but required AVP parameters"
691
+	if(ds_xavp_dst.len<=0 || ds_xavp_ctx.len<=0) {
692
+		LM_ERR("failover functions used, but required XAVP parameters"
818 693
 			   " are NULL -- feature disabled\n");
819 694
 	}
820 695
 	return 0;