Subject: [SIP] more on Record-Route and Loop-Detection

From: Loita Jahnsson <[email-masked]>
Date: Wed, 23 Aug 2000 13:02:51 +0200

> > Finally Jo has pointed out to me that maybe the spec also
> > wants to say that a server MUST NOT add itself more than
> > once into the Record-Route. Otherwise this could happen on
> > a 'legal' loop and the subsequent requests on the call leg
> > fail due to an illegal loop being created.
>
> Interesting. This would only happen in the reverse path, since its
> only in that case that the request URIs are the same (denoting
> a loop as opposed to a spiral). Its a problem,
> though, since the proxy really may need to record-route both times.
> The solution might be some URI parameter just used as a differentiator.
> A different value for this parameter would be inserted in each
> Record-Route.
> This would be popped into the request URI. Since the request URI is then
> different for both, the hashes to compute the branch ID parameter are 
> different, and this shows up as a spiral.
> 
> -Jonathan R.

Yes, this is a problem. 

A picture to illustrate it (INV means INVITE)

  ---------                  --------                  --------
  | a@c1  | -- INV u1@p1 --> |      | -- INV u2@p2 --> |      |
  ---------  (contact a@c1)  |      |                  |      |
                             |  p1  |                  |  p2  |
  ---------                  |      |                  |      |
  | b@c2  | <- INV b@c2 ---- |      | <- INV u3@p1 --- |      |
  ---------                  --------                  --------

When b@c2 creates it's Route entry it will, according to the
spec, fill in a@c1 as URI for all the Route-entries, which
is practice means that if b@c2 issues a BYE request, it will
have the same request-URI both times p1 is visited (illegal
loop).

Obviously the problem is recognized, but shouldn't it be solved?

It is suggested that "some URI parameter" should be introduced,
but why not keep the original Request-URI-values from the
original Record-Route information?

The spec says (6.34.2): " ... Since the URIs contained in the
Record-Route header fields are not useful for the reverse request
path, the UA fills all other components of the Route name-addr 
value with the name-addr value found in the Contact or the From
field. ..."

This operation seems completely pointless to me, the spec might
as well say: since the URIs are not useful, the UA should fill
all other components with DonaldDuck@Disneyland. Its like saying 
"since this information is useless, we exchange it with another 
piece of useless information".

Obviously the original Request-URI information from the 
Record-Route wouldn't be completely useless in Route for the 
scenario above. If we were using the original URIs from Record-
Route instead we wouldn't have a problem. And those URIs
are no more fake information than the one stated in the spec.

Best Regards,

   Loita Jahnsson
   SIP SW Developer

_______________________________________________
SIP mailing list
[email-masked]
http://lists.bell-labs.com/mailman/listinfo/sip

---

From: "Jo Hornsby" <[email-masked]>
Date: Wed, 23 Aug 2000 12:42:37 +0100

> > different, and this shows up as a spiral.
[...]
> A picture to illustrate it (INV means INVITE)

My view is that the spec should say that a proxy is not allowed
to add itself more than once in a Record-Route path; I'm struggling
to see why it would be useful for a proxy to be present more than
once.

> piece of useless information".

I don't think that's quite fair.  Putting the Contact/From address
in does vaguely make sense, because it indicates the ultimate
recipient of the message.  (One could imagine the chain of proxies
somehow breaking, but healing itself using this information.)

However, this has been slightly broken by the fact that the port
(in the Contact/From) is now corrupted by the proxy port.  This is
a shame.  And insofar as that is true, I might concede to Mr. Duck. &:)

> are no more fake information than the one stated in the spec.

The original Request-URI information _is_ useless for the reverse
request path.  For example, from your diagram, although u1@p1
maps to u2@p2, it in no-way implies that u2@p2 maps to u1@p1 (which
I think is what would have to happen for the Request-URIs to
make sense in reverse; something like that, anyway).

HTH,

 - Jo.

---

From: Jonathan Rosenberg <[email-masked]>
Date: Thu, 24 Aug 2000 01:31:52 -0400

> to see why it would be useful for a proxy to be present more than

No. I do not like this. When a request spirals, its arrival at the proxy
the second time is a completely separate transaction; it has no real
bearing on the first time around. For reasons of logging, features, and
applications there are many reasons why you would want to record-route
the second time - the same reasons you wanted to do it the first time.

I actually proposed a set of possible solutions in slides I put together
for Pittsburgh IETF, but never got around to discussing. THe slides are
at:
http://www.softarmor.com/sipwg/meets/IETF48/slides/pres-rosenburg-sipwg_jul00_listissues.ppt

Anyway, the solution I like best is the following: don't check for loops
in the case where there are Route headers. A little ugly, I admit, as it
creates an interaction between two components. 

> somehow breaking, but healing itself using this information.)

