Subject: SIP: more comments

From: Anders Kristensen <[email-masked]>
Date: Wed, 14 Oct 1998 15:40:56 +0100

More issues on the sip-09 spec.

  -- Anders

10.3 TCP
   "If a client closes a connection or the connection is reset (e.g.,
   because the client has crashed and rebooted), the server treats this
   as equivalent to having received a CANCEL request  for all pending
   transactions."

This directly contradicts what you said two paragraphs earlier:

  "The client MAY close the connection at any time..."

I think you have to allow the client to close the connection.

10.4.1 UDP
   "The server responds immediately upon receipt of the
   CANCEL request rather than not waiting until it has received final
   responses from the CANCEL requests it generates."

Loose the "not".

10.5.2 TCP

   "A client using TCP MUST NOT retransmit requests, but uses the same
   algorithm as for UDP (Section 10.5.1) to retransmit responses until
   it receives an ACK. (An implementation can simply set T1 and T3 to
   infinity and otherwise maintain the same state diagram.)"

This means there is a problem with a UAC using TCP to connect to a
stateless proxy which itself uses UDP as requests won't get
retransmitted.

        "It is necessary to retransmit 2xx responses as their
        reliability is assured end-to-end only. If the chain of
        proxies has a UDP link in the middle, it could lose the
        response, with no possibility of recovery. For simplicity,
        we also retransmit non-2xx responses, although that is not
        strictly necessary."

But this is true whenever you have a stateless proxy on the chain. If
there is a stateless proxy on the chain receiving message using TCP
and forwarding them using UDP *any* message can be lost. This can
happen with simple UAs which uses only TCP.

Ways to deal with this:
  1. always use retransmissions, even with TCP
  2. Do away with TCP as a transport altogether
  3. allow a UAC to require a stateless proxy on a chain to fail a
     request
  4. require that stateless proxies not use UDP on outgoing
     connections when the message came in on a TCP connection.

1 and 2 are just for keeping an open mind ;-). I think 4 is a
reasonably reasonable solution (so to speak). It qualifies the
transport selection scheme described in section 1.4.2.

12.4 Forking Proxy

There are a couple of "oddities" in the code. I realize of course that
this is pseudo-code and non-normative at that, but it's probably still
worth sanitizing it. While having the code is not strictly speaking
necessary, I think it's definitely desirable in terms of making the
text more understandable.

Anyway, the bugs are as follows.

       struct {
         address_t address;  /* address */
         int branch;         /* branch id */
         int done;           /* has responded */
       } outgoing[];

The 'address' field is not used anywhere.

         /* CANCEL: respond, fork and wait for responses */
         else if (class < 0) {
           best.status = 200;
           response(best);
           for (i = 0; i < N; i++) {
             request(CANCEL, address[i], outgoing[i].branch);
           }
           best.status = -1;
         }

You should only CANCEL requests for which a final response hasn't yet
been received, ie should test on 'outgoing[i].done' inside loop.

         if (class == 2) {
           if (r.status < best) best = r;
           break;
         }

should say 'if (r.status < best.status) ...'.

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

---

From: Henning Schulzrinne <[email-masked]>
Date: Wed, 14 Oct 1998 13:37:41 -0400

> I think you have to allow the client to close the connection.

The client can close the connection, but one could argue that it
shouldn't do that unless it has received the final response or is no
longer interested in the transaction (i.e., implicitly CANCELs the
transaction). Any reason why a client would close the TCP connection
earlier?

Note that, strictly speaking, the two sentences don't contradict each
other, since the client MAY indeed close at any time, but then suffer
the well-defined consequences (i.e., canceled call).

> transport selection scheme described in section 1.4.2.

One could argue that stateless proxies with TCP are kind of odd beasts,
since if you want any efficiency, a proxy is not just going to drop the
incoming TCP connection and then reopen it when the response comes back
its way.

Thus, solution 4 seems a reasonable restriction on stateless proxy
behavior.

> 12.4 Forking Proxy

Fixed.