Browse code

dispatcher: support for per destination address socket name attribute

- attribute name is: sockname
- if set to a socket name, enforce the send socket per destination
address

Daniel-Constantin Mierla authored on 05/04/2020 12:35:40
Showing 3 changed files
... ...
@@ -177,7 +177,8 @@ int ds_hash_load_destroy(void)
177 177
 /**
178 178
  * Recursivly iterate over ds_set and execute callback
179 179
  */
180
-void ds_iter_set(ds_set_t *node, void (*ds_action_cb)(ds_set_t *node, int i, void *arg), void *ds_action_arg)
180
+void ds_iter_set(ds_set_t *node, void (*ds_action_cb)(ds_set_t *node, int i, void *arg),
181
+		void *ds_action_arg)
181 182
 {
182 183
 	if(!node)
183 184
 		return;
... ...
@@ -308,6 +309,9 @@ int ds_set_attrs(ds_dest_t *dest, str *vattrs)
308 309
 		} else if(pit->name.len == 6
309 310
 				  && strncasecmp(pit->name.s, "socket", 6) == 0) {
310 311
 			dest->attrs.socket = pit->body;
312
+		} else if(pit->name.len == 8
313
+				  && strncasecmp(pit->name.s, "sockname", 8) == 0) {
314
+			dest->attrs.sockname = pit->body;
311 315
 		} else if(pit->name.len == 7
312 316
 				  && strncasecmp(pit->name.s, "rweight", 7) == 0) {
313 317
 			tmp_rweight = 0;
... ...
@@ -402,8 +406,15 @@ ds_dest_t *pack_dest(str iuri, int flags, int priority, str *attrs)
402 406
 		goto err;
403 407
 	}
404 408
 
