Subject: RE: [SIP] a stupid question on 3way handshake

From: Jonathan Rosenberg <[email-masked]>
Date: Sun, 19 Nov 2000 01:52:47 -0500

Sorry for taking so long to respond to many mails on the list the past few
weeks... I've been focusing on completing my dissertation...

> -----Original Message-----
> From: farhan [mailto:[email-masked]]
> Sent: Saturday, November 18, 2000 7:24 AM
> To: Billy Biggs
> Cc: SIP List
> Subject: Re: [SIP] a stupid question on 3way handshake
> 
> 
> >   I see two reasons why an ACK system is useful:
> >
> > 1. Forking.  Remember that an initial request creates many 
> call legs.
> >    Say that A sends a request to a proxy which forks in parallel to
> >    three locations:
> 
> > 2. Optimization.  The assumption in SIP is that INVITE 
> transactions take
> >    a long time, while everything else is pretty much 
> immediate.  So, in
> >    order to optimize our flow, we retransmit the INVITE 
> until we hear a
> >    provisional response, and then wait for the remote end 
> to retransmit
> >    its final response.
> >    Unfortunately, this assumption is now false, and long-outstanding
> >    requests such as REFER must be continuously 
> retransmitted to poll for
> >    the response when used over UDP.
> 
> yes billy, forking is out of question without an 
> ACKnowledgement. thanks for
> pointing this out. 

I'm sorry, but this is not correct.

Forking is fine for non-invite requests. It will result in reception of a
single response (which is, IMHO, a very nice property), which is the best
amongst all those received. Forking of non-INVITEs is therefore useful for
requests where it isn't important to know how many places received the
request; simply knowing the best response is adequate. As an example,
consider a hypothetical new request called "EXIST" which checks whether
there is a UA in the network that meets the specifications (along the lines
of caller preferences) described in the request. This request can fork to
check numerous locations, and a 200 indicates a match. In this case, the
client doesn't care how many requests were ultimately delivered, or to whom.
Just the answer matters.

I would argue that SUBSCRIBE meets this criteria as well. The caller really
doesn't care who many servers are going to be handling the subscription. So
long as some server accepts it, and generates notifications for it, thats
all that matters.

Regarding the original question, my recollection of the main motivation of
special handling for INVITE was that we believe it was the only request for
whom a response may not arrive for a long time, as it required non-automated
processing to answer. Speedy delivery of acceptance was another benefit.

In hindsight, I would have removed this special treatment. One request, one
final response. No ack. Handling cases like this one (where the "response"
might not come for a while), is more readily handled using two sepate
transactions in each direction. So, we would have a new request, called
INITIATE (instead of INVITE). A 200 response is sent as soon as the request
is received by a UAS. When the call is answered, an ACCEPT message is sent
by the called party, and responded to immediately with a 200 OK upon
receipt.

Billy writes:
Optimization.  The assumption in SIP is that INVITE 
> transactions take
>    a long time, while everything else is pretty much 
> immediate.  So, in
>    order to optimize our flow, we retransmit the INVITE until 
> we hear a
>    provisional response, and then wait for the remote end to 
> retransmit
>    its final response.
> 
>    Unfortunately, this assumption is now false, and long-outstanding
>    requests such as REFER must be continuously retransmitted 
> to poll for
>    the response when used over UDP.

Actually, I have begun to think that refer treatment should follow the
two-transaction model above. There is a serious problem otherwise. The issue
is that the INVITE triggered by the REFER may take more than 32 seconds for
an answer. If this happens, the REFER transaction will timeout before the
INVITE it triggered completes.

So, my proposal would be that REFER generates an immediate 200 OK if the
recipient is willing to try to send the request. We can then have the
recipient of REFER send a request in the reverse direction (we can debate
whether this is NOTIFY or something else) once the triggered INVITE
completes successfully. 

-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: (973) 952-5000
http://www.dynamicsoft.com

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

---

From: Billy Biggs <[email-masked]>
Date: Sun, 19 Nov 2000 02:06:14 -0600

Jonathan Rosenberg ([email-masked]):