It maintains the fundamental principle that the request URI indicates
for whom the request is destined. By relying on Route headers to get the
request there, even though the request URI says something completely
difference, makes the operation of the protocol brittle. We have seen
this at bakeoffs - loops often occur if any proxy has anything slightly
wrong with their route processing.

> a shame.  And insofar as that is true, I might concede to Mr. Duck. &:)

I agree that we have abused the port number and maddr parameters. This
is because the initial work on record-route really focused on the
forward direction, and made the incorrect assumption that the URi
sequence could always be used to reconstruct the proxy server sequence.
As we have gradually realized the fallacy of these assumptions, we have
had to work this fix in in a backwards compatible manner.

-Jonathan R.

-- 
Jonathan D. Rosenberg                       72 Eagle Rock Ave.
Chief Scientist                             First Floor
dynamicsoft                                 East Hanover, NJ 07936
[email-masked]                     FAX:   (973) 952-5050
http://www.cs.columbia.edu/~jdrosen         PHONE: (732) 741-7244
http://www.dynamicsoft.com

---

From: Loita Jahnsson <[email-masked]>
Date: Thu, 24 Aug 2000 11:15:15 +0200

Hi Jo,

Thanks for your answer.

I would like to discuss and clarify my point of view
a bit further.

> > in practice means that if b@c2 issues a BYE request, it will

As Jonathan implies, there are cases where you
would like to do this when making proxies which controls 
services,  firewalls, whatever.

As another example (I don't know if it's a good one, but anyway)
where proxy "p1" in my picture would need to Record-Route 
itself both times, you could imagine p1 having two ethernet 
interfaces. c1 & c2 are on a local network (10.0....), which 
is reached through one of the interfaces. p2 are on a wider 
network (xxx.xxx.xxx.xxx), reached through the other interface. 

If we would do what you suggest, the Record-Routing
chain would be p1 - p2 and b@c2 would construct a Route
path which would be p1 - p2 - c1. (According to the spec
today it would have been p1 - p2 - p1 - c1).

When the BYE request from b@c2 is proxied based on your 
proposed path, and arrives at p2 it wouldn't find it's 
way directly to c1 since c1 is located at the local network 
behind p1.

> a shame.  And insofar as that is true, I might concede to Mr. Duck. &:)

Well. Maybe I exhaggerated a bit, in a lame attempt to pull
a joke ;)

I would like to discuss this further, though, because I still
think my proposal is OK.

About repairing broken proxy chains; whether this is reasonable
or not; consider our small example network above, and we're
just about to proxy the BYE request from b@c2 to a@c1. Then 
suddenly, we can't contact the next proxy in our chain, and
we would like to use the request-URI to find out our final
destination. Assuming the final destination is reachable,
we would have use for the information in the Request-URI, 
and we are far better off with than information than an
address to Mr. Duck ;)

Ok, but even if the request-URI actually states
Mr. Duck, you will find the final recipient in the Route-
path anyway, if you would like to make an attempt to contact
that recipient directly. Also if a chain of proxies are
recorded, you would maybe like to bypass "as few as possible"
using the Route information to try to contact "the closest
reachable" all the time. There is really no need for information
about the final recipient to be duplicated in the request-URI
as well.

To me, it's also rather unclear to what extent you would like
to try this kind of by-passing of proxies, which insists
in being in the chain. I guess, if a proxy insists of being
in the proxy chain, it has some reason to do so. Maybe
it does stuff that are essential for the session. If such
a proxy "dies", and you happens to be successful when bypassing 
it (and maybe several others), it is undefined to me how
much the session really is "healed". 

> make sense in reverse; something like that, anyway).

OK. I agree completely, that the request-URI is useless for
the actual routing decision, when you route based on the Route
header. Thats why I joked about putting useless information
such as [email-masked] in the Request-URI ;)

But even though the original information is equally useless
for the actual routing decision, I think it is useful for
loop detection decisions.

Here is an example:

Consider our simple network above.

Here's what happens with the solution currently proposed in the
spec (I'm using pseudo SIP syntax because I'm too lazy doing too
much typing):

c1   --> p1   :     INVITE u1@p1
                    contact a@c1

p1   --> p2   :     INVITE u2@p2
                    contact a@c1
                    record-route u1@p1<maddr=p1-addr>

p2   --> p1   :     INVITE u3@p1
                    contact a@c1
                    record-route u1@p1<maddr=p1-addr>,
u2@p2<maddr=p2-addr>

p1   --> c2   :     INVITE b@c2
                    contact a@c1
                    record-route u1@p1<maddr=p1-addr>,
u2@p2<maddr=p2-addr>, u3@p1<maddr=p1-addr>

OK, so now the INVITE request has reached it's final
destination, c2,  and according to the solution proposed
in the spec today, c2 created this Route information
to be used for subsequent requests:

