Module: sems Branch: master Commit: 0c48994f00f07aac42ad6642b8a951184b4e6622 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=0c48994f00f07aac42ad6642b8a951184b4e6622
Author: Raphael Coeffic <[email protected]> Committer: Raphael Coeffic <[email protected]> Date: Fri Feb 18 13:56:26 2011 +0100 isolate strict routing. --- core/sip/trans_layer.cpp | 242 +++++++++++++++++++++++----------------------- 1 files changed, 121 insertions(+), 121 deletions(-) diff --git a/core/sip/trans_layer.cpp b/core/sip/trans_layer.cpp index f9c1a22..f2da53e 100644 --- a/core/sip/trans_layer.cpp +++ b/core/sip/trans_layer.cpp @@ -32,6 +32,7 @@ #include "trans_table.h" #include "parse_cseq.h" #include "parse_from_to.h" +#include "parse_route.h" #include "parse_100rel.h" #include "sip_trans.h" #include "msg_fline.h" @@ -572,6 +573,111 @@ int _trans_layer::send_sl_reply(sip_msg* req, int reply_code, return err; } +static void prepare_strict_routing(sip_msg* msg) +{ + assert(!msg->route.empty()); + + sip_header* fr = msg->route.front(); + assert(fr->p); + + assert(!((sip_route*)(fr->p))->elmts.empty()); + sip_nameaddr* fr_na = ((sip_route*)(fr->p))->elmts.front(); + + // place a cursor at the end of the + const char* c = fr_na->addr.s + fr_na->addr.len; + const char* end = fr->value.s + fr->value.len; + + assert(c<=end); + + // detect beginning of next route + enum { + RR_PARAMS=0, + RR_QUOTED, + RR_SEP_SWS, // space(s) after ',' + RR_NXT_ROUTE + }; + + int st = RR_PARAMS; + for(;c<end;c++){ + + switch(st){ + case RR_PARAMS: + switch(*c){ + case SP: + case HTAB: + case CR: + case LF: + break; + case COMMA: + st = RR_SEP_SWS; + break; + case DQUOTE: + st = RR_QUOTED; + break; + } + break; + case RR_QUOTED: + switch(*c){ + case BACKSLASH: + c++; + break; + case DQUOTE: + st = RR_PARAMS; + break; + } + break; + case RR_SEP_SWS: + switch(*c){ + case SP: + case HTAB: + case CR: + case LF: + break; + default: + st = RR_NXT_ROUTE; + goto nxt_route; + } + break; + } + } + + nxt_route: + + switch(st){ + case RR_QUOTED: + case RR_SEP_SWS: + DBG("Malformed first route header\n"); + case RR_PARAMS: + // remove current route header from message + msg->route.pop_front(); + DBG("route_hdrs.length() = %i\n",(int)msg->route.size()); + { + list<sip_header*>::iterator h_it = + std::find(msg->hdrs.begin(),msg->hdrs.end(),fr); + + if(h_it != msg->hdrs.end()) + msg->hdrs.erase(h_it); + } + DBG("delete (fr=0x%p)\n",fr); + delete fr; + break; + + case RR_NXT_ROUTE: + // remove current route from this header + fr->value.s = c; + fr->value.len = end-c; + break; + } + + // copy r_uri at the end of + // the route set. + msg->hdrs.push_back(new sip_header(0,"Route",msg->u.request->ruri_str)); // BUG: must include <>!!! + + // and replace the R-URI with the first route URI + msg->u.request->ruri_str = fr_na->addr; +} + + // // Ref. RFC 3261 "12.2.1.1 Generating the Request" // @@ -582,143 +688,37 @@ int _trans_layer::set_next_hop(sip_msg* msg, assert(msg); list<sip_header*>& route_hdrs = msg->route; - cstring& r_uri = msg->u.request->ruri_str; - int err=0; if(!route_hdrs.empty()){ sip_header* fr = route_hdrs.front(); - - sip_nameaddr na; - const char* c = fr->value.s; - if(parse_nameaddr(&na, &c, fr->value.len)<0) { + sip_uri* route_uri = get_first_route_uri(fr); + if(route_uri == NULL) { - DBG("Parsing name-addr failed\n"); + DBG("Parsing 1st route uri failed\n"); return -1; } - if(parse_uri(&na.uri,na.addr.s,na.addr.len) < 0) { - - DBG("Parsing route uri failed\n"); - return -1; - } - - bool is_lr = false; - if(!na.uri.params.empty()){ - - list<sip_avp*>::iterator it = na.uri.params.begin(); - for(;it != na.uri.params.end(); it++){ - - if( ((*it)->name.len == 2) && - (!memcmp((*it)->name.s,"lr",2)) ) { - - is_lr = true; - break; - } - } - - } - if (next_hop->len == 0) { - *next_hop = na.uri.host; - if(na.uri.port_str.len) - *next_port = na.uri.port; - } - - if(!is_lr){ - - // detect beginning of next route - - enum { - RR_PARAMS=0, - RR_QUOTED, - RR_SEP_SWS, // space(s) after ',' - RR_NXT_ROUTE - }; - - int st = RR_PARAMS; - const char* end = fr->value.s + fr->value.len; - for(;c<end;c++){ - - switch(st){ - case RR_PARAMS: - switch(*c){ - case SP: - case HTAB: - case CR: - case LF: - break; - case COMMA: - st = RR_SEP_SWS; - break; - case DQUOTE: - st = RR_QUOTED; - break; - } - break; - case RR_QUOTED: - switch(*c){ - case BACKSLASH: - c++; - break; - case DQUOTE: - st = RR_PARAMS; - break; - } - break; - case RR_SEP_SWS: - switch(*c){ - case SP: - case HTAB: - case CR: - case LF: - break; - default: - st = RR_NXT_ROUTE; - goto nxt_route; - } - break; - } - } - - nxt_route: - - switch(st){ - case RR_QUOTED: - case RR_SEP_SWS: - DBG("Malformed first route header\n"); - case RR_PARAMS: - // remove current route header from message - route_hdrs.pop_front(); - DBG("route_hdrs.length() = %i\n",(int)route_hdrs.size()); - { - list<sip_header*>::iterator h_it = std::find(msg->hdrs.begin(),msg->hdrs.end(),fr); - if(h_it != msg->hdrs.end()) msg->hdrs.erase(h_it); - } - DBG("delete (fr=0x%p)\n",fr); - delete fr; - break; - - case RR_NXT_ROUTE: - // remove current route from this header - fr->value.s = c; - fr->value.len = end-c; - break; - } - - - // copy r_uri at the end of - // the route set. - msg->hdrs.push_back(new sip_header(0,"Route",r_uri)); + *next_hop = route_uri->host; + if(route_uri->port_str.len) + *next_port = route_uri->port; + } - r_uri = na.addr; + if(is_loose_route(route_uri)){ + // loose routing is used, + // no need for further processing + return 0; } - + + prepare_strict_routing(msg); } else { sip_uri parsed_r_uri; + cstring& r_uri = msg->u.request->ruri_str; + err = parse_uri(&parsed_r_uri,r_uri.s,r_uri.len); if(err < 0){ ERROR("Invalid Request URI\n"); _______________________________________________ Semsdev mailing list [email protected] http://lists.iptel.org/mailman/listinfo/semsdev
