[Serusers] NATHelper + usrloc (+ rtpproxy?)

Greger V. Teigre greger at teigre.com
Fri Nov 19 13:21:21 CET 2004


Hi Matt,
When a non-NATed incoming call to a NATed client is processed (INVITE), you
must make sure that you have a  t_on_reply("1"); before you call t_relay (or
forward).  The INVITE will not be detected as behind a NAT, but the
destination is (flag is set), and the reply will take care of the rewrite.
    In your config, it looks like you call t_relay before setting
t_on_reply("1"); further down.  A forward will only forward the SIP INVITE
to another SIP proxy for processing.
    Paul (Java Rockx) just recently posted his config file with a working
NAThelper/RTPproxy setup. I suggest you look at the call logic found there.
His config is also easy to read with a lot of nice headers
    I haven't tested RTP proxy between a client behind NAT and Asterisk, but
I believe that as long as you record-route the INVITE (as you do) and handle
the replies properly, it should work.
g-)

> Matt Schulte wrote:
>> Another note to this, I moved my 'forward' and lookup statements down
>> below the t_onreply statement. I figured this should allow ser to see
>> that the client is in fact behind a NAT. It catches that now however
>> I see this in my debug (ser):
>>
>> ser[21770]: transaction was sent to a NATED client -> fix nated
>> contact ser[21770]: ERROR: on_reply processing failed
>>
>> Could the last error be a/the problem? Come on I know someone else
>> has had this problem. Please help!
>> NOTE: I just tested this out on Asterisk (as a client behind NAT) and
>> got the same results. It's simply not changing the RTP IP address..
>>
>> --snippet--
>>
>> onreply_route[1] {
>>     # NATed transaction ?
>>     if (isflagset(6) && status =~ "(183)|2[0-9][0-9]") {
>>         log(1, "transaction was sent to a NATED client -> fix nated
>> contact\n");
>>         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();
>>     };
>>
>>
>> -----Original Message-----
>> From: Matt Schulte
>> Sent: Thursday, November 18, 2004 8:09 AM
>> To: serusers at lists.iptel.org
>> Subject: [Serusers] NATHelper + usrloc (+ rtpproxy?)
>>
>>
>> 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();
>>     };
>> }
>>
>> _______________________________________________
>> Serusers mailing list
>> serusers at lists.iptel.org http://lists.iptel.org/mailman/listinfo/serusers 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/gif
Size: 93 bytes
Desc: not available
URL: <http://lists.sip-router.org/pipermail/sr-users/attachments/20041119/e47ad337/attachment.gif>


More information about the sr-users mailing list