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

Norman Brandinger norm at goes.com
Mon Dec 5 22:59:41 CET 2005


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 ?

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
>>
>>
>>  
>>
>>     
>
>
>
>   





More information about the sr-users mailing list