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