RCS file: /cvsroot/ser/sip_router/modules/acc/Attic/acc.c,v retrieving revision 1.26.2.1 diff -u -r1.26.2.1 acc.c --- modules/acc/acc.c 14 Jun 2005 20:25:19 -0000 1.26.2.1 +++ modules/acc/acc.c 25 Dec 2005 17:35:19 -0000 @@ -49,6 +49,9 @@ #include "acc_mod.h" #include "acc.h" #include "dict.h" +#include "../../parser/parse_rr.h" +#include "../../trim.h" +#include "../../parser/parse_uri.h" #ifdef RAD_ACC # ifdef RADIUSCLIENT_NG_4 # include @@ -71,6 +74,8 @@ #define M_NAME "acc" #endif +extern int swap_dir; + #define ATR(atr) atr_arr[cnt].s=A_##atr;\ atr_arr[cnt].len=A_##atr##_LEN; @@ -101,6 +106,94 @@ #endif +static int check_ftag(struct sip_msg* msg, str* uri) +{ + param_hooks_t hooks; + param_t* params; + char* semi; + struct to_body* from; + str t; + + t = *uri; + params = 0; + semi = q_memchr(t.s, ';', t.len); + if (!semi) { + DBG("No ftag parameter found\n"); + return -1; + } + + t.len -= semi - uri->s + 1; + t.s = semi + 1; + trim_leading(&t); + + if (parse_params(&t, CLASS_URI, &hooks, ¶ms) < 0) { + LOG(L_ERR, "Error while parsing parameters\n"); + return -1; + } + + if (!hooks.uri.ftag) { + DBG("No ftag parameter found\n"); + goto err; + } + + from = get_from(msg); + + if (!from || !from->tag_value.len || !from->tag_value.s) { + DBG("No from tag parameter found\n"); + goto err; + } + + if (from->tag_value.len == hooks.uri.ftag->body.len && + !strncmp(from->tag_value.s, hooks.uri.ftag->body.s, hooks.uri.ftag->body.len)) { + DBG("Route ftag and From tag are same\n"); + free_params(params); + return 0; + } else { + DBG("Route ftag and From tag are NOT same\n"); + free_params(params); + return 1; + } + + err: + if (params) free_params(params); + return -1; +} + +static int get_direction(struct sip_msg* msg) +{ + int ret; + if (parse_orig_ruri(msg) < 0) { + return -1; + } + + if (!msg->parsed_orig_ruri_ok) { + LOG(L_ERR, "Error while parsing original Request-URI\n"); + return -1; + } + + ret = check_self(&msg->parsed_orig_ruri.host, + msg->parsed_orig_ruri.port_no ? msg->parsed_orig_ruri.port_no : SIP_PORT, 0);/* match all protos*/ + if (ret < 0) return -1; + if (ret > 0) { + /* Route is in ruri */ + return check_ftag(msg, &msg->first_line.u.request.uri); + } else { + if (msg->route) { + if (parse_rr(msg->route) < 0) { + LOG(L_ERR, "Error while parsing Route HF\n"); + return -1; + } + ret = check_ftag(msg, &((rr_t*)msg->route->parsed)->nameaddr.uri); + if (msg->route->parsed) free_rr((rr_t**)&msg->route->parsed); + return ret; + } else { + DBG("No Route headers found\n"); + return -1; + } + } +} + + static inline struct hdr_field *valid_to( struct cell *t, struct sip_msg *reply) { @@ -156,9 +249,10 @@ static str mycode; str *cr; struct cseq_body *cseq; + int dir; cnt=tl=al=0; - + dir = -2; /* we don't care about parsing here; either the function * was called from script, in which case the wrapping function * is supposed to parse, or from reply processing in which case @@ -218,10 +312,19 @@ } /* fallback to from-uri if digest unavailable ... */ case 'F': /* from-uri */ - if (rq->from && (from=get_from(rq)) - && from->uri.len) { + + if (swap_dir && dir == -2) dir = get_direction(rq); + if (dir <= 0) { + if (rq->from && (from=get_from(rq)) + && from->uri.len) { val_arr[cnt]=&from->uri; - } else val_arr[cnt]=&na; + } else val_arr[cnt]=&na; + } else { + if (rq->to && (pto=get_to(rq)) + && pto->uri.len) { + val_arr[cnt]=&pto->uri; + } else val_arr[cnt]=&na; + } ATR(FROMURI); break; case '0': /* from user */ @@ -255,10 +358,19 @@ ATR(TOTAG); break; case 'T': /* to-uri */ - if (rq->to && (pto=get_to(rq)) - && pto->uri.len) { + + if (swap_dir && dir == -2) dir = get_direction(rq); + if (dir <= 0) { + if (rq->to && (pto=get_to(rq)) + && pto->uri.len) { val_arr[cnt]=&pto->uri; - } else val_arr[cnt]=&na; + } else val_arr[cnt]=&na; + } else { + if (rq->from && (from=get_from(rq)) + && from->uri.len) { + val_arr[cnt]=&from->uri; + } else val_arr[cnt]=&na; + } ATR(TOURI); break; case '1': /* to user */ Index: modules/acc/acc_mod.c =================================================================== RCS file: /cvsroot/ser/sip_router/modules/acc/Attic/acc_mod.c,v retrieving revision 1.39.2.3 diff -u -r1.39.2.3 acc_mod.c --- modules/acc/acc_mod.c 20 Sep 2005 16:03:14 -0000 1.39.2.3 +++ modules/acc/acc_mod.c 25 Dec 2005 17:35:20 -0000 @@ -115,6 +115,7 @@ int radius_flag = 0; int radius_missed_flag = 0; static int service_type = -1; +int swap_dir = 0; void *rh; struct attr attrs[A_MAX]; struct val vals[V_MAX]; @@ -206,6 +207,7 @@ {"radius_flag", INT_PARAM, &radius_flag }, {"radius_missed_flag", INT_PARAM, &radius_missed_flag }, {"service_type", INT_PARAM, &service_type }, + {"swap_direction", INT_PARAM, &swap_dir}, #endif /* DIAMETER */ #ifdef DIAM_ACC @@ -414,7 +416,7 @@ * don't be worried about parsing outcome -- if it failed, * we will report N/A */ - parse_headers(rq, HDR_CALLID| HDR_FROM| HDR_TO, 0 ); + parse_headers(rq, HDR_CALLID| HDR_FROM| HDR_TO| HDR_ROUTE, 0 ); parse_from_header(rq); if (strchr(log_fmt, 'p') || strchr(log_fmt, 'D')) { Index: modules/acc/acc_mod.h =================================================================== RCS file: /cvsroot/ser/sip_router/modules/acc/Attic/acc_mod.h,v retrieving revision 1.14 diff -u -r1.14 acc_mod.h --- modules/acc/acc_mod.h 24 Aug 2004 08:58:23 -0000 1.14 +++ modules/acc/acc_mod.h 25 Dec 2005 17:35:21 -0000 @@ -87,6 +87,7 @@ extern char* acc_totag_col; extern char* acc_fromtag_col; +extern int swap_dir; #endif /* SQL_ACC */ Index: parser/parse_param.c =================================================================== RCS file: /cvsroot/ser/sip_router/parser/parse_param.c,v retrieving revision 1.21 diff -u -r1.21 parse_param.c --- parser/parse_param.c 1 Sep 2004 12:50:40 -0000 1.21 +++ parser/parse_param.c 25 Dec 2005 17:35:26 -0000 @@ -144,6 +144,15 @@ _h->uri.maddr = _p; } break; + + case 'f': + case 'F': + if ((_p->name.len == 4) && + (!strncasecmp(_p->name.s + 1, "tag", 3))) { + _p->type = P_FTAG; + _h->uri.ftag = _p; + } + break; } } @@ -475,6 +484,7 @@ case P_MADDR: type = "P_MADDR"; break; case P_TTL: type = "P_TTL"; break; case P_RECEIVED: type = "P_RECEIVED"; break; + case P_FTAG: type = "P_FTAG"; break; default: type = "UNKNOWN"; break; } Index: parser/parse_param.h =================================================================== RCS file: /cvsroot/ser/sip_router/parser/parse_param.h,v retrieving revision 1.11 diff -u -r1.11 parse_param.h --- parser/parse_param.h 1 Sep 2004 11:56:59 -0000 1.11 +++ parser/parse_param.h 25 Dec 2005 17:35:26 -0000 @@ -53,6 +53,7 @@ P_R2, /* URI: r2 parameter (ser specific) */ P_MADDR, /* URI: maddr parameter */ P_TTL, /* URI: ttl parameter */ + P_FTAG /* URI: ftag parameter */ } ptype_t; @@ -98,6 +99,7 @@ struct param* r2; /* r2 parameter */ struct param* maddr; /* maddr parameter */ struct param* ttl; /* ttl parameter */ + struct param* ftag; /* ftag parameter */ };