c2: Route = a@c1<maddr=p1-addr>, a@c1<maddr=p2-addr>,
a@c1<maddr=p1-addr>, a@c1

Let's skip the INVITE-response & ACK and move forward
directly to the point of time when b@c2 is generating
a BYE request for the session

c2   --> p1   :     BYE a@c1
                    route a@c1<maddr=p2-addr>, a@c1<maddr=p1-addr>, a@c1

p1   --> p2   :     BYE a@c1
                    route a@c1<maddr=p1-addr>, a@c1

p2   --> p1   :     BYE a@c1         <---- loop detection ....
                    route a@c1

p1   --> p2   :     Loop detect ...

You see, when the request reaches proxy p1 the second time
with the same request-URI, it will be considered a loop,
and the transaction will not be successful, even if it
should be.

Let's go for the alternative that I proposed, which is simply 
to keep the original request-URI-information. Then after
Record-Routing the INVITE, c2 would create this Route:

c2: Route = u1@p1<maddr=p1-addr>, u2@p2<maddr=p2-addr>,
u3@p1<maddr=p1-addr>, a@c1

OK, now b@c2 will send a BYE using that information:

c2   --> p1   :     BYE u1@p1
                    route u2@p2<maddr=p2-addr>, u3@p1<maddr=p1-addr>,
a@c1

p1   --> p2   :     BYE u2@p2
                    route u3@p1<maddr=p1-addr>, a@c1

p2   --> p1   :     BYE u3@p1
                    route a@c1

p1   --> c1   :     BYE a@c1 

Sheer success ;) ;)

Best Regards,

   Loita Jahnsson
   SIP SW Designer,
   Ericsson

---

From: "Jo Hornsby" <[email-masked]>
Date: Thu, 24 Aug 2000 10:44:59 +0100

> the second time - the same reasons you wanted to do it the first time.

I have to say that I don't see why it would be so difficult for
the Proxy to note that this transaction actually corresponds to
N other transactions, and update state as appropriate...

> creates an interaction between two components. 

...but this is also reasonable.  Just be aware that some malevolent
SIP entity might give you a request with a very big Route header. &:)

 - Jo.

---

From: "Jo Hornsby" <[email-masked]>
Date: Thu, 24 Aug 2000 12:06:57 +0100

> way directly to c1 since c1 is located at the local network 

Interesting.

You are right, my "solution" would break down here.  However, I
would note that p1 might have to be careful when it Record-Route d,
in that it would have to present an maddr parameter that resolved
appropriately whichever "side" of the proxy you were facing.
(i.e., if the proxy had a different IP on each interface, it would
have to use a domain name that resolved to the right IP for both
p2 and c1/c2.)

(But we're probably roaming into the nightmarish world of NATs
[NATmare, anybody?], now.  For instance, what if c1 wanted to
call c3, which happened to reside on the xxx.xxx.xxx.xxx network?
SDP is going to be wrong, etc., etc..)

[...]
> about the final recipient to be duplicated in the request-URI

I think that a proxy that thinks it can be clever by optimising
signalling by jumping to the nearest Route would generally be
frowned upon. &:)

> much the session really is "healed".

Yes, this is true; the chain is probably still quite ill.

I think my sentiment was best expressed by Johnathan:
JR> It [using the Contact/From address] maintains the fundamental
JR> principle that the request URI indicates for whom the request
JR> is destined. By relying on Route headers to get the request
JR> there, even though the request URI says something completely
JR> difference, makes the operation of the protocol brittle. We
JR> have seen this at bakeoffs - loops often occur if any proxy
JR> has anything slightly wrong with their route processing.

[...]
> such as [email-masked] in the Request-URI ;)

No, that's not why I said it was useless.  I meant that it was
useless because in every case, ignoring the Route header, the
Request-URI was pointing at something that in most cases, would
never resolve to the calling party.

That is, if the Route header were "lost", no matter how hard
any proxy tried, it would be unlikely that it could figure out
that u3@p1 (which would be the first Route Request-URI by your
method) should be forwarded to a@c1.

> a@c1<maddr=p1-addr>, a@c1

Agreed.

> and the transaction will not be successful, even if it

Oh, I'm not disputing that.

> u3@p1<maddr=p1-addr>, a@c1

No, you've got the Route wrong, it should be:
u3@p1<maddr=p1-addr>, u2@p2<maddr=p2-addr>, u1@p1<maddr=p1-addr>

>                     route u2@p2<maddr=p2-addr>, u3@p1<maddr=p1-addr>,

Although this should be "BYE u3@p1", I think the problem is still
clear.  Ignore the Route header.  Now p1 resolved u2@p2 to u3@p1
(and u1@p1 to u2@p2) the in the "forward" direction, but it's
pretty unlikely to do the reverse in the "reverse" direction.

>                     route u3@p1<maddr=p1-addr>, a@c1

