[Serusers] no audio if clients are behind different nat

Alexander Philipp Lintenhofer lintenhofer at aon.at
Mon Jan 31 18:23:44 CET 2005


Ashling O'Driscoll schrieb:

> Hi,
>
> I have the exact same problem as described in the below email which I
> found on the serusers mailing archives. That is clients behind the
> same nat can ring each other and transmit audio but if a client tries
> to ring a client behind another nat no audio is transmitted.
> According to the below email this is because the sdp is not rewritten
> correctly. The below solution mentions calling force_rtpproxy but
> that function is called in the original config (see below)...Is there
> a specific plce that it should be invoked?
>
> Thank you,
> Aisling.
>
> You have to call force_rtpproxy -> this will rewrite the IP address
> and port with the one of the rtpproxy.
>
> klaus
>
> Sun Yen-Rong (Dan) wrote:
>
>  
>
>> Hi Klaus,
>> Firstly, thanks for your help. I used ethereal to capture the SIP
>> messages, and found out that the SDP in the forwarded INIVITE and
>>   
>
> 200 OK
>  
>
>> message are not rewritten correctly. As a result, the client with a
>> public IP address is sending RTP packets to the private IP address
>>   
>
> of
>  
>
>> the other client who is behind a NAT. One seruser suggested me to
>>   
>
> use
>  
>
>> fix_nated_sdp("3") instead of fix_nated_sdp("1"), however, it didn't
>> solve my problem. Do I also need to add a parameter to other
>>   
>
> nathelper
>  
>
>> functions as well?
>>
>> Regards,
>> Dan.
>>
>>
>> -----Original Message-----
>> From: Klaus Darilion [mailto:klaus.mailinglists at pernau.at] Sent: 
>> Thursday, May 06, 2004 9:45 PM
>> To: Sun Yen-Rong (Dan)
>> Cc: serusers at iptel.org
>> Subject: Re: [Serusers] no audio problem if clients behind NATs
>>
>> use a packet sniffer (ethereal or ngrep) and watch the SIP messages
>>   
>
> at  
>
>> the SIP proxy. Take a look at the sdp in the forwarded INVITE and
>>   
>
> 200 OK
>  
>
>> message and verify that the IP address and port in the SDP are
>>   
>
> rewritten
>  
>
>> correctly and points to the rtpproxy.
>>
>> regards,
>> klaus
>>
>> Sun Yen-Rong (Dan) wrote:
>>
>>
>>   
>>
>>> Hi all,
>>>
>>> I am using ser 0.8.12 with nathelper and rtpproxy. When I tried to
>>>     
>>
>> make
>>
>>   
>>
>>> a call between two clients which are behind the same NAT, everything
>>> work fine. However, when I try to make a call between clients which
>>>     
>>
>> are
>>
>>   
>>
>>> behind different NATs, niether client can hear each other's audio.
>>>     
>>
> my
>  
>
>>> configuration file is shown in the end of this message. Can someone
>>>     
>>
>> help
>>
>>   
>>
>>> me, please?
>>>
>>> Thanks,
>>>
>>> Dan.
>>>
>>> #
>>> # $Id: nathelper.cfg,v 1.1.2.1 2003/11/24 14:47:18 janakj Exp $
>>> #
>>> # simple quick-start config script including nathelper support
>>>
>>> # This default script includes nathelper support. To make it work
>>> # you will also have to install Maxim's RTP proxy. The proxy is
>>>     
>>
>> enforced
>>
>>   
>>
>>> # if one of the parties is behind a NAT.
>>> #
>>> # If you have an endpoing in the public internet which is known to
>>> # support symmetric RTP (Cisco PSTN gateway or voicemail, for
>>>     
>>
>> example),
>>
>>   
>>
>>> # then you don't have to force RTP proxy. If you don't want to
>>>     
>>
> enforce
>  
>
>>> # RTP proxy for some destinations than simply use t_relay() instead
>>>     
>>
> of
>  
>
>>> # route(1)
>>> #
>>> # Sections marked with !! Nathelper contain modifications for
>>>     
>>
>> nathelper
>>
>>   
>>
>>> #
>>> # NOTE !! This config is EXPERIMENTAL !
>>> #
>>> # ----------- global configuration parameters
>>>     
>>
> ------------------------
>  
>
>>> debug=3         # debug level (cmd line: -dddddddddd)
>>> fork=yes
>>> log_stderror=no    # (cmd line: -E)
>>>
>>> check_via=no    # (cmd. line: -v)
>>> dns=no           # (cmd. line: -r)
>>> rev_dns=no      # (cmd. line: -R)
>>> port=5060
>>> children=4
>>> fifo="/tmp/ser_fifo"
>>>
>>> # ------------------ module loading
>>>     
>>
> ----------------------------------
>  
>
>>> ",#
>>> # $Id: nathelper.cfg,v 1.2 2003/04/15 20:35:29 jiri Exp $
>>> #
>>> # example script showing use of nathelper module # (incomplete for 
>>> sake of brevity)
>>> #
>>>
>>> # ----------- global configuration parameters
>>>     
>>
> ------------------------
>  
>
>>> # ------------------ module loading
>>>     
>>
> ----------------------------------
>  
>
>>> loadmodule "/usr/local/lib/ser/modules/sl.so"
>>> loadmodule "/usr/local/lib/ser/modules/tm.so"
>>> loadmodule "/usr/local/lib/ser/modules/rr.so"
>>> loadmodule "/usr/local/lib/ser/modules/maxfwd.so"
>>> loadmodule "/usr/local/lib/ser/modules/usrloc.so"
>>> loadmodule "/usr/local/lib/ser/modules/registrar.so"
>>> loadmodule "/usr/local/lib/ser/modules/textops.so"
>>>
>>> # !! Nathelper
>>> loadmodule "/usr/local/lib/ser/modules/nathelper.so"
>>>
>>> # ----------------- setting module-specific parameters
>>>     
>>
> ---------------
>  
>
>>> # -- usrloc params --
>>>
>>> modparam("usrloc", "db_mode",   0)
>>>
>>> # -- rr params --
>>> # add value to ;lr param to make some broken UAs happy
>>> 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
>>>
>>> # -------------------------  request routing logic
>>>     
>>
> -------------------
>  
>
>>> # 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
>>>
>>>         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") {
>>>                 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 the request is for other domain use UsrLoc
>>>     # (in case, it does not work, use the following command
>>>     # with proper names and addresses in it)
>>>     if (uri==myself) {
>>>
>>>         if (method=="REGISTER") {
>>>
>>> # Uncomment this if you want to use digest authentication
>>> #            if (!www_authorize("iptel.org", "subscriber")) {
>>> #                www_challenge("iptel.org", "0");
>>> #                break;
>>> #            };
>>>
>>>             save("location");
>>>             break;
>>>         };
>>>
>>>         lookup("aliases");
>>>         if (!uri==myself) {
>>>             append_hf("P-hint: outbound alias\r\n");             
>>> route(1);
>>>             break;
>>>         };
>>>
>>>         # native SIP destinations are handled using our USRLOC
>>>     
>>
>> DB
>>
>>   
>>
>>>         if (!lookup("location")) {
>>>             sl_send_reply("404", "Not Found");
>>>             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)) {
>>>         force_rtp_proxy();
>>>     };
>>>
>>>     # NAT processing of replies; apply to all transactions (for
>>>     
>>
>> example,
>>
>>   
>>
>>>     # re-INVITEs from public to private UA are hard to identify as
>>>     # NATed at the moment of request processing); look at replies
>>>     t_on_reply("1");
>>>
>>>     # send it out now; use stateful forwarding as it works reliably
>>>     # even for UDP2TCP
>>>     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();
>>>   };
>>> }
>>>     
>>
>
>
>
> -------------------Legal  
> Disclaimer---------------------------------------
>
> The above electronic mail transmission is confidential and intended 
> only for the person to whom it is addressed. Its contents may be 
> protected by legal and/or professional privilege. Should it be 
> received by you in error please contact the sender at the above quoted 
> email address. Any unauthorised form of reproduction of this message 
> is strictly prohibited. The Institute does not guarantee the security 
> of any information electronically transmitted and is not liable if the 
> information contained in this communication is not a proper and 
> complete record of the message as transmitted by the sender nor for 
> any delay in its receipt.
>
> _______________________________________________
> Serusers mailing list
> serusers at lists.iptel.org
> http://lists.iptel.org/mailman/listinfo/serusers
>
>  
>
If it is not symmetric NAT, try to ask a STUN Server outside in the 
internet. You just need a client which supports STUN (and it works)! The 
clients learn about the NAT (kind of NAT and outbound address) and 
change their SDP therefore. A good software choice is XTen lite. A STUN 
Server is at sip.technikum-wien.at (Ports 3478, 3479)

regards,
Philipp





More information about the sr-users mailing list