Module: sip-router
Branch: master
Commit: 6016958dfe71996689abc897baa629afb3b1c552
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=6016958…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)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;