Subject: Re: Record-Route and Route header clarification

From: John Hearty <[email-masked]>
Date: Tue, 27 Apr 1999 09:10 -0500 (CDT)

>As there was no Contact in the INVITE, shouldn't B omit A from its
>stored route, i.e. store the route SPS3,SPS1 and leave it to SPS1 to do
>the final routing to A?

 No, we can't leave it up to SPS1 to do the final routing to A.  We
need to specify it in the Route header to make sure SPS1 doesn't use
some other intermediate proxy to get to A.  If that were to happen,
based on the defined rules, there would be no route header, and such
an intermediate proxy could add a Record-Route header on the reverse
Invite from B.  Then A would not know if it should use the originally
stored route or build a new one.  Including the final destination as
the last element in a Route header is required to ensure messages take
the correct route all the way.

John Hearty
MCI Worldcom

Date: Tue, 27 Apr 1999 06:58 -0500 (CDT)
From: Anders Kristensen <[email-masked]>
Organization: HP Labs
To: "Donovan, Steven R." <[email-masked]>
CC: "[email-masked]'" <[email-masked]>
Sender: [email-masked]
Subject: Re: Record-Route and Route header clarification

> "Donovan, Steven R." wrote:
> 
> The purpose of the Record-Route and Route headers is to ensure that
> SIP requests for an established session and the ACK request resulting
> from the INVITE, 200 OK message pair get routed through interested
> proxy servers.  The correct routing needs to occur in both directions,
> both when the request comes from the calling user agent and when it
> comes from the called user agent.
> 

Nice explanation of the problem. I have one small question...

> 
> SCENARIO TWO (No contact included in INVITE message)
> ------------
> 
> User A        SPS1         SPS2         SPS3          B2
>    ------------>------------>------------>------------>
>    Invite SPS1  Invite SPS2  Invite SPS3  Invite B2
>    F:User A     F:User A     F:User A     F:User A
>    T:User B     T:User B     T:User B     T:User B
>    Q:1 INVITE   Q:1 INVITE   Q:1 INVITE   Q:1 INVITE
>    I:1@A        I:1@A        I:1@A        I:1@A
>                 RR:(SPS1)    RR:(SPS1)    RR:(SPS3,
>                                               SPS1)
> 
>   At this point User B will store the Route SPS3,SPS1,User A

As there was no Contact in the INVITE, shouldn't B omit A from its
stored route, i.e. store the route SPS3,SPS1 and leave it to SPS1 to do
the final routing to A?

-- 
Anders Kristensen <[email-masked]>,
http://www-uk.hpl.hp.com/people/ak/
Hewlett-Packard Labs, Bristol, UK

---

From: Anders Kristensen <[email-masked]>
Date: Tue, 27 Apr 1999 17:08:51 +0100

> the correct route all the way.

Actually, I'm not sure this is a valid argument, and the reason opens up
some questions about the way Route based routing works (or not works, as
it may be). Consider what happens at SPS1 when B has the "end-to-end"
path SPS3,SPS1,A stored. In this case SPS1 receives a request (from B
via SPS3) like:

INVITE SPS1
F:User A
T:User B
Q:2 INVITE
I:1@A
R:(User A)

The spec then says [6.33]:

   Each host removes the first entry and then proxies the
   request to the host listed in that entry, also using it as the
   Request-URI.

so SPS1 pops User A from the Route header and routes the request to User
A using User A as the request URI. I see nothing here that would prevent
the message to go via a proxy from SPS1 to A!  This is especially the
case when the final destination in the route was copied form the From
header of the initial INVITE because in this case the final item in the
Route is likely to be host-independent, but even in the case where it's
the value of a Contact header there is nothing in the spec (as far as I
can tell) that guarantees that routing according to this field will work
as intended.

IMHO this is a general problem with how Record-Route and Route are
defined. For example, suppose I'm a UA having the route

  <sip:[email-masked]>, <sip:[email-masked]>,
  <sip:[email-masked]>

associated with some call leg. Now I'm supposed to route an INVITE on
this leg to sip:[email-masked], but who says the standard routing
algorithm won't throw in a proxy between me and host bell-tel.com?  SIP
addresses and the resolution procedure are wonderfully flexible but in
the case of fixed routes this is unwanted.

