[Devel] [Users] nathelper/rtpproxy when both SIP UA are behind same NAT

Tavis P tavis.lists at galaxytelecom.net
Tue Dec 6 21:25:50 CET 2005


It works!

Thanks for the reference Klaus

Heres a config snippit:


        else if ( isflagset(2) and isflagset(3) )
        {
            log(1, "Both Clients are behind NAT");

            # Store the destination domain into an AVP
            avp_printf("i:450", "$dd");
       
            if ( avp_check("i:450", "eq/$src_ip/g") )
            {
                xlog("L_INFO", "Detected Two Clients Behind the Same NAT
- Disabling Mediaproxy");
           
                # Do not use mediaproxy as the clients seem to be behind
the same NAT
                resetflag(2);
                resetflag(3);
            }           
       
        }



Klaus Darilion wrote:

> Norman Brandinger wrote:
>
>> Yes,  you pretty much ended up at the same place I did.
>>
>> It appears that the value from the "received" column is what is needed.
>>
>> I guess the question is: "after a lookup(), is the "received" column
>> saved in a pseudo variable ?
>
>
> $du, $dd, $d....
>
> klaus
>
>>
>> Norm
>>
>>
>> Tavis P wrote:
>>
>>> Sorry my logic was bad, again
>>>
>>> It seems that its not really feasable to do media path optimization for
>>> clients that are behind the same nat currently (at least not with the
>>> approaches i've taken)
>>>
>>> The primary issue is that i can find no reliable way to access the
>>> external IP address of the callee ( maybe "received" information stored
>>> in Location Database?) when both clients are behind a NAT, if this was
>>> made available then it should be easy.  Somthing like:
>>>
>>>
>>>         # If both clients are behind nat we can check to see if they
>>> are
>>> behind the same
>>>         # external IP and optimize the media path to go directly
>>> between
>>> them
>>>         else if ( isflagset(2) and isflagset(3) )
>>>         {
>>>             log(1, "Both Clients are behind the same NAT");
>>>
>>>             avp_printf("i:450", "RECEIVED Header Field of Callee");
>>>             avp_subst("i:450", "/need to/extract only the IP from text
>>> string/");
>>>                    if ( avp_check("i:450", "eq/$src_ip/g") )
>>>             {
>>>                 log(1, "Both clients seem to be behind the same NAT,
>>> disabled mediaproxy use");
>>>                            # Do not use mediaproxy as the clients
>>> are behind the
>>> same NAT
>>>                 resetflag(2);
>>>                 resetflag(3);
>>>             }          Tavis P wrote:
>>>
>>>  
>>>
>>>> The one i posted before was for clients using STUN who are behind a
>>>> NAT
>>>> that does not support hairpinning (data directed from the internal ip
>>>> address of one client to the external ip address of the nat does
>>>> not map
>>>> to other internal clients) but the logic is similar for media
>>>> optimization of nat clients in the same network environment.
>>>>
>>>> I'm working on a little bit of script that i think could do it, the
>>>> first thing that you should check for is that the external IP
>>>> address is
>>>> the same (not using the script below as you've shown) and then
>>>> check of
>>>> the internal ip address is the same using avp_printf and then
>>>> avp_subst
>>>> to subtract the information from the SIP headers where it resides
>>>>
>>>> I'll post it later on today if i get some time
>>>>
>>>> Norman Brandinger wrote:
>>>>
>>>>  
>>>>
>>>>   
>>>>
>>>>> Hi Tavis,
>>>>>
>>>>> I tried your suggestion.
>>>>>
>>>>> First, thanks for the information about using avp_printf() to save a
>>>>> pseudo variable to an AVP.  Either I overlooked the doc in regard to
>>>>> this or there isn't any doc.  Do you know if it's documented ?  Seem
>>>>> to recall a comment about this on the mailing list a while ago...??
>>>>>
>>>>> It in my testing, $si = public IP address of the NAT Router which is
>>>>> what was expected.  However, $rd = the private IP of the callee.
>>>>> Unfortunately the private ip isn't useful.  A quick look at the
>>>>> location table shows that the private IP stored in the "contact"
>>>>> column.  It appears that the value from the "received" column is what
>>>>> is needed.  I guess the question is: "after a lookup(), is the
>>>>> "received" column saved in a pseudo variable ?
>>>>>
>>>>> Regards,
>>>>> Norm
>>>>>
>>>>>
>>>>> Tavis P wrote:
>>>>>
>>>>>       
>>>>>
>>>>>> actually, this would be better
>>>>>>
>>>>>>        avp_printf("i:401", "$rd");
>>>>>>               if ( avp_check("i:401", "eq/$src_ip/g") )
>>>>>>        {
>>>>>>            xlog("L_INFO", "\"$si\" == \"$rd\"  ");
>>>>>>        }
>>>>>>
>>>>>> Tavis P wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>>           
>>>>>>
>>>>>>> Opps i made a mistake, instead of "avp_write" you need to use
>>>>>>> "avp_printf" to store the pseudo variable into an AVP
>>>>>>> and when you are doing the comparison with avp_check you need an
>>>>>>> alias
>>>>>>> defined for the second AVP otherwise you might end up comparing
>>>>>>> the AVP
>>>>>>> with a literal value
>>>>>>>
>>>>>>>
>>>>>>>       modparam( "avpops", "avp_aliases", "dest_ip=i:401" )
>>>>>>>
>>>>>>>       avp_printf("i:400", "$si");
>>>>>>>       avp_printf("i:401", "$rd");
>>>>>>>
>>>>>>>       if ( avp_check("i:400", "eq/$dest_ip/g") )
>>>>>>>       {
>>>>>>>           xlog("L_INFO", "\"$si\" == \"$rd\"  ");
>>>>>>>       }
>>>>>>>
>>>>>>>
>>>>>>> Norman Brandinger wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>  
>>>>>>>               
>>>>>>>
>>>>>>>> I agree that the solution that was presented is BAD for the
>>>>>>>> reasons
>>>>>>>> stated by both of us and probably more :)
>>>>>>>>
>>>>>>>> Perhaps using $Ri after the successful lookup() and comparing
>>>>>>>> it to
>>>>>>>> the $src_ip AVP would work.
>>>>>>>>
>>>>>>>> The problem was trying to compare a pseudo variable with an AVP.
>>>>>>>>
>>>>>>>>
>>>>>>>> The doc <snipped below> does not state that pseudo variables
>>>>>>>> can be
>>>>>>>> used by avp_write().
>>>>>>>>
>>>>>>>> Pseudo-variables can be used with following modules of OpenSER:
>>>>>>>>
>>>>>>>> * avpops - function “avp_printf()”
>>>>>>>> * xlog - functions “xlog()” and “xdbg()”
>>>>>>>>
>>>>>>>> I did try to use avp_write() to save a pseudo variable to an
>>>>>>>> AVP but
>>>>>>>> was unsuccessful.
>>>>>>>>
>>>>>>>> Do you have an example of writing a pseudo variable to an AVP ?
>>>>>>>>
>>>>>>>> Regards,
>>>>>>>> Norm
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Tavis P wrote:
>>>>>>>>
>>>>>>>>  
>>>>>>>>                      
>>>>>>>>
>>>>>>>>> Another, more lightweight solution, is:
>>>>>>>>>
>>>>>>>>> After a successful lookup(location) you can compare the
>>>>>>>>> received IP
>>>>>>>>> address ($si) with the destination domain/ip address returned
>>>>>>>>> from
>>>>>>>>> the
>>>>>>>>> "lookup" function call ($rd), i think these two pieces of
>>>>>>>>> information
>>>>>>>>> are reliable for this purpose
>>>>>>>>>
>>>>>>>>> This way you don't have to make extra database calls to determine
>>>>>>>>> locality
>>>>>>>>>
>>>>>>>>> Also if you want to compare pseudo variables you can first write
>>>>>>>>> them to
>>>>>>>>> an AVP using "avp_write" and then you can make use of "avp_check"
>>>>>>>>> with
>>>>>>>>> data sourced from a pseudo variable
>>>>>>>>>
>>>>>>>>> Norman Brandinger wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>                               
>>>>>>>>>
>>>>>>>>>> I have looked into the problem related to saving saving
>>>>>>>>>> resources by
>>>>>>>>>> not calling rtpproxy or mediaproxy when both the caller and
>>>>>>>>>> callee are
>>>>>>>>>> behind the same NAT.
>>>>>>>>>>
>>>>>>>>>> This topic has been discussed many times however, there have
>>>>>>>>>> been no
>>>>>>>>>> "working" examples, or even partial examples posted (that I'm
>>>>>>>>>> aware
>>>>>>>>>> of).
>>>>>>>>>>
>>>>>>>>>> Below is a solution to the problem, but is a BAD hack at best.
>>>>>>>>>>
>>>>>>>>>> This solution is BAD because AVP's are added to the
>>>>>>>>>> usr_preferences
>>>>>>>>>> table during the registration process, but there is no
>>>>>>>>>> notification
>>>>>>>>>> that a registration has expired and is no longer valid.  A
>>>>>>>>>> cron job
>>>>>>>>>> could be run periodically to delete all received_ip AVP's
>>>>>>>>>> with no
>>>>>>>>>> matching entry in the location table, but this is another
>>>>>>>>>> hack to
>>>>>>>>>> fix
>>>>>>>>>> the first hack.
>>>>>>>>>>
>>>>>>>>>> The solution is BAD because a database calls must be made to
>>>>>>>>>> save
>>>>>>>>>> the
>>>>>>>>>> received_ip address into an AVP, then another database call
>>>>>>>>>> must be
>>>>>>>>>> made to reload the value just so that it can be tested
>>>>>>>>>> against the
>>>>>>>>>> caller's $src_ip.  A pseudo variable $Ri already exists that
>>>>>>>>>> contains
>>>>>>>>>> the value we use in received_ip, but I have not been able to
>>>>>>>>>> find a
>>>>>>>>>> way for avp_check() to use $Ri.
>>>>>>>>>>
>>>>>>>>>> The solution is BAD because it will fail when the SIP
>>>>>>>>>> device(s) are
>>>>>>>>>> behind more than a single NAT router.  I believe this is not an
>>>>>>>>>> issue
>>>>>>>>>> for 95% of the users and 99% of the small office or home users.
>>>>>>>>>>
>>>>>>>>>> I think that a better solution would be to enhance
>>>>>>>>>> avp_check() to
>>>>>>>>>> accept pseudo variables for the "value" parameter.  This would
>>>>>>>>>> remove
>>>>>>>>>> the need for any database calls.
>>>>>>>>>>
>>>>>>>>>> I'm cross-posting this response to the developers list to
>>>>>>>>>> bring this
>>>>>>>>>> to their attention and ask for suggestions (it's possible
>>>>>>>>>> that I've
>>>>>>>>>> totally missed something).  If a decision is made to open the
>>>>>>>>>> avpops
>>>>>>>>>> module to pseudo variables (other than just avp_print()), I
>>>>>>>>>> would
>>>>>>>>>> suggest the following be looked at:
>>>>>>>>>>
>>>>>>>>>> avp_check() the value parm should accept pseudo variables
>>>>>>>>>> avp_write() the value parm should accept pseudo variables
>>>>>>>>>> avp_pushto() the name parameter should accept pseudo variables
>>>>>>>>>> avp_op() the value parameter should accept pseudo variables
>>>>>>>>>>
>>>>>>>>>> Regards,
>>>>>>>>>> Norm
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> 1) During REGISTER processing, place the following code.  I
>>>>>>>>>> would
>>>>>>>>>> suggest that you put the code "after" all authentication
>>>>>>>>>> checks and
>>>>>>>>>> "after" the save("location") statement.
>>>>>>>>>>
>>>>>>>>>> # Delete any previously saved IP addressess from the user.
>>>>>>>>>> avp_db_delete("$from/username","s:received_ip");
>>>>>>>>>>
>>>>>>>>>> # Save the source IP address of the user into an AVP called
>>>>>>>>>> received_ip.
>>>>>>>>>> # The saved IP address should be the public address of the NAT
>>>>>>>>>> router.
>>>>>>>>>> avp_write("$src_ip", "s:received_ip");
>>>>>>>>>>
>>>>>>>>>> # Save the AVP received_ip into the usr_preferences tables
>>>>>>>>>> associated
>>>>>>>>>> with the user that just registered
>>>>>>>>>> avp_db_store("$from/username","s:received_ip");
>>>>>>>>>>
>>>>>>>>>> 2) During INVITE processing (or wherever you make the
>>>>>>>>>> decision to
>>>>>>>>>> use
>>>>>>>>>> or not use rtpproxy / mediaproxy) , place the following code.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> #---------------------------------------------------------------------------
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> # Are the caller and callee behind the same NAT ?
>>>>>>>>>>
>>>>>>>>>> #---------------------------------------------------------------------------
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> avp_db_load("$to/username", "s:received_ip");
>>>>>>>>>> if (avp_check("s:received_ip", "eq/$src_ip")) {
>>>>>>>>>>  setflag(CALLER_AND_CALLEE_ ARE_BEHIND_THE_SAME_NAT);
>>>>>>>>>> };
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> _______________________________________________
>>>>>>>>>> Devel mailing list
>>>>>>>>>> Devel at openser.org
>>>>>>>>>> http://openser.org/cgi-bin/mailman/listinfo/devel
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>                                              
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>                                   
>>>>>>>>
>>>>>>>>
>>>>>>>>  
>>>>>>>>                          
>>>>>>>
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> Users mailing list
>>>>>>> Users at openser.org
>>>>>>> http://openser.org/cgi-bin/mailman/listinfo/users
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>                    
>>>>>>
>>>>>>
>>>>>>  
>>>>>>             
>>>>>
>>>>>
>>>>>         
>>>>
>>>>
>>>> _______________________________________________
>>>> Users mailing list
>>>> Users at openser.org
>>>> http://openser.org/cgi-bin/mailman/listinfo/users
>>>>
>>>>
>>>>  
>>>>
>>>>     
>>>
>>>
>>>
>>>
>>>
>>>   
>>
>>
>>
>>
>> _______________________________________________
>> Users mailing list
>> Users at openser.org
>> http://openser.org/cgi-bin/mailman/listinfo/users
>>
>>
>
>





More information about the Users mailing list