As Johnathan said, Record-Route has been somewhat abused by maddr
and port, but using the Contact/From gives us the best we can do
without sacrificing backward compatibility.

Cheers,

 - Jo.

---

From: Loita Jahnsson <[email-masked]>
Date: Thu, 24 Aug 2000 13:20:05 +0200

Hi Jonathan,

   Thanks for your answer.

   I would like to discuss this subject further though.
 
> creates an interaction between two components.

   Ok, I have looked at your slides and I found two proposed
   solutions.

   I guess your solution based on not doing loop detection
   when a request contains Route header could be fine solving
   that specific problem.

   But the thing is, the loop detection problem might not be the 
   only problem which occurs due to the UAS removal of the original 
   request-URI information from the Record-Route when creating
   it's Route. 

   Let's look at this network (all proxies are stateful)
   :)

   --------             ------    ---u1@p1----->  ------
   |      |             |    |    |               |    |
   | a@c1 |  -user@fp-> | p1 | ------u2@p1----->  | p2 |   ... continued
   |      |             |    |    |               |    |
   --------             ------    ---u3@p1----->  ------

   I'm not really good at ascii graphics, so I only draw half
   the picture ;). I will try to describe the rest verbally.

   In proxy p2, three INVITE requests will be received
   with the same call leg, but representing different
   transactions, needing separated transaction handling.
   (For example, each of the transactions in p1 could generate
   a new fork from p1 to a number of different servers generating
   a number of different response codes and needing their
   own handling of UDP re-transmissions and more.)

   So, since we have several transaction handlers in p2
   for the same call leg, we need something more than the
   call leg to identify the different transactions. And the
   only thing that I can think of that would be sort of static
   for the transaction/session would be the request-URI.

   And the only time I could think of where it wouldn't work 
   is because the request-URI-information is removed by the called UA 
   from the Record-Route when called UA creates the Route.

   If this is a real problem (maybe you know of a solution
   other than using the request-URIs), I think it should not be
   of great significance that the fundamental principle of the
   request-URI (that you should be able to use it for routing
   at all times) would be broken using the original request-
   URI-information for Route. I think that principle was broken 
   at the moment Record-Route/Route was introduced to SIP.

   Best Regards,

      Loita Jahnsson
      SIP SW Designer

---

From: Loita Jahnsson <[email-masked]>
Date: Fri, 25 Aug 2000 12:01:33 +0200

Hi Jo!

Thanks for your answer!

I think I was a bit too eager to prove my point, so
I was careless when writing my example. Both Record-
Route and as a consequence Route is wrong there.

Each host should push itself first in the Record-Route
list (which I didn't do).

The called UA should maintain the order of the entries
in the list though, read 6.34.2 in the spec:

"If a UA finds a Record-Route header in a request
received as a UAS, it copies the Record-Route maddr
parameters and any port value, maintaining their ordering ... "

I am sorry about the confusion I caused by writing
my example carelessly.

What I was trying to show however, is the benefit
of keeping the original URI information when the
called UA is building it's Route information. 

I know you recognized this, Jo, but I want to correct 
the example anyway, in case other would read it ;)
The modified example is included below.

I would also like to say something about the reasons
given for keeping the spec the way it is.

> JR> has anything slightly wrong with their route processing.

OK. Let's look at the similarlity between Via headers and
Route headers as far as routing concerns.

Via - Response - routing:

* Via is a list of destinations that should be used
  when routing the response. 

* If the Via is constructed in a wrong manner the routing 
  of the response will fail.

* You don't have a response-URI to make a second routing
  attempt with if the Via-routing fails.

Route - Request - routing:

* Route is a list of destinations that should be used
  when routing the request. 

* I think similarly to the Via - if the Route is constructed 
  in a wrong manner the routing should fail. As I wrote in 
  a previous posting it is undefined how much you would be able 
  to heal a session anyway. 

  You have to be able to trust Route in the same manner you 
  trust the Via for a response!!!!

* When using Route, you don't need a request-URI to
  be able to perform the routing task. 

But, here is my statement, which if it's wrong I would
like an explanation of why it's wrong:

The request-URI in SIP today has dual purpose, (i)
routing (when Route is not present), (ii) to together
with the call leg identify transactions within a
stateful SIP proxy.

For the sake of (ii) the request-URI _is_ important
at all times, also when routing with Route. (Look at
the example net I made in my answer to Jonathan, and
you will see what I mean).

So I would wish that we could be pragmatic about this
and keep the original URI information from Record-Route
when building the Route at all times.

I really hope this discussion will be continued.

Best Regards,

   Loita Jahnsson
   SIP SW Designer
   Ericsson, Sweden

-------- MODIFIED EXAMPLE ---------------------------------------

c1   --> p1   :     INVITE u1@p1
                    contact a@c1
 