> [...] Forking of non-INVITEs is therefore useful for requests where it
> isn't important to know how many places received the request; simply
> knowing the best response is adequate. [...]
> 
> I would argue that SUBSCRIBE meets this criteria as well. The caller
> really doesn't care who many servers are going to be handling the
> subscription. So long as some server accepts it, and generates
> notifications for it, thats all that matters.

  It matters when trying to unsubscribe.  To be intelligence-
at-the-edges correct, an unsubscribe should be sent within the call-leg
created by the original SUBSCRIBE.  However, to be forking-safe, the
unsubscribe should be sent to the orignal address which was subscribed
to, without a tag.

  It is a minor complaint.  I know that to keep my implementation clean,
a SUBSCRIBE in my stack will create a single call leg, and any NOTIFYs
received outside of that call leg will be given 481s.  I don't buy the
"[...] subscribers SHOULD be prepared to receive notifications with
previously unknown tags in the "From" field [...]" argument.  Oh well.

> > The assumption in SIP is that INVITE transactions take a long time,
> > while everything else is pretty much immediate.  So, in order to
> > optimize our flow, we retransmit the INVITE until we hear a
> > provisional response, and then wait for the remote end to retransmit
> > its final response.
> > 
> > requests such as REFER must be continuously retransmitted to poll
> > for the response when used over UDP.
> 
> two-transaction model above. There is a serious problem otherwise. The
> issue is that the INVITE triggered by the REFER may take more than 32
> seconds for an answer. If this happens, the REFER transaction will
> timeout before the INVITE it triggered completes.

  As well, there is no way to tell if the far end accepted the REFER and
is processing it, or if it will eventually return a 501.  Responding to
REFER immediately helps with error checking.

  We would also be less likely to have to worry about multiple
outstanding transactions on a call-leg.

  However, it is much more verbose, and a major change to the REFER
draft.  These were the two reasons I didn't suggest it earlier.  I might
submit a BYE/Also transfer draft if this proposal flies, or maybe
advocate louder it be added to bis.  Thoughts?

> So, my proposal would be that REFER generates an immediate 200 OK if
> the recipient is willing to try to send the request. We can then have
> the recipient of REFER send a request in the reverse direction (we can
> debate whether this is NOTIFY or something else) once the triggered
> INVITE completes successfully. 

  I'm all for it.

-- 
Billy Biggs, 3Com               Email: [email-masked]
http://www.div8.net/billy/      Phone: [email-masked]

---

From: Vijay Gurbani <[email-masked]>
Date: Sun, 19 Nov 2000 13:23:10 -0600

Jonathan Rosenberg wrote:
[...]
> request; simply knowing the best response is adequate. 
[...]

Except when multiple downstream UASes return a "best" response to a forked
non-INVITE request.  A while ago, we had a similar dialog regarding the
forking of a non-INVITE request like OPTIONS.  A forking proxy would send
the initial OPTIONS to several branches downstream; suppose 2 branches
returned a 200 OK.  Then the proxy would send the first 200 OK received up-
stream; absord the second 200 OK and send CANCEL on the remaining branches. 
Or the proxy could simply send multiple 200 OKs upstream and hope the UAC
can sort them out and pick the "best".

From a proxy's point of view, what exactly to do when multiple downstream 
UASes return a "best" response should be codified, IMHO.  Otherwise, we 
could run into scenarios where on certain requests the proxy ONLY sends one 
"best" response upstream and in other cases it must send all "best"
responses received upstream and leave the arbitration to the UAC.

- vijay
-- 
Vijay K. Gurbani  vkg@{lucent.com,research.bell-labs.com,acm.org}
Internet Software and eServices Group 
Lucent Technologies/Bell Labs Innovations 263 Shuman Blvd., Rm 1A-413
Naperville, Illinois 60566     Voice: +1 630 224 0216   Fax: +1 630 713 0184

---

From: Billy Biggs <[email-masked]>
Date: Sun, 19 Nov 2000 14:16:30 -0600

Vijay Gurbani ([email-masked]):

