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

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


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)

I've not followed the thread, but I think this could work:

	#incoming call
	# step 1
	write src_ip $si to AVP
	lookup("location");
	# step 2
	write destination IP $dd into AVP
	compare AVPs
	if AVP1!=AVP2 && natflag {use rtpproxy}

I think this should work as long as there is only one client registered. 
If there are multiple branches, step 2 must be done in the branch route.

klaus


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