diff --git a/ChangeLog b/ChangeLog index 540ded6..a9fcd86 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 0.5.8 ===== + 05-Sep-2004: - Cross-provider calls (e.g. sipphone <-> FWD, with dial + prefixes) did not work properly + 04-Sep-2004: - more on Route Headers 27-Aug-2004: - preliminary (and reduced) support for Route Headers 26-Aug-2004: - more DEBUG output 22-Aug-2004: - fix: secure_enviroment - set proper EGID (by Daniel Mueller) diff --git a/src/proxy.c b/src/proxy.c index 80f3411..887861e 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -158,34 +158,36 @@ int proxy_request (sip_ticket_t *ticket) { * is the telegram directed to an internally registered host? * -> it must be an INCOMING request */ - if (type == 0) for (i=0; ireq_uri, urlmap[i].masq_url)==STS_SUCCESS) || - (!MSG_IS_REGISTER(request) && - (compare_url(request->req_uri, urlmap[i].reg_url)==STS_SUCCESS))) { - type=REQTYP_INCOMING; - break; - } - /* incoming request ('to' == 'masq') || (('to' == 'reg') && !REGISTER)*/ - if ((compare_url(request->to->url, urlmap[i].masq_url)==STS_SUCCESS) || - (!MSG_IS_REGISTER(request) && - (compare_url(request->to->url, urlmap[i].reg_url)==STS_SUCCESS))) { - type=REQTYP_INCOMING; - break; + /* incoming request (SIP URI == 'masq') || ((SIP URI == 'reg') && !REGISTER)*/ + if ((compare_url(request->req_uri, urlmap[i].masq_url)==STS_SUCCESS) || + (!MSG_IS_REGISTER(request) && + (compare_url(request->req_uri, urlmap[i].reg_url)==STS_SUCCESS))) { + type=REQTYP_INCOMING; + break; + } + /* incoming request ('to' == 'masq') || (('to' == 'reg') && !REGISTER)*/ + if ((compare_url(request->to->url, urlmap[i].masq_url)==STS_SUCCESS) || + (!MSG_IS_REGISTER(request) && + (compare_url(request->to->url, urlmap[i].reg_url)==STS_SUCCESS))) { + type=REQTYP_INCOMING; + break; + } } } #endif @@ -402,11 +404,19 @@ int proxy_request (sip_ticket_t *ticket) { * include my own as well. The local UA will probably send its answer * to the topmost Route Header (8.1.2 of RFC3261) */ - if ((type == REQTYP_INCOMING) && - (request->record_routes) && + if ((request->record_routes) && (!osip_list_eol(request->record_routes, 0))) { - DEBUGC(DBCLASS_PROXY,"Adding my Record-Route"); - route_add_recordroute(ticket); + if (type == REQTYP_INCOMING) { + DEBUGC(DBCLASS_PROXY,"Adding my Record-Route"); + route_add_recordroute(ticket); + } else { + /* + * outgoing packets must not have a record route header, as + * these likely will contain private IP addresses. + */ + DEBUGC(DBCLASS_PROXY,"Purging Record-Routes (outgoing packet)"); + route_purge_recordroute(ticket); + } } /* @@ -657,15 +667,73 @@ int proxy_response (sip_ticket_t *ticket) { * is the telegram directed to an internal registered host? * -> it must be an INCOMING response */ - if (type == 0) for (i=0; ifrom->url, urlmap[i].reg_url)==STS_SUCCESS) || - (compare_url(response->from->url, urlmap[i].masq_url)==STS_SUCCESS)) { - type=RESTYP_INCOMING; - break; + if (type == 0) { + for (i=0; ifrom->url, urlmap[i].reg_url)==STS_SUCCESS) || + (compare_url(response->from->url, urlmap[i].masq_url)==STS_SUCCESS)) { + type=RESTYP_INCOMING; + break; + } } } +/* &&&& Open Issue &&&& + it has been seen with corss-provider calls that the FROM may be 'garbled' + (e.g 1393xxx@proxy01.sipphone.com for calls made sipphone -> FWD) + How can we deal with this? Should I take into consideration the 'Via' + headers? This is the only clue I have, pointing to the *real* UA. + Maybe I should put in a 'siproxd' ftag value to recognize it a header + put in by myself +*/ + if ((type == 0) && (!osip_list_eol(response->vias, 0))) { + osip_via_t *via; + struct in_addr addr_via, addr_myself; + int port_via, port_ua; + + /* get the via address */ + via = (osip_via_t *) osip_list_get (response->vias, 0); + DEBUGC(DBCLASS_PROXY, "proxy_response: check via [%s] for " + "registered UA",via->host); + sts=get_ip_by_host(via->host, &addr_via); + if (sts == STS_FAILURE) { + DEBUGC(DBCLASS_DNS, "proxy_response: cannot resolve VIA [%s]", + via->host); + } else { + + for (i=0; ihost, &addr_myself); + if (sts == STS_FAILURE) { + DEBUGC(DBCLASS_DNS, "proxy_response: cannot resolve " + "true_url [%s]", via->host); + continue; + } + + port_via=0; + if (via->port) port_via=atoi(via->port); + if (port_via <= 0) port_via=SIP_PORT; + + port_ua=0; + if (urlmap[i].true_url->port) + port_ua=atoi(urlmap[i].true_url->port); + if (port_ua <= 0) port_ua=SIP_PORT; + + DEBUGC(DBCLASS_BABBLE, "proxy_response: checking for registered " + "host [%s:%i] <-> [%s:%i]", + urlmap[i].true_url->host, port_ua, + via->host, port_via); + + if ((memcmp(&addr_myself, &addr_via, sizeof(addr_myself))==0) && + (port_via == port_ua)) { + type=RESTYP_INCOMING; + break; + } + } + } + } + #endif ticket->direction=type; @@ -773,11 +841,19 @@ int proxy_response (sip_ticket_t *ticket) { * include my own as well. The local UA will probably send its answer * to the topmost Route Header (8.1.2 of RFC3261) */ - if ((type == RESTYP_INCOMING) && - (response->record_routes) && + if ((response->record_routes) && (!osip_list_eol(response->record_routes, 0))) { - DEBUGC(DBCLASS_PROXY,"Adding my Record-Route"); - route_add_recordroute(ticket); + if (type == RESTYP_INCOMING) { + DEBUGC(DBCLASS_PROXY,"Adding my Record-Route"); + route_add_recordroute(ticket); + } else { + /* + * outgoing packets must not have a record route header, as + * these likely will contain private IP addresses. + */ + DEBUGC(DBCLASS_PROXY,"Purging Record-Routes (outgoing packet)"); + route_purge_recordroute(ticket); + } } /* diff --git a/src/route_processing.c b/src/route_processing.c index 09f79db..f162792 100644 --- a/src/route_processing.c +++ b/src/route_processing.c @@ -71,7 +71,7 @@ int route_preprocess(sip_ticket_t *ticket){ * header is existing at all). If so, remove it from the list and * rewrite the request URI to point to the now topmost Route. */ - if (mymsg->routes && !osip_list_eol(mymsg->routes, 0)) { + if (mymsg->routes && (osip_list_size(mymsg->routes)>0)) { last=osip_list_size(mymsg->routes)-1; /* * I have seen that some (all?) UAs do set a Route: header @@ -90,6 +90,9 @@ int route_preprocess(sip_ticket_t *ticket){ DEBUGC(DBCLASS_PROXY, "route_preprocess: checking Route " "header[%i]", i); route = (osip_route_t *) osip_list_get(mymsg->routes, i); + if (route == NULL) continue; + if (route->url == NULL) continue; + if (route->url->host == NULL) continue; sts = get_ip_by_host(route->url->host, &addr1); if (get_ip_by_ifname(configuration.inbound_if, &addr2) != STS_SUCCESS) { @@ -255,8 +258,7 @@ int route_add_recordroute(sip_ticket_t *ticket){ /* insert before all other record-route */ osip_list_add (mymsg->record_routes, r_route, 0); } else { - osip_record_route_free (r_route); - osip_free (r_route); + osip_record_route_free(r_route); } /* if url_init */ } /* if record route init */ @@ -265,6 +267,30 @@ int route_add_recordroute(sip_ticket_t *ticket){ } +/* + * PROXY_PURGE_RECORDROUTE + * + * Purge all Record-route headers + * + * RETURNS + * STS_SUCCESS on success + */ +int route_purge_recordroute(sip_ticket_t *ticket){ + osip_message_t *mymsg=ticket->sipmsg; + osip_record_route_t *r_route=NULL; + + if (mymsg->record_routes && !osip_list_eol(mymsg->record_routes, 0)) { + while (!osip_list_eol(mymsg->record_routes, 0)) { + r_route = (osip_record_route_t *) osip_list_get(mymsg->record_routes, 0); + osip_list_remove(mymsg->record_routes, 0); + osip_record_route_free(r_route); + /* mymsg->record_routes will be freed by osip_message_free() */ + } + } + return STS_SUCCESS; +} + + /* * PROXY_DETERMINE_NEXT_HOP * @@ -287,7 +313,6 @@ int route_determine_nexthop(sip_ticket_t *ticket, * the SIP URI to point to the destination of the route (NOT IMPLEMENTED) */ if (mymsg->routes && !osip_list_eol(mymsg->routes, 0)) { - route = (osip_route_t *) osip_list_get(mymsg->routes, 0); /* get the destination from the Route Header */ route = (osip_route_t *) osip_list_get(mymsg->routes, 0); diff --git a/src/sip_utils.c b/src/sip_utils.c index 4240600..00f73bb 100644 --- a/src/sip_utils.c +++ b/src/sip_utils.c @@ -128,12 +128,10 @@ int check_vialoop (sip_ticket_t *ticket) { From that point of view, siproxd *should* not try to check against it's local IF addresses if they are private. this then of course again can lead to a endless loop... - -> Use a fixed unique part of branch parameter to identify that it - is MY via - - can we use something like a Tag in via headers?? (a veriy likely - to-be-unique ID) + -> Might use a fixed unique part of branch parameter to identify + that it is MY via + */ osip_message_t *my_msg=ticket->sipmsg; int sts; diff --git a/src/siproxd.h b/src/siproxd.h index cb2d457..79a61e9 100644 --- a/src/siproxd.h +++ b/src/siproxd.h @@ -133,6 +133,7 @@ int proxy_rewrite_request_uri(osip_message_t *mymsg, int idx); /*X*/ /* route_preprocessing.c */ int route_preprocess(sip_ticket_t *ticket); /*X*/ int route_add_recordroute(sip_ticket_t *ticket); /*X*/ +int route_purge_recordroute(sip_ticket_t *ticket); /*X*/ int route_postprocess(sip_ticket_t *ticket); /*X*/ int route_determine_nexthop(sip_ticket_t *ticket, struct in_addr *dest, int *port); /*X*/