p1   --> p2   :     INVITE u2@p2
                    contact a@c1

p2   --> p1   :     INVITE u3@p1
                    contact a@c1
                    record-route u2@p1<maddr=p2-addr>,
u1@p1<maddr=p1-addr>

p1   --> c2   :     INVITE b@c2
                    contact a@c1
                    record-route u3@p1<maddr=p1-addr>,
u2@p2<maddr=p2-addr>, u1@p1<maddr=p1-addr>

c2   --> p1   :     BYE a@c1

p1   --> p2   :     BYE a@c1

Let's go for the alternative that I proposed, which is simply
keep the original request-URI-information. Then after
Record-Routing the INVITE, c2 would create this Route:

c2: Route = u3@p1<maddr=p1-addr>, u2@p2<maddr=p2-addr>,
   u1@p1<maddr=p1-addr>, a@c1

c2   --> p1   :     BYE u3@p1
 
p1   --> p2   :     BYE u2@p2

p2   --> p1   :     BYE u1@p1
                    route a@c1

p1   --> c1   :     BYE a@c1

******************************

---

From: Loita Jahnsson <[email-masked]>
Date: Fri, 25 Aug 2000 12:15:50 +0200

Hi,

   I'd like to clarify the example I made yesterday, because
   I made a typo.

   It should look like this:

   --------             ------    ---u1@p2----->  ------
   |      |             |    |    |               |    |
   | a@c1 |  -user@fp-> | p1 | ------u2@p2----->  | p2 |   ... continued
   |      |             |    |    |               |    |
   --------             ------    ---u3@p2----->  ------

   In other word, proxy p1 forks the requests to three different
   users at proxy p2.

   This is where the request-URI is needed to separate the
   transactions (or at least I believe so).

   I think basically, the problem was recognized when you had
   the spiral discussion previously this year. Then it was
   recognized that the request-URI had to be taken into account
   when separating the transactions at the proxy for the spiral
   case. And after that discussion, it is taken into account, 
   because the branch values are generated partially based on the 
   request-URI information.

   But I believe the problem is more of a general nature and
   not limited to the case of spirals/loops alone, and that
   it should be recognized that the request-URI also serves
   (together with the call leg) as a transaction identifier
   for a state-ful proxy.

   Best Regards,

      Loita Jahnsson
      SIP SW designer

---

From: Neil Deason <[email-masked]>
Date: Fri, 25 Aug 2000 15:38:29 +0100

Rather than just kick this around for a bit and drop it
without consensus it would be nice to reach closure.

How about we just don't do loop detection 
if there is a Route: to follow. Has anyone got a 
good reason not to take this simple approach?

BTW there were some slight errors in the modified
example which I have commented on below in case they
caused any confusion.

Cheers,
Neil.
- 
Ubiquity Software Corporation, UK        http://www.ubiquity.net

[snip]
>                     record-route u2@p1<maddr=p2-addr>,

Should be record-route u2@p2<maddr=p2-addr>,
u1@p1<maddr=p1-addr>

>                     route u2@p2<maddr=p2-addr>, u3@p1<maddr=p1-addr>,

Should be route u2@p2<maddr=p2-addr>, u1@p1<maddr=p1-addr>, a@c1
Which would then propagate through below ....

---

From: Loita Jahnsson <[email-masked]>
Date: Mon, 28 Aug 2000 09:28:28 +0200

Hi Neil,

   Thank you for correcting the example from the typos I made
   and for pushing this discussion forwards.

