[Serusers] Some questions on "loose_route"

Jan Janak jan at iptel.org
Sat Jan 3 19:05:25 CET 2004


On 02-01 14:46, Franz Edler wrote:
> Hi all again,
> 
> from various examples in the SER admin_guide and my own SIP knowledge-base I
> conclude, that the action "loose-route()" is responsible for correct routing
> of those requests, that are not destined to the proxy (host of Request-URI
> is not the proxy) and that have a proper Route-header indicating
> "loose-routing".

  Not really. loose_route() implements record routing. Because it must
  be backwards compatible with strict routers, it implements both, loose
  routing and strict routing.

  It should process all messages that contain Route header fields, even
  those that have hostname or IP of the proxy in Request-URI (it can
  happen).

  You should call loose_route() on every message unless you know what
  you are really doing.

> As such the action "loose_route()" should be sufficient to modify the
> Request in such a way, that the following action "t-relay()" finishes
> processing of the request. Therefore the action short sequence 
> 	... if (loose_route()) { t_relay(); break; };
> does all, what is necessary for loose routing of those requests.

  I think that this one deserves some explanation. The reason why 

  if (loose_route()) {
      t_relay();
  }

  is needed and why just loose_route(); is not sufficient is as follows:

  In some situations, SER needs to insert two Route header fields -- we
  call this double record-routing. It is necessary, for example, when a
  request comes over UDP and ser sends it over TCP. Suppose the
  following situation:

  A -- UDP -- SER -- TCP -- B

  A sends a SIP message over UDP to ser and ser forwards the message
  over TCP to B. Later if B sends a message within dialog, you usually
  want it to go the same way -- that means it should be sent over TCP to
  ser and ser forwards it over UDP to be.

  To achieve this, ser needs to add two Record-Route header fields, one
  with UDP transport and one with TCP transport, they will look like
  this:

  Record-Route: <sip:ser at 1.2.3.4;r2;transport=TCP>
  Record-Route: <sip:ser at 1.2.3.4;r2>

  (the only difference is in the parameters). Client B sees the "TCP"
  Record-Route first and sends the further messages over TCP. Client A
  reverses the order of the header fields and sees the "UDP" Route
  first.

  Because the ser in the middle created both headers, it also has to
  remove both resulting Route header fields. That's what r2 parameter is
  for -- it tells ser that another Route header field follows and it should
  be removed as well.

  Unfortunately there are broken implementations in the wild that strip
  parameters that they don't know -- in this case the r2 parameter. ser
  will not remove the 2nd Route if the parameter is missing, instead it
  would forward the message to it. In some cases it doesn't harm -- the
  message will just spiral through the same proxy one more time.

  Now the tough part -- in some cases it does harm -- for example when
  there are some strict routers along the path. In this case the message
  would contain the IP address of ser in the Request-URI (from the 2nd
  Route).

  In most config files, loose_route() is usually followed by a condition
  like this:

  if (uri==myself)

  and that condition would match (because there is the IP of ser in the
  Request-URI). That's wrong, because mid-dialog requests should
  not be processed in this part of script.

  loose_route() returns true in this case and you must make sure that
  if (uri==myself) is not reached.

  That's the reason why t_relay() is called inside the condition --
  message contained Route headers and shouldn't be processed by the script.
  
> My problem is, that I could not produce a condition, where "loose_route()"
> evaluates to true, so that the action block { t_relay(); break; } is
> executed. I expect, that in a simple call-scenario with one record-routing
> SIP proxy (SER) the routing of the ACK- and the BYE-method should trigger
> the above mentioned "loose_route()" action. But unfortunately it does not.
> Why?

  See above, this condition is a sort of safety net and normaly it is not
  triggered.

  You should have t_relay(); at the end of your script which will take
  care of all other record-routed requests. See the default config file
  for more details.

    Jan.




More information about the sr-users mailing list