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

Klaus Darilion klaus.mailinglists at pernau.at
Tue Dec 6 09:29:28 CET 2005


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