> good reason not to take this simple approach?

   Yes, that's what I have been trying to express in some
   of my previous postings to this discussion. But maybe
   it has been lost in all the typos I've made, and maybe
   also in my not-so-good english ;)

   The suggestion of not doing loop detection if there is
   a Route will probably solve that specific problem. 

   Previously on this list there was a discussion on loops 
   vs. spirals and then it was solved was making a cryptographic 
   hash of Request-URI + call leg data when generating the branch
   value for the Via field and that approach solved that
   specific problem.

   But I believe, that the problem is of more general nature,
   and I think making "fixes" in the protocol such as the branch
   value solution for loops/spirals and this new solution with 
   not doing loop detection if there is a Route, will add more
   complexity than needed and anyway not solve the general
   problem.

   The thing that needs to be recognized, or at least I think
   so (maybe it's wrong, just tell me so if it is) is that
   proxies (at least stateful ones) needs a concept of 
   "transaction identifier", being the call leg + the requestURI,
   in order to be able to separate different transactions
   with the same call leg through the same proxy . One example
   of that is the spiral case. Another example is when you have
   a proxy, p1, forking a request to several different users at
   another proxy, p2. In p2, you will need to use the request-
   URI + the call leg to be able to separate the transactions.
   (p1 & p2 are stateful in this example). 

   If this will be recognized, you may not need solutions like
   the branch value of today, like not doing loop detection
   when having Route, and similar.

   If you recognize this concept, and adapt what needs to be
   adapted to support it (for example not changing the request-URI
   when the called UA are creating the Route), I think you
   will end up with a more simple solution than the ones suggested
   today.

   Best Regards,

      Loita Jahnsson
      SIP SW Designer

---

From: Loita Jahnsson <[email-masked]>
Date: Tue, 29 Aug 2000 09:07:12 +0200

Hi,

   Consider this theoretical fork tree example (I've tried to use 
   some kind of generic URI notation for the nodes in the
   tree):

                                u0@p0
                                  |
                   --------------------------------
                   |                              |
                u11@p11                        u12@p12
                   |                              |
           -----------------              -----------------
           |               |              |               |
        u21@p21         u22@p22        u23@p23         u24@p24
           |               |              |               |
      ---------       ---------       ---------       ---------
      |       |       |       |       |       |       |       |
   u31@p31 u32@p32 u33@p33 u34@p34 u35@p35 u36@p36 u37@p37 u38@p38

   This is just a limited example, and could be more generalized,
   but I think it will do for this discussion.

   Theoretically, a proxy X could occupy any number of combinations
   of nodes in this tree, from 0 to all. (For example it could be
   X == p0 == p21 == p23 == p34 when forwarding a request through
   the tree). For most of these combinations you would want to keep 
   the transactions separated from eachother, being a stateful proxy. 
   The spiral case which was previously discussed in this list is 
   merely a subset of combinations in such a theoretical "forwarding
tree".

   Implementing the proxy X, and given the way the SIP spec is written
   today, I don't know of a way to separate the transactions within
   proxy X. 

   I would greatly appreciate if anybody in the SIP community,
   knowing of a solution to this that could be implemented
   today, could send a posting to this discussion. 

   Otherwise it can be considered as a real problem for the whole
   community - it is simply impossible to implement a real stateful 
   SIP server product today, existing in larger networks.

   In that case a suggestion is to make it possible to use the call 
   leg + cseq + information extracted from/based on the requestURI
   to be able to identify the transactions within a proxy.

   However, the way Route is designed today, original
   request-URI information from Record-Route path is destroyed 
   for some higher purpose that I haven't been able to understand.

   I would like the original request-URI information from
   Record-Route to be kept in the Route, because then I would
   be able to use request-URI information together with call leg & 
   cseq to identify transactions.
   
   The simplicity of the proxy operation, when being able to
   identify transactions in this suggested manner, is rather appealing 
   to me at least. Given this opportunity, other things in SIP could
   be simplified as well. For example the hash part of the
   branch values for the Via could probably be removed, saving 
   considerably more bytes than the short form of SIP ;) ;) when 
   the requests are forwarded a number of times.

   Of course there are a number of alternative solutions, a new
   header could be invented, or whatever. But if this is a problem,
   at least something needs to be done.

   I do realize that this is a theoretical discussion and the some 
   of these combinations are highly unlikely to happen in a "real" 
   network, but as SIP network structures start to build, one could 
   easily predict that many "unlikely" cases will occur.

   If this will be recognized by others as a problem, I would like
   to emphasize the benefit of finding one rather simple solution
   that would solve the general problem, rather than to invent
   a number of "fixes" in the protocol to solve a number of "special
   cases" of the general problem.

   Best Regards,

      Loita Jahnsson
      SIP SW Designer

---

From: "Jo Hornsby" <[email-masked]>
Date: Tue, 29 Aug 2000 11:09:13 +0100

>    some kind of generic URI notation for the nodes in the

This is trivially solved (for the example above) with the notion
of "Isomorphic Requests" as defined in the spec.  Basically,
every request that differs in at least one of From, To, Call-ID,
CSeq, Request-URI or topmost-Via from any other request, indicates
a distinct transaction.

I would note that the spec doesn't mention anything about looking
at the topmost-Via at this point, this should probably be fixed?

[...]
>    to be able to identify the transactions within a proxy.

As above.

>    for some higher purpose that I haven't been able to understand.

I finally think I'm with you. &:)

Let's consider the following:
  A -INV-> P1 -INV-> P2 -INV-> P1 -INV-> B

A is originating UA, B is receiving UA, P1 & P2 are proxies that
Record-Route.

Let's say that a call is successfully set up.  Now B wants to
hang-up.  We've been discussing what the Route will look like
for the BYE, and currently the "consensus" is that P1 can appear
twice with impunity; proxies don't loop-detect when Route headers
are present.

Okay, fine, but when the P2-P1 "portion" of the BYE reaches P1,
how will it distinguish that request from the initial B-P1
"portion"?  "Easy!"  I hear you cry, "We'll just look at the topmost
Via."  Okay, but I already detected this as a Request-Merge, and
returned a 482.

