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

Tavis P tavis.lists at galaxytelecom.net
Mon Dec 5 22:10:11 CET 2005


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 Users mailing list