[Devel] loose_route() incorrectly strict routing locally forwarded messages

Bogdan-Andrei Iancu bogdan at voice-system.ro
Thu Apr 13 11:13:03 CEST 2006


Hi Tavis,

thanks for the debugging. I think the best solution will be to have a 
port set all the time in the alias structure - if the alias definition 
does not contain a port, when inserting the alias use either the value 
of "port=" or the default 5060 if no general port is defined.

the grep_aliases function will not be changed at all.

Does it sound logic to you?

regards,
bogdan

Tavis P wrote:

>I've found the bug, it lies in the "grep_aliases" function inside
>/name_alias.h
>
>The if statement inside of the for loop will always return true when the
>IP address and the protocol are same but the port is different because
>it is comparing the port of the Route header to the port of the alias
>definition (which, when left out is "0")
>
>What it should be doing is comparing the port of the Route: header to
>that specified by the "port=..." directive as the ports in the
>"alias=..." directives are essentially noops, so its a bit unintuitive
>
>Now the easy workaround is to include the port in all "alias=..." (eg,
>"alias=127.0.0.1:15061") statements, which should be documented for the
>few that will actually need the functionality. 
>Otherwise the grep_aliases function (or some other function, since it
>does do what what is says it does well (grep aliases =D)) will have to
>be modified to check the port against the port specified by the "port="
>directive (since that is the only port that openser will listen on
>anyways, any specified in the alias directives will never be true if
>they are different from that of port=
>
>Example code: (comments added by me)
>----
>if (
>  (a->alias.len==len) &&
>/* This line is essentially flawed in that it is comparing the Route:
>address port to that specified in the "alias=" declaration, and NOT that
>specified with the "port=" declaration.
>(a->port==0) will always return true unless the port was added to the
>alias= declaration
>*/
>  ( (a->port==0) || (port==0) || (a->port==port) ) &&
>  ( (a->proto==0) || (proto==0) || (a->proto==proto) ) &&
>  ( strncasecmp(a->alias.s, name, len)==0 )
>)
>return 1; /* Indicate that the "Route:" header address is us, triggering
>strict routing semantics in "loose_route()" openser function
>
>
>tavis
>
>Tavis P wrote:
>  
>
>>I was thinking the same thing, although it struck me as odd that the
>>check still failed even though there is code in place to also check the
>>destination port vs the local port, perhaps that is where the problem lays?
>>
>>The message contains a Route: header that has the local external ip
>>address of the server as the host so removing the "alias=127.0.0.1" was
>>not effective
>>
>>I'm not much of a C programmer, but if the problem lies simply in the
>>port check then perhaps i'll have some luck in tracking it down
>>
>>
>>Bogdan-Andrei Iancu wrote:
>>  
>>    
>>
>>>Hi Tavis,
>>>
>>>the loose_route() function use the an internal function check_myself()
>>>(similar to ==myself in cfg) to see if it's strict or loose route.
>>>
>>>my guess is that the function sees the asterisk address
>>>(127.0.0.1:5080) as a local one. try to remove the alias from your cfg.
>>>
>>>regards,
>>>bogdan
>>>
>>>Tavis P wrote:
>>>
>>>    
>>>      
>>>
>>>>I've been having a problem where ACK and BYE messages that are being
>>>>forwarded to another port on the local machine (where asterisk is
>>>>running for example) are being incorrectly handled by loose_route().
>>>>It seems to think it needs to use strict routing semantics (replacing
>>>>the RURI with that of the Route: header field value) however the message
>>>>is not structured to be strict routed so it causes local looping
>>>>problems.
>>>>
>>>>Using the same UA but altering the routing slightly such that the messge
>>>>is sent to a non-local different ip address (in which case the ACK/BYE
>>>>is of the same structure but has a different destination and tags/flags,
>>>>etc)) the loose_route() function properly classifies the ACK/BYE as
>>>>needing to be loose routed and everything works as expected
>>>>
>>>>Attached is a stripped down openser config file that will exhibit the
>>>>problem i've encountered
>>>>The following lines will need modification:
>>>>- "seturi("sip:400 at 127.0.0.1:5080");"   - you will need to have some
>>>>local application (could be another openser that simply responds "200
>>>>OK"!) that will listen on another port locally
>>>>- "#seturi("sip:400 at some.other.system");"   - change to
>>>>some.other.system to some external system that will accept an INVITE and
>>>>initiate a dialog
>>>>
>>>>
>>>>Initially the script will route the call to the local host and you will
>>>>see in the log that loose_route() will treat the message using strict
>>>>route semantics even though the message does not classify
>>>>afterwards you can comment out the first seturi() command and uncomment
>>>>the second seturi command, make the same phone call and see that
>>>>loose_route() will properly classify the ACK and BYE messages
>>>>
>>>>
>>>>This was tested on the latest version of openser 1.0.0 stable checked
>>>>out of CVS on Friday April 7, 2006
>>>>UACs tested with this configuration: (All of which do not do strict
>>>>routing)
>>>>Cisco 7960 W/Voice Software 7.5
>>>>Sipura SPA2100 W/Firmware 3.2.5d
>>>>Xlite 1105d
>>>>
>>>>
>>>>I've stored pcap and openser debug (level 99) traces of each situation
>>>>(local forward and external forward), they are available on request
>>>>
>>>>
>>>>thanks!
>>>> 
>>>>
>>>>      
>>>>        
>>>>
>>>    
>>>      
>>>
>>_______________________________________________
>>Devel mailing list
>>Devel at openser.org
>>http://openser.org/cgi-bin/mailman/listinfo/devel
>>
>>
>>  
>>    
>>
>
>  
>




More information about the Devel mailing list