So now we also say that you don't do Request-Merge Detection or
Loop Detection when there are Route headers present.  This does
not help, since if we update the scenario to be:
  A -INV-> P1 -INV-> P2 -INV-> P1 -INV-> P2 -INV-> B
We can no-longer guarantee that P1 will see different topmost-Vias.

Now there are a couple of hacks around this:
 1) We could start to count Vias.  This has been brought up in
    relation to Loop Detection in the face of Via hiding.
 2) We could make extra requirements on the branch parameter
    such that it would always be different in these cases.
    (Note that this will still mean we would have to ignore
    Request-Merging with Route headers present.  Although I
    admit it's slightly difficult to see how such a situation
    would ever occur. (:&)
 3) We could mandate that proxies are allowed to add themselves
    into a Record-Route path _at most once_.

I prefer 3), mainly because of it's simplicity from a protocol
perspective, and also because I haven't heard a good argument
why it's harmful.  Sure, it's going to require a small amount
of extra complexity in transaction-handling in proxies, but I
can't see that it's going to be so difficult to work around.

>    cseq to identify transactions.

I still don't buy this.  I agree with Johnathan that it makes
the protocol more "brittle".  Request-URI has a very well-defined
meaning, and that meaning is completely lost if we take this
approach.

>    the requests are forwarded a number of times.

No, we can never remove the requirement that the branch parameter
is a function of the Request-URI.  If we do that, it becomes
impossible to detect loops.

>    cases" of the general problem.

I vote for 3).  I'll be distributing badges shortly. &:)

 - Jo.

---

From: Loita Jahnsson <[email-masked]>
Date: Tue, 29 Aug 2000 14:01:24 +0200

Hi Jo,

Thanks for you answer!

> why it's harmful.  

I tried to give you an example with a proxy with a local
network on one side and an wider network on the other side.
I don't know if it's a good example, but anyway the "3" solution
wouldn't work there.

Or ???

Also, if you remember, Jonathan didn't like it because a
proxy implementing services and stuff might want to keep
the transactions apart.

> meaning, and that meaning is completely lost if we take this

I think, when routing using Route, the request-URI is
merely an illusion as far as routing concerns. Look at
how the Via works when routing responses. It's not brittle 
at all ;)

> impossible to detect loops.

I don't mean that we could remove the branch parameter,
I am talking about the hash part (1.21323454556667), ie all
the digits after the dot. Don't bother to count them, I just
pressed down a lot of digits simultaneously on my keyboard :)

Instead we could just use 1, 2, 3, ... as branch values, still 
being able to detect loops.

If we use the request-URI (as I suggested) to find the correct 
transaction handler/transaction data in the proxy, spirals are 
treated correctly automatically since they trigger different
transaction handlers/or represent different transaction data.
We wouldn't need the hash part of the branch values.

Best Regards,

   Loita Jahnsson
   SIP SW Designer

---

From: "Jo Hornsby" <[email-masked]>
Date: Tue, 29 Aug 2000 13:58:23 +0100

> I don't know if it's a good example, but anyway the "3" solution

Ah yes.  I had forgotten about that problem, but I seem to remember
that it only solved a small part of a general difficulty when one
starts to look at firewalls.
 
> proxy implementing services and stuff might want to keep

Yes.  Fair enough, but I haven't seen an argument yet why the
proxy can't maintain a 1-to-many map internally.

> how the Via works when routing responses. It's not brittle 

Agreed, the Request-URI isn't being used at all.  I guess I just
feel more secure knowing it's there and it's right.  (Well,
almost.)

[...]
> being able to detect loops.

Yes, but those digits still have to be a function of the branch
parameter somehow.  Index into an array &:) or whatever.  I don't
see how this changes anything.  (We have an implementation now
that does loop detection and detects request merging scenarios
and can spiral, and the branch parameter is basically a
monotonically increasing integer.)

> We wouldn't need the hash part of the branch values.

In an incoming request, the branch parameter in the topmost Via
is generally going to be meaningless insofar as locating the
correct "transaction" in a proxy (well, you need it in perverse
request-merging situations).  You do, however, need to look
down the list of Vias, and look for a "familiar" branch parameter.
That's the important bit.

Anyway, Neil has got me all turned around on the issue.  I'm now
thinking perhaps 2), since the added restriction of not doing
loop detection (request merging) checks on requests with Route
headers in isn't that Draconian, and it also solves another problem
that I've been harping on about: Loop Detection and Via Hiding
(see "thread" from last week).  That is, add the requirement that
branch parameters are always unique (within some reasonable
time-frame).

