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

Tavis P tavis.lists at galaxytelecom.net
Wed May 3 02:10:24 CEST 2006

I've encountered some problems with the suggested workarounds, when the
alias' are set to include the server port there seems to be some
problems with the tm module "missing" (not realizing they are meant for
itself) some messages and forwarding them instead.

I havn't had the time to debug this observation properly, i'm hoping to
be able too in the coming weeks.  I think right now forwarding messages
to another port on the same server is very broken.  I'll a little
disclaimer in the wiki section on alias

Bogdan-Andrei Iancu wrote:
> Hi Tavi,
> I gave more thinking on the issues, and as you said, is more a problem
> of logic than programming. I would say the best solution is to let the
> code as it is, as it offer more flexibility, and to document better
> the "alias" behaviour to avoid future misunderstandings.
> What changed my mind? here is an example:  you have the proxy
> listening on udp and tcp on 2 ports; and it serves the domain
> "mysip.net"...if we change the code, we will have to strictly define
> the aliases (all proto and port combination -> 4 entries) to be sure
> your domain also covers the 2 protos and ports...and it's not natural.
> So, I will add more info in the wiki page for "aliases"....is it
> reasonable?
> regards,
> bogdan
> Tavis P wrote:
>> It is a good intern solution, adding the port to the alias definition
>> works perfectly, although it may confuse some due to non obvious
>> behaviour.  I think its a problem better solved in head though
>> I've made a change to the OpenSER core_cookbook wiki, in the alias
>> heading to indicate that it may be necessary to add the port after all
>> alias definitions
>> tavis
>> Bogdan-Andrei Iancu wrote:
>>> 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=") 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=" 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
>>>>>> ( 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");"   - 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!

More information about the Devel mailing list