[Serusers] NATHelper + usrloc (+ rtpproxy?)

Matt Schulte mschulte at netlogic.net
Thu Nov 18 15:08:55 CET 2004


All,

	This is my first post to this list so go easy on me. :-) I'm
rather new to Ser, in fact I just installed it for the first time early
in the week. I'm working on the NAThelper module to get traversal
working, I have outbound (sip phone -> NATout -> ser) working just
peachy, RTP works in both directions hooray. The question is I'm having
problems getting RTP inbound, the ring of course goes through, and RTP
from the NAT'd side of course works fine however getting back through
the NAT (from outside) for RTP in this sense fails. Let me explain the
setup:

I'm using the registrar, NAThelper, usrloc, and of course (Portaone's)
RTPproxy modules. The current SIP phone is an SNOM (yes yes, I know..).
The "endpoint" is Asterisk. When I do a sip debug on Asterisk, I see the
RTP request however it's coming from the NAT'd fake address:

v=0
o=root 780961119 780961119 IN IP4 192.168.1.101
s=call
c=IN IP4 192.168.1.101
t=0 0
m=audio 10004 RTP/AVP 0
a=rtpmap:0 pcmu/8000
a=sendrecv


I have an idea of what to fix just not sure how to fix it. Obviously we
need it to goto RTPproxy, since this is "backwards" how would I get it
to recognize the correct IP?

See my config below, most of it is ripped off of the NAThelper.cfg
example. :-) Thanks all..

NOTE: All calls are destined for ${SIPDOMAIN}, in this case, the
machines hostname. This is normal and intentional :-)

# ---- SNIPPAGE ----
modparam("rr", "enable_full_lr", 1)

# !! Nathelper
modparam("registrar", "nat_flag", 6)
modparam("nathelper", "natping_interval", 30) # Ping interval 30 s
modparam("nathelper", "ping_nated_only", 1)   # Ping only clients behind
NAT
# main routing logic

route{

# initial sanity checks -- messages with
        # max_forwards==0, or excessively long requests
        if (!mf_process_maxfwd_header("10")) {
                sl_send_reply("483","Too Many Hops");
                break;
        };
        if (msg:len >=  max_len ) {
                sl_send_reply("513", "Message too big");
                break;
        };
        # !! Nathelper
        # Special handling for NATed clients; first, NAT test is
        # executed: it looks for via!=received and RFC1918 addresses
        # in Contact (may fail if line-folding is used); also,
        # the received test should, if completed, should check all
        # vias for rpesence of received
        if (nat_uac_test("3")) {
                # Allow RR-ed requests, as these may indicate that
                # a NAT-enabled proxy takes care of it; unless it is
                # a REGISTER
                log("LOG: Caught uac test 3 \n");
                if (method == "REGISTER" || ! search("^Record-Route:"))
{
                    log("LOG: Someone trying to register from private
IP, rewriting\n");

                    # This will work only for user agents that support
symmetric
                    # communication. We tested quite many of them and
majority is
                    # smart enough to be symmetric. In some phones it
takes a configuration
                    # option. With Cisco 7960, it is called
NAT_Enable=Yes, with kphone it is
                    # called "symmetric media" and "symmetric
signalling".

                    fix_nated_contact(); # Rewrite contact with source
IP of signalling
                    if (method == "INVITE") {
                        log("LOG: fix nated sdp\n");
                        fix_nated_sdp("1"); # Add direction=active to
SDP
                    };
                    force_rport(); # Add rport parameter to topmost Via
                    setflag(6);    # Mark as NATed
                };
        };

        # we record-route all messages -- to make sure that
        # subsequent messages will go through our proxy; that's
        # particularly good if upstream and downstream entities
        # use different transport protocol
        if (!method=="REGISTER") record_route();

        # subsequent messages withing a dialog should take the
        # path determined by record-routing
        if (loose_route()) {
                # mark routing logic in request
                append_hf("P-hint: rr-enforced\r\n");
                route(1);
                break;
        };

        if (!uri==myself) {
                # mark routing logic in request
                append_hf("P-hint: outbound\r\n");
                route(1);
                break;
        };


        if (uri==myself) {

                if (method=="REGISTER") {
                        log("LOG: Caught register, registering user in
local db\n");
                        save("location");
                        break;
                };

                lookup("aliases");
                if (!uri==myself) {
                        append_hf("P-hint: outbound alias\r\n");
                        route(1);
                        break;
                };
                log("LOG: Caught uri myself\n");
                # native SIP destinations are handled using our USRLOC
DB
                #if (!lookup("location")) {
                #       sl_send_reply("404", "Do what now");
                #       break;
                #};
        };
        append_hf("P-hint: usrloc applied\r\n");
        route(1);

}

route[1]
{
        # !! Nathelper
        if (uri=~"[@:](192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.)"
&& !search("^Route:")){
            sl_send_reply("479", "We don't forward to private IP
addresses");
            break;
        };
        # if client or server know to be behind a NAT, enable relay
        if (isflagset(6)) {
                log("LOG: Caught NAT flag 6 forcing rtp proxy\n");
            force_rtp_proxy();
        };
        if (method=="REGISTER") {
                break;
                log("LOG: Caught Register down in our call routing,
breaking\n");
        };

#### Below is mostly my own doing ####
        if (method=="INVITE")   {
                log("LOG: Caught INVITE \n");
                if (lookup("location")) {
                        log ("LOG: Caught registered invite, sending
there\n");
                        # NOTE forcing rtp maybe bad idea for ALL users,
this is
                        # a quick fix (which doesn't work anyway!)
                        #force_rtp_proxy();
                        #forward(uri:host, uri:port); #nor does this
                        t_relay();
                        break;
                } else if (uri=~"^sip:[0-9]*@") { # ... forward to
asterisk;
                        forward(xxx.xxx.xxx.xxx, 5060);
                        log("LOG: Tapping rowlf\n");
                        break;
                };
        };
#### ####
   
        t_on_reply("1");

        if (!t_relay()) {
                sl_reply_error();
        };
}

# !! Nathelper
onreply_route[1] {
    # NATed transaction ?
    if (isflagset(6) && status =~ "(183)|2[0-9][0-9]") {
        fix_nated_contact();
        force_rtp_proxy();
    # otherwise, is it a transaction behind a NAT and we did not
    # know at time of request processing ? (RFC1918 contacts)
    } else if (nat_uac_test("1")) {
        fix_nated_contact();
    };
}




More information about the sr-users mailing list