Clearly (?), the intention of the spec is for each item in Record-Route
and Route headers to be host-dependent. As far as I can tell there is a
hidden assumption that each entity on a route has exactly one A DNS RR
associated with it and that routing is done on the basis of this A RR
and not, for example, on the basis of a SRV RR, as this might cause the
message NOT to go via the exact same network element that generated the
entry in first place.

One approach to this problem is to say that its the responsibility of
the entity inserting its own address on a Record-Route header to make
sure that this address is specific enough to ensure that this very same
element receives subsequent messages (if that's an absolute
requirement). So if ieee.org is served by more than one SIP server, each
of whose IP addresses are returned by an A DNS lookup, the SIP URL on a
Record-Route corresponding to one of these servers would have to have a
maddr attribute (as recommended by the spec anyway) or its host part
would be a dotted-decimal IP address.  Additionally, when routing is
based on the Route header, SIP entities should always use A lookups only
(mustn't use SRV for example), and only on the address as it appears in
the Route header.

This seems kind of serious. Did I miss something here?  Anyway, on the
initial question of whether B should include A in its stored route when
no Contact was present in A's initial INVITE I still believe the correct
answer is no.

---

From: Jonathan Rosenberg <[email-masked]>
Date: Tue, 27 Apr 1999 12:52:31 -0400

> the correct route all the way.

There are two separate issues here:

(1) changes in the routing after the original INVITE,
(2) making sure SPS1 can Route to A

For (2), the solution is not to Route based on From, but to make
inclusion of Contact mandatory in the INVITE, just as we have discussed
making it mandatory in the 200 OK.

For (1), I have come to the conclusion that you want to be able to
change the routing after the initial one is setup. This is useful for
terminal mobility through SIP, where the UAS or UAC re-INVITEs with a
new Contact header, to change the route to its new location. Allowing
the route to be updated also means that proxies can elect to "drop out"
of the call signaling path when they feel they are no longer useful. 

Thanks,
Jonathan R.

-- 
Jonathan D. Rosenberg                       Lucent Technologies
Member of Technical Staff                   101 Crawfords Corner Rd.
High Speed Networks Research                Holmdel, NJ 07733
FAX:   (732) 834-5379                       Rm. 4C-526
EMAIL: [email-masked]
URL: http://www.cs.columbia.edu/~jdrosen

---

From: Jonathan Rosenberg <[email-masked]>
Date: Tue, 27 Apr 1999 15:40:16 -0400

> can tell) that guarantees that routing according to this field will work

This is correct. But, if there is no Contact, and the last routed proxy
has received it, who cares if there are more intermediate proxies along
the way? In any case, the change of making Contact mandatory will fix
this.

> requirement). 

yes. place the maddr parameter in the URI in the Record-Route header, if
its important (my server does this). The draft spec should definitely
have a caveat along those lines.

> This seems kind of serious. Did I miss something here? 

You're correct, but I don't think its serious. If your server is
concerned, use the maddr parameter.

> Anyway, on the

I agree.

-Jonathan R.

---

From: Anders Kristensen <[email-masked]>
Date: Tue, 27 Apr 1999 21:07:07 +0100

> the way? In any case, the change of making Contact mandatory will fix

