diff --git a/src/modules/drouting/drouting.c b/src/modules/drouting/drouting.c index 4811faa0d50..56ddc43b961 100644 --- a/src/modules/drouting/drouting.c +++ b/src/modules/drouting/drouting.c @@ -38,6 +38,7 @@ #include "../../core/parser/parse_from.h" #include "../../core/parser/parse_uri.h" #include "../../core/dset.h" +#include "../../core/mod_fix.h" #include "../../core/rpc_lookup.h" #include "../../core/rand/kam_rand.h" @@ -110,10 +111,7 @@ static int dr_init(void); static int dr_child_init(int rank); static int dr_exit(void); -static int fixup_do_routing(void **param, int param_no); -static int fixup_from_gw(void **param, int param_no); - -static int do_routing(struct sip_msg *msg, dr_group_t *drg); +static int do_routing(struct sip_msg *msg, int grp_id); static int do_routing_0(struct sip_msg *msg, char *str1, char *str2); static int do_routing_1(struct sip_msg *msg, char *str1, char *str2); static int use_next_gw(struct sip_msg *msg); @@ -132,20 +130,20 @@ MODULE_VERSION static cmd_export_t cmds[] = { {"do_routing", (cmd_function)do_routing_0, 0, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE}, - {"do_routing", (cmd_function)do_routing_1, 1, fixup_do_routing, 0, + {"do_routing", (cmd_function)do_routing_1, 1, fixup_igp_null, 0, REQUEST_ROUTE | FAILURE_ROUTE}, {"use_next_gw", (cmd_function)use_next_gw, 0, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE}, {"next_routing", (cmd_function)use_next_gw, 0, 0, 0, FAILURE_ROUTE}, {"is_from_gw", (cmd_function)is_from_gw_0, 0, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, - {"is_from_gw", (cmd_function)is_from_gw_1, 1, fixup_from_gw, 0, + {"is_from_gw", (cmd_function)is_from_gw_1, 1, fixup_igp_null, 0, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, - {"is_from_gw", (cmd_function)is_from_gw_2, 2, fixup_from_gw, 0, + {"is_from_gw", (cmd_function)is_from_gw_2, 2, fixup_igp_igp, 0, REQUEST_ROUTE}, {"goes_to_gw", (cmd_function)goes_to_gw_0, 0, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, - {"goes_to_gw", (cmd_function)goes_to_gw_1, 1, fixup_from_gw, 0, + {"goes_to_gw", (cmd_function)goes_to_gw_1, 1, fixup_igp_null, 0, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, {0, 0, 0, 0, 0, 0} }; @@ -626,12 +624,39 @@ static inline str *build_ruri( static int do_routing_0(struct sip_msg *msg, char *str1, char *str2) { - return do_routing(msg, NULL); + int grp_id; + struct to_body *from; + struct sip_uri uri; + + /* get the username from FROM_HDR */ + if(parse_from_header(msg) != 0) { + LM_ERR("unable to parse from hdr\n"); + return -1; + } + from = (struct to_body *)msg->from->parsed; + /* parse uri */ + if(parse_uri(from->uri.s, from->uri.len, &uri) != 0) { + LM_ERR("unable to parse from uri\n"); + return -1; + } + + grp_id = get_group_id(&uri); + if(grp_id < 0) { + LM_ERR("failed to get group id\n"); + return -1;; + } + + return do_routing(msg, grp_id); } static int do_routing_1(struct sip_msg *msg, char *str1, char *str2) { - return do_routing(msg, (dr_group_t *)str1); + int grp_id; + if(fixup_get_ivalue(msg, (gparam_t*)str1, &grp_id)<0) { + LM_ERR("failed to get group id parameter\n"); + return -1; + } + return do_routing(msg, grp_id); } @@ -686,13 +711,11 @@ int dr_already_choosen(rt_info_t *rt_info, int *active_gwlist, return 0; } -static int do_routing(struct sip_msg *msg, dr_group_t *drg) +static int do_routing(struct sip_msg *msg, int grp_id) { - struct to_body *from; - struct sip_uri uri; rt_info_t *rt_info; - int grp_id; int i, j, l, t; + struct sip_uri uri; str *ruri; int_str val; struct usr_avp *avp; @@ -710,41 +733,6 @@ static int do_routing(struct sip_msg *msg, dr_group_t *drg) goto error1; } - /* get the username from FROM_HDR */ - if(parse_from_header(msg) != 0) { - LM_ERR("unable to parse from hdr\n"); - goto error1; - } - from = (struct to_body *)msg->from->parsed; - /* parse uri */ - if(parse_uri(from->uri.s, from->uri.len, &uri) != 0) { - LM_ERR("unable to parse from uri\n"); - goto error1; - } - - /* get user's routing group */ - if(drg == NULL) { - grp_id = get_group_id(&uri); - if(grp_id < 0) { - LM_ERR("failed to get group id\n"); - goto error1; - } - } else { - if(drg->type == 0) - grp_id = (int)drg->u.grp_id; - else if(drg->type == 1) { - grp_id = 0; /* call get avp here */ - if((avp = search_first_avp( - drg->u.avp_id.type, drg->u.avp_id.name, &val, 0)) - == NULL - || (avp->flags & AVP_VAL_STR)) { - LM_ERR("failed to get group id\n"); - goto error1; - } - grp_id = val.n; - } else - grp_id = 0; - } LM_DBG("using dr group %d\n", grp_id); /* get the number */ @@ -992,85 +980,6 @@ static int do_routing(struct sip_msg *msg, dr_group_t *drg) } -static int fixup_do_routing(void **param, int param_no) -{ - char *s; - dr_group_t *drg; - pv_spec_t avp_spec; - str r; - - s = (char *)*param; - - if(param_no == 1) { - if(s == NULL || s[0] == 0) { - LM_CRIT("empty group id definition"); - return E_CFG; - } - - drg = (dr_group_t *)pkg_malloc(sizeof(dr_group_t)); - if(drg == NULL) { - LM_ERR("no more memory\n"); - return E_OUT_OF_MEM; - } - memset(drg, 0, sizeof(dr_group_t)); - - if(s[0] == '$') { - /* param is a PV (AVP only supported) */ - r.s = s; - r.len = strlen(s); - if(pv_parse_spec(&r, &avp_spec) == 0 || avp_spec.type != PVT_AVP) { - LM_ERR("malformed or non AVP %s AVP definition\n", s); - pkg_free(drg); - return E_CFG; - } - - if(pv_get_avp_name(0, &(avp_spec.pvp), &(drg->u.avp_id.name), - &(drg->u.avp_id.type)) - != 0) { - LM_ERR("[%s]- invalid AVP definition\n", s); - pkg_free(drg); - return E_CFG; - } - drg->type = 1; - /* do not free the param as the AVP spec may point inside - * this string*/ - } else { - while(s && *s) { - if(*s < '0' || *s > '9') { - LM_ERR("bad number\n"); - pkg_free(drg); - return E_UNSPEC; - } - drg->u.grp_id = (drg->u.grp_id) * 10 + (*s - '0'); - s++; - } - pkg_free(*param); - } - *param = (void *)drg; - } - - return 0; -} - - -static int fixup_from_gw(void **param, int param_no) -{ - unsigned long type; - int err; - - if(param_no == 1 || param_no == 2) { - type = str2s(*param, strlen(*param), &err); - if(err == 0) { - pkg_free(*param); - *param = (void *)type; - return 0; - } else { - LM_ERR("bad number <%s>\n", (char *)(*param)); - return E_CFG; - } - } - return 0; -} static int strip_username(struct sip_msg *msg, int strip) { @@ -1109,14 +1018,19 @@ static int is_from_gw_0(struct sip_msg *msg, char *str, char *str2) } -static int is_from_gw_1(struct sip_msg *msg, char *str, char *str2) +static int is_from_gw_1(struct sip_msg *msg, char *str1, char *str2) { pgw_addr_t *pgwa = NULL; - int type = (int)(long)str; + int type; if(rdata == NULL || *rdata == NULL || msg == NULL) return -1; + if(fixup_get_ivalue(msg, (gparam_t*)str1, &type)<0) { + LM_ERR("failed to get parameter value\n"); + return -1; + } + pgwa = (*rdata)->pgw_addr_l; while(pgwa) { if(type == pgwa->type @@ -1131,12 +1045,21 @@ static int is_from_gw_1(struct sip_msg *msg, char *str, char *str2) static int is_from_gw_2(struct sip_msg *msg, char *str1, char *str2) { pgw_addr_t *pgwa = NULL; - int type = (int)(long)str1; - int flags = (int)(long)str2; + int type; + int flags; if(rdata == NULL || *rdata == NULL || msg == NULL) return -1; + if(fixup_get_ivalue(msg, (gparam_t*)str1, &type)<0) { + LM_ERR("failed to get type parameter value\n"); + return -1; + } + if(fixup_get_ivalue(msg, (gparam_t*)str2, &flags)<0) { + LM_ERR("failed to get flags parameter value\n"); + return -1; + } + pgwa = (*rdata)->pgw_addr_l; while(pgwa) { if(type == pgwa->type @@ -1152,19 +1075,17 @@ static int is_from_gw_2(struct sip_msg *msg, char *str1, char *str2) } -static int goes_to_gw_1(struct sip_msg *msg, char *_type, char *_f2) +static int goes_to_gw_helper(struct sip_msg *msg, int type) { pgw_addr_t *pgwa = NULL; struct sip_uri puri; struct ip_addr *ip; str *uri; - int type; if(rdata == NULL || *rdata == NULL || msg == NULL) return -1; uri = GET_NEXT_HOP(msg); - type = (int)(long)_type; if(parse_uri(uri->s, uri->len, &puri) < 0) { LM_ERR("bad uri <%.*s>\n", uri->len, uri->s); @@ -1183,8 +1104,17 @@ static int goes_to_gw_1(struct sip_msg *msg, char *_type, char *_f2) return -1; } +static int goes_to_gw_1(struct sip_msg *msg, char *_type, char *_f2) +{ + int type; + if(fixup_get_ivalue(msg, (gparam_t*)_type, &type)<0) { + LM_ERR("failed to get parameter value\n"); + return -1; + } + return goes_to_gw_helper(msg, type); +} static int goes_to_gw_0(struct sip_msg *msg, char *_type, char *_f2) { - return goes_to_gw_1(msg, (char *)(long)-1, _f2); + return goes_to_gw_helper(msg, -1); }