Browse code

dispatcher: new variant - ds_is_from_list(groupid, uri, mode)

- can match against records in dispatcher groups
- if groupid==1 - will match against all groups
- if uri is empty, then will match against source address (ip, port,
proto). Otherwise it has to be a full SIP URI value. The matching
is not taking in consideration any parameter apart of transport
- mode is a bitmask to tell the matching rules
- if it is 0, will match everything: ip, port and protocol
- if bit one is set, will skip matching the port
- if bit two is set, will skip matching the protocol

Daniel-Constantin Mierla authored on 05/09/2014 15:21:40
Showing 3 changed files
... ...
@@ -332,8 +332,10 @@ int add_dest2list(int id, str uri, int flags, int priority, str *attrs,
332 332
 	/* Free the hostname */
333 333
 	hostent2ip_addr(&dp->ip_address, he, 0);
334 334
 
335
-	/* Copy the Port out of the URI: */
335
+	/* Copy the port out of the URI */
336 336
 	dp->port = puri.port_no;		
337
+	/* Copy the proto out of the URI */
338
+	dp->proto = puri.proto;
337 339
 
338 340
 	if(sp->dlist==NULL)
339 341
 	{
... ...
@@ -2245,15 +2247,45 @@ int ds_print_list(FILE *fout)
2245 2247
 /* Checks, if the request (sip_msg *_m) comes from a host in a group
2246 2248
  * (group-id or -1 for all groups)
2247 2249
  */
2248
-int ds_is_from_list(struct sip_msg *_m, int group)
2250
+int ds_is_addr_from_list(sip_msg_t *_m, int group, str *uri, int mode)
2249 2251
 {
2250 2252
 	pv_value_t val;
2251 2253
 	ds_set_t *list;
2252 2254
 	int j;
2255
+	struct ip_addr* pipaddr;
2256
+	struct ip_addr  aipaddr;
2257
+	unsigned short tport;
2258
+	unsigned short tproto;
2259
+	sip_uri_t puri;
2260
+	static char hn[256];
2261
+	struct hostent* he;
2253 2262
 
2254 2263
 	memset(&val, 0, sizeof(pv_value_t));
2255 2264
 	val.flags = PV_VAL_INT|PV_TYPE_INT;
2256 2265
 
2266
+	if(uri==NULL || uri->len<=0) {
2267
+		pipaddr = &_m->rcv.src_ip;
2268
+		tport = _m->rcv.src_port;
2269
+		tproto = _m->rcv.proto;
2270
+	} else {
2271
+		if(parse_uri(uri->s, uri->len, &puri)!=0 || puri.host.len>255) {
2272
+			LM_ERR("bad uri [%.*s]\n", uri->len, uri->s);
2273
+			return -1;
2274
+		}
2275
+		strncpy(hn, puri.host.s, puri.host.len);
2276
+		hn[puri.host.len]='\0';
2277
+
2278
+		he=resolvehost(hn);
2279
+		if (he==0) {
2280
+			LM_ERR("could not resolve %.*s\n", puri.host.len, puri.host.s);
2281
+			return -1;
2282
+		}
2283
+		hostent2ip_addr(&aipaddr, he, 0);
2284
+		pipaddr = &aipaddr;
2285
+		tport = puri.port_no;
2286
+		tproto = puri.proto;
2287
+	}
2288
+
2257 2289
 	for(list = _ds_list; list!= NULL; list= list->next)
2258 2290
 	{
2259 2291
 		// LM_ERR("list id: %d (n: %d)\n", list->id, list->nr);
... ...
@@ -2262,9 +2294,11 @@ int ds_is_from_list(struct sip_msg *_m, int group)
2262 2294
 			for(j=0; j<list->nr; j++)
2263 2295
 			{
2264 2296
 				// LM_ERR("port no: %d (%d)\n", list->dlist[j].port, j);
2265
-				if (ip_addr_cmp(&_m->rcv.src_ip, &list->dlist[j].ip_address)
2266
-						&& (list->dlist[j].port==0
2267
-							|| _m->rcv.src_port == list->dlist[j].port))
2297
+				if (ip_addr_cmp(pipaddr, &list->dlist[j].ip_address)
2298
+						&& ((mode&DS_MATCH_NOPORT) || list->dlist[j].port==0
2299
+							|| tport == list->dlist[j].port)
2300
+						&& ((mode&DS_MATCH_NOPROTO)
2301
+							|| tproto == list->dlist[j].proto))
2268 2302
 				{
2269 2303
 					if(group==-1 && ds_setid_pvname.s!=0)
2270 2304
 					{
... ...
@@ -2296,6 +2330,10 @@ int ds_is_from_list(struct sip_msg *_m, int group)
2296 2330
 	return -1;
2297 2331
 }
2298 2332
 
2333
+int ds_is_from_list(struct sip_msg *_m, int group)
2334
+{
2335
+	return ds_is_addr_from_list(_m, group, NULL, DS_MATCH_NOPROTO);
2336
+}
2299 2337
 
2300 2338
 int ds_print_mi_list(struct mi_node* rpl)
2301 2339
 {
... ...
@@ -61,6 +61,10 @@
61 61
 #define DS_PROBE_ALL		1
62 62
 #define DS_PROBE_INACTIVE	2
63 63
 
64
+#define DS_MATCH_ALL		0
65
+#define DS_MATCH_NOPORT		1
66
+#define DS_MATCH_NOPROTO	2
67
+
64 68
 extern str ds_db_url;
65 69
 extern str ds_table_name;
66 70
 extern str ds_set_id_col;
... ...
@@ -124,6 +128,8 @@ int ds_hash_load_init(unsigned int htsize, int expire, int initexpire);
124 128
 int ds_hash_load_destroy(void);
125 129
 
126 130
 int ds_is_from_list(struct sip_msg *_m, int group);
131
+int ds_is_addr_from_list(sip_msg_t *_m, int group, str *uri, int mode);
132
+
127 133
 /*! \brief
128 134
  * Timer for checking inactive destinations
129 135
  */
... ...
@@ -156,7 +162,8 @@ typedef struct _ds_dest
156 162
 	int dload;
157 163
 	ds_attrs_t attrs;
158 164
 	struct ip_addr ip_address; 	/*!< IP-Address of the entry */
159
-	unsigned short int port; 	/*!< Port of the request URI */
165
+	unsigned short int port; 	/*!< Port of the URI */
166
+	unsigned short int proto; 	/*!< Protocol of the URI */
160 167
 	int failure_count;
161 168
 	struct _ds_dest *next;
162 169
 } ds_dest_t;
... ...
@@ -159,6 +159,8 @@ static int w_ds_load_update(struct sip_msg*, char*, char*);
159 159
 
160 160
 static int w_ds_is_from_list0(struct sip_msg*, char*, char*);
161 161
 static int w_ds_is_from_list1(struct sip_msg*, char*, char*);
162
+static int w_ds_is_from_list3(struct sip_msg*, char*, char*, char*);
163
+static int fixup_ds_is_from_list3(void** param, int param_no);
162 164
 
163 165
 static void destroy(void);
164 166
 
... ...
@@ -190,6 +192,8 @@ static cmd_export_t cmds[]={
190 192
 		0, 0, REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE},
191 193
 	{"ds_is_from_list",  (cmd_function)w_ds_is_from_list1, 1,
192 194
 		fixup_igp_null, 0, ANY_ROUTE},
195
+	{"ds_is_from_list",  (cmd_function)w_ds_is_from_list3, 3,
196
+		fixup_ds_is_from_list3, 0, ANY_ROUTE},
193 197
 	{"ds_load_unset",    (cmd_function)w_ds_load_unset,   0,
194 198
 		0, 0, ANY_ROUTE},
195 199
 	{"ds_load_update",   (cmd_function)w_ds_load_update,  0,
... ...
@@ -840,6 +844,40 @@ static int w_ds_is_from_list1(struct sip_msg *msg, char *set, char *str2)
840 844
 	return ds_is_from_list(msg, s);
841 845
 }
842 846
 
847
+static int w_ds_is_from_list3(struct sip_msg *msg, char *set, char *uri, char *mode)
848
+{
849
+	int vset;
850
+	int vmode;
851
+	str suri;
852
+
853
+	if(fixup_get_ivalue(msg, (gparam_t*)set, &vset)!=0)
854
+	{
855
+		LM_ERR("cannot get set id value\n");
856
+		return -1;
857
+	}
858
+	if(fixup_get_svalue(msg, (gparam_t*)uri, &suri)!=0)
859
+	{
860
+		LM_ERR("cannot get uri value\n");
861
+		return -1;
862
+	}
863
+	if(fixup_get_ivalue(msg, (gparam_t*)mode, &vmode)!=0)
864
+	{
865
+		LM_ERR("cannot get mode value\n");
866
+		return -1;
867
+	}
868
+
869
+	return ds_is_addr_from_list(msg, vset, &suri, vmode);
870
+}
871
+
872
+static int fixup_ds_is_from_list3(void** param, int param_no)
873
+{
874
+	if(param_no==1 || param_no==3)
875
+		return fixup_igp_null(param, 1);
876
+	if(param_no==2)
877
+		return fixup_spve_null(param, 1);
878
+	return 0;
879
+}
880
+
843 881
 static int ds_parse_reply_codes() {
844 882
 	param_t* params_list = NULL;
845 883
 	param_t *pit=NULL;