[sr-dev] git:master: dispatcher: new variant - ds_is_from_list(groupid, uri, mode)

Daniel-Constantin Mierla miconda at gmail.com
Fri Sep 5 17:46:58 CEST 2014


Module: sip-router
Branch: master
Commit: 6016958dfe71996689abc897baa629afb3b1c552
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=6016958dfe71996689abc897baa629afb3b1c552

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date:   Fri Sep  5 17:21:40 2014 +0200

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

---

 modules/dispatcher/dispatch.c   |   48 ++++++++++++++++++++++++++++++++++----
 modules/dispatcher/dispatch.h   |    9 ++++++-
 modules/dispatcher/dispatcher.c |   38 ++++++++++++++++++++++++++++++
 3 files changed, 89 insertions(+), 6 deletions(-)

diff --git a/modules/dispatcher/dispatch.c b/modules/dispatcher/dispatch.c
index 8fc6b79..120dcdd 100644
--- a/modules/dispatcher/dispatch.c
+++ b/modules/dispatcher/dispatch.c
@@ -332,8 +332,10 @@ int add_dest2list(int id, str uri, int flags, int priority, str *attrs,
 	/* Free the hostname */
 	hostent2ip_addr(&dp->ip_address, he, 0);
 
-	/* Copy the Port out of the URI: */
+	/* Copy the port out of the URI */
 	dp->port = puri.port_no;		
+	/* Copy the proto out of the URI */
+	dp->proto = puri.proto;
 
 	if(sp->dlist==NULL)
 	{
@@ -2245,15 +2247,45 @@ int ds_print_list(FILE *fout)
 /* Checks, if the request (sip_msg *_m) comes from a host in a group
  * (group-id or -1 for all groups)
  */
-int ds_is_from_list(struct sip_msg *_m, int group)
+int ds_is_addr_from_list(sip_msg_t *_m, int group, str *uri, int mode)
 {
 	pv_value_t val;
 	ds_set_t *list;
 	int j;
+	struct ip_addr* pipaddr;
+	struct ip_addr  aipaddr;
+	unsigned short tport;
+	unsigned short tproto;
+	sip_uri_t puri;
+	static char hn[256];
+	struct hostent* he;
 
 	memset(&val, 0, sizeof(pv_value_t));
 	val.flags = PV_VAL_INT|PV_TYPE_INT;
 
+	if(uri==NULL || uri->len<=0) {
+		pipaddr = &_m->rcv.src_ip;
+		tport = _m->rcv.src_port;
+		tproto = _m->rcv.proto;
+	} else {
+		if(parse_uri(uri->s, uri->len, &puri)!=0 || puri.host.len>255) {
+			LM_ERR("bad uri [%.*s]\n", uri->len, uri->s);
+			return -1;
+		}
+		strncpy(hn, puri.host.s, puri.host.len);
+		hn[puri.host.len]='\0';
+
+		he=resolvehost(hn);
+		if (he==0) {
+			LM_ERR("could not resolve %.*s\n", puri.host.len, puri.host.s);
+			return -1;
+		}
+		hostent2ip_addr(&aipaddr, he, 0);
+		pipaddr = &aipaddr;
+		tport = puri.port_no;
+		tproto = puri.proto;
+	}
+
 	for(list = _ds_list; list!= NULL; list= list->next)
 	{
 		// 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)
 			for(j=0; j<list->nr; j++)
 			{
 				// LM_ERR("port no: %d (%d)\n", list->dlist[j].port, j);
-				if (ip_addr_cmp(&_m->rcv.src_ip, &list->dlist[j].ip_address)
-						&& (list->dlist[j].port==0
-							|| _m->rcv.src_port == list->dlist[j].port))
+				if (ip_addr_cmp(pipaddr, &list->dlist[j].ip_address)
+						&& ((mode&DS_MATCH_NOPORT) || list->dlist[j].port==0
+							|| tport == list->dlist[j].port)
+						&& ((mode&DS_MATCH_NOPROTO)
+							|| tproto == list->dlist[j].proto))
 				{
 					if(group==-1 && ds_setid_pvname.s!=0)
 					{
@@ -2296,6 +2330,10 @@ int ds_is_from_list(struct sip_msg *_m, int group)
 	return -1;
 }
 
+int ds_is_from_list(struct sip_msg *_m, int group)
+{
+	return ds_is_addr_from_list(_m, group, NULL, DS_MATCH_NOPROTO);
+}
 
 int ds_print_mi_list(struct mi_node* rpl)
 {
diff --git a/modules/dispatcher/dispatch.h b/modules/dispatcher/dispatch.h
index c02cf50..e0466d8 100644
--- a/modules/dispatcher/dispatch.h
+++ b/modules/dispatcher/dispatch.h
@@ -61,6 +61,10 @@
 #define DS_PROBE_ALL		1
 #define DS_PROBE_INACTIVE	2
 
+#define DS_MATCH_ALL		0
+#define DS_MATCH_NOPORT		1
+#define DS_MATCH_NOPROTO	2
+
 extern str ds_db_url;
 extern str ds_table_name;
 extern str ds_set_id_col;
@@ -124,6 +128,8 @@ int ds_hash_load_init(unsigned int htsize, int expire, int initexpire);
 int ds_hash_load_destroy(void);
 
 int ds_is_from_list(struct sip_msg *_m, int group);
+int ds_is_addr_from_list(sip_msg_t *_m, int group, str *uri, int mode);
+
 /*! \brief
  * Timer for checking inactive destinations
  */
@@ -156,7 +162,8 @@ typedef struct _ds_dest
 	int dload;
 	ds_attrs_t attrs;
 	struct ip_addr ip_address; 	/*!< IP-Address of the entry */
-	unsigned short int port; 	/*!< Port of the request URI */
+	unsigned short int port; 	/*!< Port of the URI */
+	unsigned short int proto; 	/*!< Protocol of the URI */
 	int failure_count;
 	struct _ds_dest *next;
 } ds_dest_t;
diff --git a/modules/dispatcher/dispatcher.c b/modules/dispatcher/dispatcher.c
index f551003..5356f2e 100644
--- a/modules/dispatcher/dispatcher.c
+++ b/modules/dispatcher/dispatcher.c
@@ -159,6 +159,8 @@ static int w_ds_load_update(struct sip_msg*, char*, char*);
 
 static int w_ds_is_from_list0(struct sip_msg*, char*, char*);
 static int w_ds_is_from_list1(struct sip_msg*, char*, char*);
+static int w_ds_is_from_list3(struct sip_msg*, char*, char*, char*);
+static int fixup_ds_is_from_list3(void** param, int param_no);
 
 static void destroy(void);
 
@@ -190,6 +192,8 @@ static cmd_export_t cmds[]={
 		0, 0, REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE},
 	{"ds_is_from_list",  (cmd_function)w_ds_is_from_list1, 1,
 		fixup_igp_null, 0, ANY_ROUTE},
+	{"ds_is_from_list",  (cmd_function)w_ds_is_from_list3, 3,
+		fixup_ds_is_from_list3, 0, ANY_ROUTE},
 	{"ds_load_unset",    (cmd_function)w_ds_load_unset,   0,
 		0, 0, ANY_ROUTE},
 	{"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)
 	return ds_is_from_list(msg, s);
 }
 
+static int w_ds_is_from_list3(struct sip_msg *msg, char *set, char *uri, char *mode)
+{
+	int vset;
+	int vmode;
+	str suri;
+
+	if(fixup_get_ivalue(msg, (gparam_t*)set, &vset)!=0)
+	{
+		LM_ERR("cannot get set id value\n");
+		return -1;
+	}
+	if(fixup_get_svalue(msg, (gparam_t*)uri, &suri)!=0)
+	{
+		LM_ERR("cannot get uri value\n");
+		return -1;
+	}
+	if(fixup_get_ivalue(msg, (gparam_t*)mode, &vmode)!=0)
+	{
+		LM_ERR("cannot get mode value\n");
+		return -1;
+	}
+
+	return ds_is_addr_from_list(msg, vset, &suri, vmode);
+}
+
+static int fixup_ds_is_from_list3(void** param, int param_no)
+{
+	if(param_no==1 || param_no==3)
+		return fixup_igp_null(param, 1);
+	if(param_no==2)
+		return fixup_spve_null(param, 1);
+	return 0;
+}
+
 static int ds_parse_reply_codes() {
 	param_t* params_list = NULL;
 	param_t *pit=NULL;




More information about the sr-dev mailing list