Subject: RE: "Legal" via loops

From: "Donovan, Steven R." <[email-masked]>
Date: Thu, 02 Dec 1999 16:59:07 +0000

Dave Oran wrote:

On first blush, it appears this will work. Another approach that may be
simpler is to allow a VIA to be marked explicitly as a "loop-barrier", so
that any proxy doing loop detect does not look further back in the VIA list
than the first "loop-barrier". Any stateful proxy that intercepts responses
and re-issues INVITES would mark its VIA with a loop-barrier.

SRD> But then how is a true loop detected?  If proxy 2, after receiving a
request from proxy 1, adds its via as a loop-barrier and sends the request
back to proxy 1, using the same request URI as the original request to proxy
1, this should be treated as a via loop.  By your rule, proxy 1 would stop
its via loop detection at the loop-barrier and process the request.  It is
interesting that if proxy 1 is stateless then the request will be sent back
to proxy 2.  If it is a stateful proxy, then proxy 1 will treat the request
as a retransmission.

SRD> There still needs to be a way for the proxy to store the request URI in
the via header so it can know when an INVITE for an existing transaction is
really a new request.  Jonathan's approach achieves that with the assumption
that the proxy stores the request URI in the state information associated
with the transaction.  This approach has the merit that it uses an existing
parameter to the Via header.  

SRD> An alternative approach would be to add a parameter to the Via header
that could be used by the proxy to store the request URI.  For privacy
reasons, the proxy would need to encrypt the request URI when storing it.  

This seems simpler than Jonathan's proposal but may have backward
compatibility problems. OTOH, existing proxies will falsely detect loops no
matter what we do, right?

SRD> You are correct, existing proxies will detect loops no matter what we
do.

Steve