Right. At least to the extent that people use Contact addresses that
cause messages routed according to those addresses to go straight to
their current host. If they don't, e.g. because they use
host-independent Contacts (which they shouldn't do), then I agree it
probably doesn't really matter.  As long as all hosts that really want
to make sure they stay on the signalling path can do so, there should be
no harm in interjecting additional proxies along the way.

BTW there's still the problem John Hearty mentioned earlier that when a
Route ends with the next-to-last proxy, i.e. doesn't include the final
destination, the last proxy may add a Record-Route header which can
confuse the receiving UA. This is solved by mandating the use of Contact
headers, but could also be handled by requiring the last proxy on the
Route path to retain an empty Route header in the forwarded message and
requiring proxies receiving such a header to include it in the forwarded
message thus preventing anyone from adding the Record-Route header.

---

From: Jonathan Rosenberg <[email-masked]>
Date: Tue, 27 Apr 1999 21:51:34 -0400

> message thus preventing anyone from adding the Record-Route header.

This seems a bigger change, as its a modification to the existing
Route/Record-Route processing in a server. Making Contact mandatory is
not a fundamental change (no code change required in any servers), its
just a change in strength from SHOULD to MUST at the UA. Given that
making Contact mandatory seems to solve a number of problems, I believe
that it is the best solution.

-Jonathan R.

---

From: Lars Berggren <[email-masked]>
Date: Wed, 28 Apr 1999 10:01:22 +0200

> that it is the best solution.

Making Contact mandatory may solve the problem. However, I think in some
cases its not that easy for a UAC to supply a host-dependent Contact
header.

If the UAC responsible for supplying the Contact header resides behind a
firewall on a LAN with local IP addresses, what is the UAC supposed to
put in the Contact? The local hostname or IP address is not a good
choice since they are not globally reachable. It can put the same
host-independent SIP-URL as it probably will put in the From header, but
then the routing will be host-independent and the use of Contact has no
effect.

Also for reasons of privacy and security, one does not want to show
local IP addresses or hostnames to a party outside the firewall.

If some kind of firewall SIP-proxy for the UAC is present, it can add
itself to a Record-Route list and be the one responsible for making the
routing host-dependent.

For the moment, I can see 3 ways for the proxy to accomplish this.

1. It keeps state for the call leg and a record of where to route
subsequent requests within the call leg from it's global side to the
local side. If the UAC added a Contact with local information the proxy
can rewrite or remove it.

2. If it is possible (via extension or changes to spec) to encrypt and
hide the Contact similar to the hiding of Via fields, then the proxy
could do so and letting the UAC put local information in the Contact
header. This has the advantage that no state is required in the proxy
for routing the requests. The disadvantage here has to do with backward
compability.

3. Similar to #2 but the Contact could be hidden by removing it,
encrypting its SIP-URL in a way that does not destroy the syntax and
pushing it into the Record-Route list before pushing the entry of the
proxy. When subsequent Routed requests arrives at the proxy's 'global
side' it knows it must decrypt the first Route before forwarding it.
Other parties are not concerned with this encrypted entry since they are
not supposed to look at it. The disadvantage here is that the Contact
will not be visible in the request, opposing the suggestion of a
mandatory Contact. However, in this approach, the Contact can be made
mandatory in requests from UA:s, but not when some proxy have added a
Record-Route header.

Comments are welcome.

/Lars

-- 
Lars Berggren       <[email-masked]>
Intertex Data AB    tel: +46-8-6282828
Sundbyberg, Sweden  fax: +46-8-6286414

---

From: Jonathan Rosenberg <[email-masked]>
Date: Wed, 28 Apr 1999 09:09:38 -0400

> can rewrite or remove it.

This sounds like a sort of stateful SIP NAT.

> mandatory in requests from UA:s, but not when some proxy have added a

This sounds like a stateless SIP NAT.

Solutions (1) and (3) seem acceptable to me; neither requires protocol
changes nor standardization. Note that not having a Contact header, as
in suggestion (3), may "oppose the suggestion" of a mandatory Contact,
but thats fine here since an intermediate proxy is still responsible for
"guaranteeing" that the full routed path is being followed. While having
Contact is mandatory in an INVITE from a UAC, I not sure having a UAS
return a 400 response if one is not present is a good idea.

If we do want UAS's to return 400 when no Contact is present, the proxy
in (3) could still keep the Contact, but rewrite it to be valid but of
signficance only to the NAT/proxy. It would also insert itself into the
Record-Route. This solution is a combination of your (3) and (2).

Its worth noting, however, that the Contact headers are just one of many
problems in these cases where you don't want to assume a globally
routable IP infrastructure. This SIP NAT will also have to rewrite the
SDP since the media addresses will be wrong. That seems a much bigger
pain....

-Jonathan R.

---

From: Lars Berggren <[email-masked]>
Date: Thu, 29 Apr 1999 12:48:24 +0200

> return a 400 response if one is not present is a good idea.

I just thought 'making Contact mandatory' meant it had to be present in
INVITE requests leaving proxies too. If Contact is made mandatory I
think it should be clearly stated that a UAS should not expect it if
there is an intermediate proxy present.

> Record-Route. This solution is a combination of your (3) and (2).

It will insert itself into the Record-Route if the UAS supports it. If
it does not, I guess it may try to use the rewritten Contact for
subsequent requests, which is not the intention.

> SDP since the media addresses will be wrong. That seems a much bigger

I agree, the media part is a harder problem to solve.

/Lars