[OpenSER-Devel] [ openser-Bugs-1943833 ] recover from previous strict routing triggered incorrectly?

SourceForge.net noreply at sourceforge.net
Wed Apr 23 16:07:14 CEST 2008


Bugs item #1943833, was opened at 2008-04-16 14:06
Message generated for change (Settings changed) made by bogdan_iancu
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=743020&aid=1943833&group_id=139143

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: modules
Group: ver 1.3.x
Status: Open
Resolution: None
Priority: 5
Private: No
Submitted By: Andrew Pogrebennyk (apogrebennyk)
>Assigned to: Bogdan-Andrei Iancu (bogdan_iancu)
Summary: recover from previous strict routing triggered incorrectly?

Initial Comment:
Hi,

I am trying to create openser configuration for proxy that connects private (VPN) network with public network. I started with a config similar to http://voipembedded.com/resources/openser_cr.cfg, added a call to force_send_socket() rtpproxy to send from public IP and rtpproxy/nathelper in bridge mode. As per config loose_route() is called from openser.cfg to route a sequential request within a dialog through record-routing. 
Now when a BYE from callee comes in, it contains two Route headers: Route: <a.b.c.d;r2=on;lr;ftag=...> where a.b.c.d is server's public IP, Route: <10.0.0.100;r2=on;lr;ftag=...> where 10.0.0.100 is a private IP and username at a.b.c.d in Request-URI.

Take a look at loose_route():

/*
 * Do loose routing as defined in RFC3261
 */
int loose_route(struct sip_msg* _m, char* _s1, char* _s2)
{
    int ret;

    if (find_first_route(_m) != 0) {
        LM_DBG("There is no Route HF\n");
        return -1;
    }
       
    if (parse_sip_msg_uri(_m)<0) {
        LM_ERR("failed to parse Request URI\n");
        return -1;
    }

    ret = is_preloaded(_m);
    if (ret < 0) {
        return -1;
    } else if (ret == 1) {
        return after_loose(_m, 1);
    } else {
#ifdef ENABLE_USER_CHECK
        if (is_myself(&_m->parsed_uri.user, &_m->parsed_uri.host,
        _m->parsed_uri.port_no)) {
#else
        if (is_myself(&_m->parsed_uri.host, _m->parsed_uri.port_no)) {
#endif
            return after_strict(_m);
        } else {
            return after_loose(_m, 0);
        }
    }
} 

Obviously, is_myself() check passes and after_strict() is called.

when after_strict() is called, it looks if the URI given in Route contains lr parameter which marks loose routers, if so this block of code is executed:
    {
        LM_DBG("Next hop: '%.*s' is loose router\n",
            uri.len, ZSW(uri.s));

        if(get_maddr_uri(&uri, &puri)!=0) {
            LM_ERR("failed to check maddr\n");
            return RR_ERROR;
        }
        if (set_dst_uri(_m, &uri) < 0) {
            LM_ERR("failed to set dst_uri\n");
            return RR_ERROR;
        }

        /* Next hop is a loose router - Which means that is is not endpoint yet
         * In This case we have to recover from previous strict routing, that
         * means we have to find the last Route URI and put in in R-URI and
         * remove the last Route URI. */
        if (rt != hdr->parsed) {
            /* There is a previous route uri which was 2nd uri of mine
             * and must be removed here */
            rem_off = hdr->body.s;
            rem_len = rt->nameaddr.name.s - hdr->body.s;
            if (!del_lump(_m, rem_off - _m->buf, rem_len, 0)) {
                LM_ERR("failed to remove Route HF\n");
                return RR_ERROR;
            }
        }


        res = find_rem_target(_m, &hdr, &rt, &prev);
        if (res < 0) {
            LM_ERR("searching for last Route URI failed\n");
            return RR_ERROR;
        } else if (res > 0) {
            /* No remote target is an error */
            return RR_ERROR;
        }

        uri = rt->nameaddr.uri;
        if(get_maddr_uri(&uri, 0)!=0) {
            LM_ERR("checking maddr failed\n");
            return RR_ERROR;
        }
        if (rewrite_uri(_m, &uri) < 0) {
            LM_ERR("failed to rewrite R-URI\n");
            return RR_ERROR;
        }

        /* The first character if uri will be either '<' when it is the
         * only URI in a Route header field or ',' if there is more than
         * one URI in the header field */
        LM_DBG("The last route URI: '%.*s'\n", rt->nameaddr.uri.len,
                ZSW(rt->nameaddr.uri.s));

        if (prev) {
            rem_off = prev->nameaddr.name.s + prev->len;
            rem_len = rt->nameaddr.name.s + rt->len - rem_off;
        } else {
            rem_off = hdr->name.s;
            rem_len = hdr->len;
        }
        if (!del_lump(_m, rem_off - _m->buf, rem_len, 0)) {
            LM_ERR("failed to remove Route HF\n");
            return RR_ERROR;
        }
    } 

Therefore recover from previous strict routing is triggered: contents of request line is destroyed and 10.0.0.100 is put instead:
Apr 15 16:16:24 vpn-proxy oser[11027]: DBG:core:rewrite_uri: rewriting Request-URI with 'sip:10.0.0.100;r2=on;lr;ftag=aa40c2a5-54fb-1810-970d-0015c5bf2da5'
Apr 15 16:16:24 vpn-proxy oser[11032]: [1] Got in dialog request not catched by loose_route(): BYE sip:10.0.0.100;r2=on;lr;ftag=aa40c2a5-54fb-1810-970d-0015c5bf2da5 SIP/2.0^M Via:... 

And we respond with 404 to in-dialog requests not catched by loose_route(). Please advice what should I do to solve this problem. Perhaps loose_route() should not call after_strict() in case of double record-routing? 

Thank you,
Andrew Pogrebennyk

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=743020&aid=1943833&group_id=139143



More information about the Devel mailing list