> > Forking is fine for non-invite requests. It will result in reception
> > of a single response (which is, IMHO, a very nice property), which
> > is the best amongst all those received. Forking of non-INVITEs is
> > therefore useful for requests where it isn't important to know how
> > many places received the request; simply knowing the best response
> > is adequate. 
> [...]
> 
> Except when multiple downstream UASes return a "best" response to a
> forked non-INVITE request.  A while ago, we had a similar dialog
> regarding the forking of a non-INVITE request like OPTIONS.  A forking
> proxy would send the initial OPTIONS to several branches downstream;
> suppose 2 branches returned a 200 OK.  Then the proxy would send the
> first 200 OK received up- stream; absord the second 200 OK and send
> CANCEL on the remaining branches.  Or the proxy could simply send
> multiple 200 OKs upstream and hope the UAC can sort them out and pick
> the "best".

  The behavior is the same as for INVITE requests.  If you receive
multiple 200 OK responses, you MUST forward them up.  That has been the
consensus from everyone I've ever spoken with.

  However, since these responses are 'unreliable', dropping them is
simply a simulation of bad network conditions, but I wouldn't recommend
it.

  I was pretty sure this is spelled out in 2543, but I can't find an
appropriate quote.  Maybe it should be better spelled out.

---

From: Vijay Gurbani <[email-masked]>
Date: Sun, 19 Nov 2000 14:59:00 -0600

Billy Biggs wrote:
[...]
> consensus from everyone I've ever spoken with.

Hmmm, let's see...the RFC does indicate that a forking proxy MAY terminate
pending INVITE requests on other branches when it gets a 200 OK for at least 
one branch.  Following this logic, it proxies the 200 OK it got _first_ up-
stream and sends a CANCEL on all other branches.  Say it gets another 200
OK (INVITE) after it has send a CANCEL; the proxy can rest assured that the
CANCEL and the 200 OK (INVITE) "crossed each other on the wire."  Thus it
can locally ACK the 200 OK (INVITE) and then send a BYE on that branch.

So, what I was trying to get at is that a proxy may exhibit the behavior I 
describe above and only send the first 200 OK upstream; further 200 OK 
(INVITE) maybe processed locally.  

Certainly this is not be true for all requests.  It could very well be that 
forking proxies MUST send all 2xx responses to non-INVITE forked requests 
upstream as soon as they get it.  For INVITE requests, they may exhibit
the behavior described above.  We should simply state that in the RFC so 
there are no ambiguities.

- vijay

---

From: Billy Biggs <[email-masked]>
Date: Sun, 19 Nov 2000 15:42:19 -0600

Vijay Gurbani ([email-masked]):

> > multiple 200 OK responses, you MUST forward them up.  That has
> > been the consensus from everyone I've ever spoken with.
> 
> Hmmm, let's see...the RFC does indicate that a forking proxy MAY
> terminate pending INVITE requests on other branches when it gets a 200
> OK for at least one branch.  Following this logic, it proxies the 200
> OK it got _first_ up- stream and sends a CANCEL on all other branches.
> Say it gets another 200 OK (INVITE) after it has send a CANCEL; the
> proxy can rest assured that the CANCEL and the 200 OK (INVITE)
> "crossed each other on the wire."  Thus it can locally ACK the 200 OK
> (INVITE) and then send a BYE on that branch.

  Sorry, but that would be really really evil.

  From RFC2543, 12.4:

   2xx: The proxy MUST forward the response upstream towards the client,
        without sending an ACK downstream. After receiving a 2xx, the
        server MAY terminate all other pending requests by sending a
        CANCEL request and closing the TCP connection, if applicable.

  It's up to the client to BYE any additional calls -if it wants to-,
not the proxy.  It's perfectly acceptable to make one call and have two
seperate locations pick up!

  The text reads that the proxy MUST not ACK the response locally to
protect the UA.  That is for any 2xx responses received.  There might be
reasons why the proxy would choose not to cancel the other branches (if
there are no other branches?  if the other branch is a call logger?  who
knows), and I think that is why the MAY is there.

  This behavior is the same for non-INVITE requests.  I guess it could
be stated more explicitly though.