405
-	/* check socket attribute */
406
-	if(dp->attrs.socket.s && dp->attrs.socket.len > 0) {
409
+	/* set send socket by name or address */
410
+	if(dp->attrs.sockname.s && dp->attrs.sockname.len > 0) {
411
+		dp->sock = ksr_get_socket_by_name(&dp->attrs.sockname);
412
+		if(dp->sock == 0) {
413
+			LM_ERR("non-local socket name <%.*s>\n", dp->attrs.sockname.len,
414
+					dp->attrs.sockname.s);
415
+			goto err;
416
+		}
417
+	} else if(dp->attrs.socket.s && dp->attrs.socket.len > 0) {
407 418
 		/* parse_phostport(...) expects 0-terminated string
408 419
 		 * - after socket parameter is either ';' or '\0' */
409 420
 		if(dp->attrs.socket.s[dp->attrs.socket.len] != '\0') {
... ...
@@ -1746,8 +1757,8 @@ int ds_load_unset(struct sip_msg *msg)
1746 1757
 /**
1747 1758
  *
1748 1759
  */
1749
-static inline int ds_push_dst(
1750
-		struct sip_msg *msg, str *uri, struct socket_info *sock, int mode)
1760
+static inline int ds_push_dst(sip_msg_t *msg, str *uri, socket_info_t *sock,
1761
+		int mode)
1751 1762
 {
1752 1763
 	struct action act;
1753 1764
 	struct run_act_ctx ra_ctx;
... ...
@@ -1933,7 +1944,18 @@ int ds_add_xavp_record(ds_set_t *dsidx, int pos, int set, int alg,
1933 1944
 			nxval.v.s = dsidx->dlist[pos].attrs.socket;
1934 1945
 			if(xavp_add_value(&ds_xavp_dst_socket, &nxval, &nxavp)==NULL) {
1935 1946
 				xavp_destroy_list(&nxavp);
1936
-				LM_ERR("failed to add destination attrs xavp field\n");
1947
+				LM_ERR("failed to add socket address attrs xavp field\n");
1948
+				return -1;
1949
+			}
1950
+		}
1951
+		if((ds_xavp_dst_mode & DS_XAVP_DST_ADD_SOCKNAME)
1952
+				&& (dsidx->dlist[pos].attrs.sockname.len > 0)) {
1953
+			memset(&nxval, 0, sizeof(sr_xval_t));
1954
+			nxval.type = SR_XTYPE_STR;
1955
+			nxval.v.s = dsidx->dlist[pos].attrs.sockname;
1956
+			if(xavp_add_value(&ds_xavp_dst_sockname, &nxval, &nxavp)==NULL) {
1957
+				xavp_destroy_list(&nxavp);
1958
+				LM_ERR("failed to add socket name attrs xavp field\n");
1937 1959
 				return -1;
1938 1960
 			}
1939 1961
 		}
... ...
@@ -3295,9 +3317,15 @@ void ds_ping_set(ds_set_t *node)
3295 3317
 			 *		transaction_cb cb, void* cbp); */
3296 3318
 			set_uac_req(&uac_r, &ds_ping_method, 0, 0, 0, TMCB_LOCAL_COMPLETED,
3297 3319
 					ds_options_callback, (void *)(long)node->id);
3298
-			if(node->dlist[j].attrs.socket.s != NULL
3320
+			if(node->dlist[j].attrs.sockname.s != NULL
3321
+					&& node->dlist[j].attrs.sockname.len > 0) {
3322
+				uac_r.ssockname = &node->dlist[j].attrs.sockname;
3323
+			} else if(node->dlist[j].attrs.socket.s != NULL
3299 3324
 					&& node->dlist[j].attrs.socket.len > 0) {
3300 3325
 				uac_r.ssock = &node->dlist[j].attrs.socket;
3326
+			} else if(ds_default_sockname.s != NULL
3327
+					  && ds_default_sockname.len > 0) {
3328
+				uac_r.ssockname = &ds_default_sockname;
3301 3329
 			} else if(ds_default_socket.s != NULL
3302 3330
 					  && ds_default_socket.len > 0) {
3303 3331
 				uac_r.ssock = &ds_default_socket;
... ...
@@ -68,6 +68,7 @@
68 68
 
69 69
 #define DS_XAVP_DST_SKIP_ATTRS	1
70 70
 #define DS_XAVP_DST_ADD_SOCKSTR	(1<<1)
71
+#define DS_XAVP_DST_ADD_SOCKNAME	(1<<2)
71 72
 
72 73
 #define DS_XAVP_CTX_SKIP_CNT	1
73 74
 
... ...
@@ -102,6 +103,7 @@ extern str ds_xavp_dst_dstid;
102 103
 extern str ds_xavp_dst_attrs;
103 104
 extern str ds_xavp_dst_sock;
104 105
 extern str ds_xavp_dst_socket;
106
+extern str ds_xavp_dst_sockname;
105 107
 
106 108
 extern str ds_xavp_ctx_cnt;
107 109
 
... ...
@@ -123,6 +125,7 @@ extern int inactive_threshold; /*!< number of successful requests,
123 125
 extern int ds_probing_mode;
124 126
 extern str ds_outbound_proxy;
125 127
 extern str ds_default_socket;
128
+extern str ds_default_sockname;
126 129
 extern struct socket_info *ds_default_sockinfo;
127 130
 
128 131
 int ds_init_data(void);
... ...
@@ -179,6 +182,7 @@ typedef struct _ds_attrs {
179 182
 	str body;
180 183
 	str duid;
181 184
 	str socket;
185
+	str sockname;
182 186
 	int maxload;
183 187
 	int weight;
184 188
 	int rweight;
... ...
@@ -86,6 +86,7 @@ str ds_xavp_dst_dstid = str_init("dstid");
86 86
 str ds_xavp_dst_attrs = str_init("attrs");
87 87
 str ds_xavp_dst_sock = str_init("sock");
88 88
 str ds_xavp_dst_socket = str_init("socket");
89
+str ds_xavp_dst_sockname = str_init("sockname");
89 90
 
90 91
 str ds_xavp_ctx_cnt = str_init("cnt");
91 92