[Everbody please change their badges to say "2" instead of "3". (:&]

Thoughts?

Cheers,

 - Jo.

---

From: Jonathan Rosenberg <[email-masked]>
Date: Tue, 29 Aug 2000 09:59:13 -0400

> branch parameters are always unique (within some reasonable

This is my preference. This gives Loita the desired property - you can
uniquely identify the transaction as a concatenation of a finite set of
fields - To, From, R-URI, Call-ID, CSeq, top via (plus branch-ID). Jo

> at the topmost-Via at this point, this should probably be fixed?

Yes, it should. 

An interesting wrinkle I just thought of - stateless proxies. They need
to be sure that the branch-ID they insert is unique, but also the same
for retransmitted requests within the same transaction. I suppose this
can be done by having them compute the branch ID param as a hash of the
To, From, Call-ID, CSeq, R-URI and top Via of the incoming request,
along with the process-ID, IP address or some other invariant unique to
each proxy instance. This should probably also be noted in the spec.

-Jonathan R.

---

From: "Jo Hornsby" <[email-masked]>
Date: Tue, 29 Aug 2000 15:08:18 +0100

> each proxy instance. This should probably also be noted in the spec.

Cool.  Can we now remove the 
 "A server that is capable of hiding Via headers MUST attempt to
  decrypt all Via headers marked as "hidden" to perform loop detection.
  Servers that are not capable of hiding can ignore hidden Via fields
  in their loop detection algorithm."
paragraph (Section 6.25 of bis01), then, since this is now
unnecessary to detect loops?

 - Jo.

---

From: Jonathan Rosenberg <[email-masked]>
Date: Tue, 29 Aug 2000 23:46:40 -0400

> unnecessary to detect loops?

I am missing something here; why does this eliminate loop detection?

-Jonathan R.

---

From: "Jo Hornsby" <[email-masked]>
Date: Wed, 30 Aug 2000 10:28:43 +0100

> > > An interesting wrinkle I just thought of - stateless
> > > proxies. They need to be sure that the branch-ID they insert is
> > > unique, but also the same for retransmitted requests within the
> > > same transaction. I suppose this can be done by having them
> > > compute the branch ID param as a hash of the To, From, Call-ID,
> > > CSeq, R-URI and top Via of the incoming request, along with the
> > > process-ID, IP address or some other invariant unique to each
> > > proxy instance. This should probably also be noted in the spec.
> >

It doesn't eliminate Loop Detection, but it means that you don't
need to waste time decrypting Vias to check for loops.

Previously, I was concerned that this was a bogus approach, since
if you attempt to detect Loops by decrypting Vias, any ACKs or
CANCELs relating to this request would be ambiguous (would they be
for the "first" time you "saw" the request, or for the "second"?).
This is because there was no guarantee that the branch parameter
would be different in each case.

Requiring that the branch parameter is always unique alleviates
this problem; however, since you suggest adding some other
invariant, it now becomes possible for a proxy to identify its
"own" branch parameters.  Thus decrypting Vias for the sole
purpose of checking for Loops becomes rendundant.

 - Jo.

---

From: Loita Jahnsson <[email-masked]>
Date: Thu, 31 Aug 2000 10:00:22 +0200

Hi,

> Jonathan Rosenberg wrote;
> 
> fields - To, From, R-URI, Call-ID, CSeq, top via (plus branch-ID). 

Solution 2 is quite ok. This would offer a possibility
to separate parallell transactions within a SIP session, 
which is a good thing :)

You might want to consider the case below though:

***************************************************************************

                     ---------> u1@p2  ---> ub1@cb1
                     |
  ua@ca  ------> u@p ---------> u2@p2  ---> ub2@cb2

ca sends an INVITE to u@p, which forks the request to 
different users. As it turns out, both ub1@cb1 and ub2@cb2 sends
a 200 OK and "p" happens to be able to forward multiple 200 OK's. 
ca is an implementation that could actually ACK both of the 200 OK's 
and setup and represent parallell media sessions towards both cb1 
and cb2 for the single SIP session.

Imagine "p" implementing some service or controlling a
firewall or media proxy for example. "p" would then have to 
keep the different "sub-sessions" apart, because, cb1 & cb2
could hang up at different occasions.

Consider "p" and "p2" to be Record-Routing.

When cb2 hangs up it would appear in "p" as:

BYE ua@ca, Route ua@ca

and when cb1 hangs up it would appear in the proxy as:

BYE ua@ca, Route ua@ca

How should "p" be able to determine which "sub-session" the BYE
is for? 

***************************************************************************

So when thinking about it once more, Jonathans suggestion with 
a URI parameter, might be the most appropriate one?

Best Regards,

   Loita Jahnsson

---

From: Neil Deason <[email-masked]>
Date: Thu, 31 Aug 2000 11:51:12 +0100

> You might want to consider the case below though:

From p's point of view the topmost Via would be different
thus identifying the two possible BYEs as non isomorphic
requests. Also in this example a tag in the From 
differentiates the call legs if the proxy needs to be 
call stateful for some specialised service.

Cheers,
Neil.