> -----Original Message-----
> From: [email-masked]
> [mailto:[email-masked]]On Behalf Of Jonathan
> Rosenberg
> Sent: Thursday, December 02, 1999 1:37 AM
> To: Donovan, Steven R.
> Cc: [email-masked]
> Subject: Re: "Legal" via loops
>
>
> Yes, this is a problem. We have discussed it in the past, and I don't
> think there was an agreed upon solution.
>
> I believe the solution to this that is backwards compatible is to make
> use of the branch ID parameter in the Via field. Let me explain.
>
> At a proxy, we say that a request is a new transaction (not a
> retransmission, and not a loop), if its Call-ID, To, From CSeq *and*
> request URI are different from another request. In that case, we can
> define a transaction ID as a hash over these quantities. Call this hash
> H. Also assume that a proxy is set up so that if it forks, it never
> forks more than 2**N times, for some N that is sufficiently large. When
> a proxy forks, the ith branch has a branchid parameter with the value (H
> << N) + i.
>
> When a response arrives, the proxy takes the branch ID parameter from
> the top Via field, shifts it right by N, and obains the transaction ID.
> This allows the response to be matched to the request. The N bits that
> were shifted out identify which branch the response is for.
>
> To do loop detection, when a request arrives, the proxy looks for its
> own address in the Via list. If it finds it, AND if the branch ID
> parameter in that Via field, shifted right N bits, match the transaction
> ID computed for this request, it is considered a loop. Otherwise, if the
> proxy doesn't find its address in the Via list, but the transaction ID
> computed from the request matches the transaction ID of an existing
> transaction, its a retransmission. Otherwise, its a request for a new
> transaction.
>
> There are other ways to place both the actual branch ID, and this new
> hash, into the branch ID parameter in the Via field, besides this shift
> by N.
>
> Comments?
>
> -Jonathan R.
>
> > "Donovan, Steven R." wrote:
> >
> > I believe that this has been discussed in the past, but I don't
> > believe there was a resolution.
> >
> > It reframe the problem, assume user A invites user B at proxy 1.  User
> > B redirects the call to User C at proxy 2 and user C redirects the
> > call to user D at proxy 1.
> >
> > User A            Proxy 1           Proxy 2
> > ----------------->
> > Invite B@P1
> > V: A
> > F: UserA@A
> > T: UserB@P1
> > I: 1234@A
> > Cseq: 1 INVITE
> >                   ----------------->
> >                   Invite C@P2
> >                   V: P1
> >                   V: A
> >                   F: UserA@A
> >                   T: UserB@P1
> >                   I: 1234@A
> >                   Cseq: 1 INVITE
> >                   <-----------------
> >                   Invite D@P1
> >                   V: P2
> >                   V: P1
> >                   V: A
> >                   F: UserA@A
> >                   T: UserB@P1
> >                   I: 1234@A
> >                   Cseq: 1 INVITE
> >
> > At this point, proxy 1 will reject the call with a 482 Loop Detected.
> > This is despite the fact that it is a new request for a different
> > request URI.  It just happens that two users in the path of the INVITE
> > are served by the same proxy.
> >
> > Am I correct that no resolution to this problem has been proposed?
> >
> > Steve
> >
> > P.S. We have some ideas on how to address this, but first I want to
> > make sure that  I haven't missed an already proposed solution.
> >
> > P.P.S There is a second level problem lurking for stateful proxies,
> > even if we solve the via loop issue.  This is due to the fact that a
> > stateful proxy that does not detect this as a via loop will detect it
> > as a retransmission (same call leg (to, from, callid) with the same
> > cseq and probably drop the invite.
>
> --
> Jonathan D. Rosenberg                       200 Executive Drive
> Chief Scientist                             Suite 120
> dynamicsoft                                 West Orange, NJ 07052
> [email-masked]                     FAX:   (732) 741-4778
> http://www.cs.columbia.edu/~jdrosen         PHONE: (732) 741-7244
> http://www.dynamicsoft.com
>
>
>

---

From: "David R. Oran" <[email-masked]>
Date: Thu, 2 Dec 1999 15:50:03 -0500

RE: "Legal" via loops
  -----Original Message-----
  From: Donovan, Steven R. [mailto:[email-masked]]
  Sent: Thursday, December 02, 1999 11:59 AM
  To: 'David R. Oran'; Jonathan Rosenberg
  Cc: [email-masked]
  Subject: RE: "Legal" via loops

  Dave Oran wrote:

  On first blush, it appears this will work. Another approach that may be
  simpler is to allow a VIA to be marked explicitly as a "loop-barrier", so
  that any proxy doing loop detect does not look further back in the VIA
list
  than the first "loop-barrier". Any stateful proxy that intercepts
responses
  and re-issues INVITES would mark its VIA with a loop-barrier.

  Proxy 1 would'nt do this unless it had gotten a redirect back senting it
to a different Contact: header. That's why I said "a stateful proxy that
intercepts responses".

  SRD> There still needs to be a way for the proxy to store the request URI
in the via header so it can know when an INVITE for an existing transaction
is really a new request.  Jonathan's approach achieves that with the
assumption that the proxy stores the request URI in the state information
associated with the transaction.  This approach has the merit that it uses
an existing parameter to the Via header.

  True. I was trying to come up with a scheme that didn't require comparing
URIs.

  I prefer Jonathan's scheme to that.

  This seems simpler than Jonathan's proposal but may have backward
  compatibility problems. OTOH, existing proxies will falsely detect loops
no
  matter what we do, right?

  Steve

---

From: Jonathan Rosenberg <[email-masked]>
Date: Sat, 04 Dec 1999 00:08:20 -0500

>        SRD> But then how is a true loop detected?  If proxy 2, after receiving a request from proxy 1, adds its via as a
>        loop-barrier and sends the request back to proxy 1, using the same request URI as the original request to proxy 1, this
>        should be treated as a via loop.  By your rule, proxy 1 would stop its via loop detection at the loop-barrier and process
>        the request.  It is interesting that if proxy 1 is stateless then the request will be sent back to proxy 2.  If it is a stateful
>        proxy, then proxy 1 will treat the request as a retransmission. 
> 
>        Proxy 1 would'nt do this unless it had gotten a redirect back senting it to a different Contact: header. That's
>        why I said "a stateful proxy that intercepts responses". 

You are both talking about two different problems. 

Loops are prevented by two means:

1. a proxy never forwards a request to a server currently on the Via
list
2. if a proxy receives a request and the proxy already appears on the
via list, it returns a loop detected error.

In theory, with (1) always done, (2) would never happen. But, you can't
rely on it being done at another proxy, so a proxy always needs to
verify that it doesn't propagate a problem created by another proxy. The
solution I suggest is for (2). I think Dave's suggestion is targeted at
(1). He is saying that when a redirect comes, its for some "new"
address, and therefore, its OK for the proxy to recurse on it and send
the request again to servers which received the request previously. The
problem with this approach is that a request can be forwarded to a "new"
address, in addition to a server being redirected to a "new" address. As
a result, Dave's mechanism only works for half the cases. What I propose
works for all of them. Note that my proposal also means that a proxy
shouldn't do (1) at all! THis is because the loop might be a legal one,
and the proxy can't know from the Via fields alone.

-Jonathan R.