[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 sr-users
mailing list