Changes in SIP from bis09 to RFC3261


by Jonathan Rosenberg

Posted to SIP List 24Jul02

There were approximately 150 changes made to bis-09 for the generation of RFC 3261. Coming up with this list was an exercise in extremely detailed and painful review of the document, something which took us a great deal of time. The vast majority of these were typos, comma insertions, indentation fixes, and so on. However, there were a few dozen changes that reflect "bug fixes" which were reported between bis-09 and RFC 3261. Here is a summary of those of any significance whatsoever (you will find most to be trivial):

* The definition of header field was not quite right. We corrected it to:

Header Field: A header field is a component of the SIP message header. A header field can appear as one or more header field rows. Header field rows consist of a header field name and zero or more header field values. Multiple header field values on a given header field row are separated by commas. Some header fields can only have a single header field value, and as a result, always appear as a single header field row.

* The definition and mechanisms for URL encoding were based on a normative reference to RFC 1738. This RFC has been obsoleted by RFC 2396. The references were updated to point to RFC 2396, and RFC 1738 was removed from the list of references.

* The specification did not define the default language for text body parts. HTTP specifies that it's ISO-8859-1. Our reference to HTTP 1.1 for the definition of the Content-Type header would lead you to believe that this is the default for SIP too. However, since SIP uses UTF-8, this default makes no sense. So, we have explicitly stated that the default charset is UTF-8. You will find this text in section 7.4.1:

"SIP messages MAY contain binary bodies or body parts. When no explicit charset parameter is provided by the sender, media subtypes of the "text" type are defined to have a default charset value of "UTF-8". "

* There are constraints on when a UAS can be stateless. Stateless UAS are really meant for handling unauthenticated requests, and are not a general behavior. As an example, you can't really be a stateless registrar. This is now explicitly called out in Section 8.2.7, first paragraph:

"..the response and resends it, just as if it were replying to the first instance of the request. A UAS cannot be stateless unless the request processing for that method would always result in the same response if the requests are identical. This rules out stateless registrars, for example."

* It was pointed out that the rules for matching a CANCEL to its transaction were not quite right if you went through the formal process. We've corrected that, with the new text in Section 9.2, paragraph 1:

"The TU determines the transaction to be cancelled by taking the CANCEL request, and then assuming that the request method is anything but CANCEL or ACK and applying the transaction" ^^^^^^

* Bis-09 defined the behavior of CANCEL on any method besides CANCEL as a "no-op". However, it didn't define what no-op meant. So, we removed the term no-op. The text, in Section 9.2, paragraph 4, now reads:

"A CANCEL request has no impact on the processing of transactions with any other method defined in this specification."

* The specification was inconsistent in its interpretation of a missing Expires header and expires contact param in a REGISTER request. One section said it meant the client means for 3600, the other said it was a server defined minimum. With the new rules on the inability of a server to reduce the client requested value, there would be no way to have the client allow the server to choose unless we went with the latter definition. So, we did. Section 10.2.1.1, last paragraph, now reads:

"If neither mechanism for expressing a suggested expiration time is present in a REGISTER, the client is indicating its desire for the server to choose."

* In REGISTER requests, the "scope" of the q-value was defined to be relative to "other bindings present in the REGISTER message or existing within the location service of the registrar". Those are two different scopes. Which is it? Its the location service within the registrar. The text in Section 10.2.1.2 now reads:

"The "q" parameter indicates a relative preference for the particular Contact header field value compared to other bindings for this address-of-record."

* bis-09 was inconsistent in its failure handling for REGISTER between Contact: * and a URI in the Contact header. In the former case, an out of sequence REGISTER did not update the specific binding with the ordering failure, but the others could be updated, and in the latter case, the update failed. Since we have specified that all request processing is atomic, the Contact: * treatment was not right. Therefore, the text in bullet 6 of Section 10.3 was updated to indicate that the update is aborted, and the request fails, in the event of a sequence error.

* The wording in section 10.3, bullet 7, was inconsistent. On one hand, it said the server had to use values when explicitly specified, but also said that it could shorten the interval. This has been clarified. The values in the Expires header or expires contact param are the client requested expirations, and the server can shorten those.

* A question arose as to whether a forked INVITE request resulted in multiple offer/answer exchanges (one for each dialog established) or just one offer/answer exchange. Its multiple. This has been clarified in Section 13.2.1, paragraph 8:

"..parameters that apply to those means, and addresses for receiving media from the offerer. An offer/answer exchange is within the context of a dialog, so that if a SIP INVITE results in multiple dialogs, each is a separate offer/answer exchange."

* Text in bis-09 seemed to imply that you could always generate a new offer in a request as long as you had no outstanding offers. However, thats true in addition to any method-specific rules, such as the ones outline for UPDATE. This has been clarified in Section 13.2.1, bullet 4:

"After having sent or received an answer to the first offer, the UAC MAY generate subsequent offers in requests based on rules specified for that method, but only if it has received answers to any previous offers, and has not sent any offers to which it hasn't gotten an answer."

* Similarly, there was some text in bis-09 which led you to believe that were only two possible offer/answer exchanges (INVITE/200 or 200/ACK) that were EVER possible. Thats not right. Its only the case for elements compliant to bis alone. If you support UPDATE, there are more possible. This is clarified in Section 13.2.1, 4th from last paragraph:

"Concretely, the above rules specify two exchanges for UAs compliant to this specification alone - the offer is in...."

* The rules for timer C in bis-09 might lead you to believe that retransmits of the INVITE can refresh timer C. Thats not so; its only provisional responses. This is now clarified in Section 13.3.1.1, next to last paragraph:

"A proxy has the option of canceling a transaction when there is a gap of 3 minutes between responses in a transaction."

* There was some confusion reported at sipit over whether a branch ID needs to be distinct for each transaction through a spiral. Many implementations apparently were inserting the same branch ID in each pass, which is not right. This has been clarified in Section 16.6, bullet point 8, first paragraph:

"This implies that the proxy will compute its own branch parameter, which will be globally unique for that branch, and contain the requisite magic cookie. Note that this implies that the branch parameter will be different for different instances of a spiraled or looped request through a proxy."

* The recommended algorithm for computing a branch ID in Section 16.6, bullet point 8, omitted the Via header in the hash. Its now been included. ^^^^^^^^^^

* The spec was inconsistent in UA and proxy handling of transport failures. A proxy was supposed to return a 400, whilst a UA, a 503. Its been made consistent to 503. This results in a change in the text of Section 16.9, which now reads:

"If the transport layer notifies a proxy of an error when it tries to forward a request (see Section 18.4), the proxy MUST behave as if the forwarded request received a 503 (Service Unavailable) response."

* It was reported that the processing of timer D in the transaction layer was wrong. This is the timer that fires in the INVITE client transaction after it has ceased waiting for retransmits of the final response, in order to send an ACK. Bis-09 said to inform the TU of a timeout. However, this is not a failure condition, so that makes no sense. As such, Section 17.1.1.2, now reads:

"If timer D fires while the client transaction is in the "Completed" state, the client transaction MUST move to the terminated state." ^ * Bis-09 defined a response retransmission as any response that matches a transaction matched by a previous response. Thats true ONLY for final responses. It doesn't work for provisional. Since there is no normative text associated with the term "response retransmission", we removed this definition entirely from Section 17.1.3.

* We clarified that, when moving to terminated state for client invite transactions, you need to delete the transaction immediately.

* The rules in Section 17.2.3, for matching a request to a transaction when the branch ID had the cookie, were not quite right. In particular, they were wrong for CANCEL. The rules were updated:

The request matches a transaction if:

1. the branch parameter in the request is equal to the one in the top Via header field of the request that created the transaction, and

2. the sent-by value in the top Via of the request is equal to the one in the request that created the transaction, and

3. the method of the request matches the one that created the transaction, except for ACK, where the method of the request that created the transaction is INVITE.

* Section 18.1.1 led you to believe that if a request was too large for UDP, and you resent it, it had to be with TCP. ACtually, it can be with any congestion controlled transport (as defined by RFC 2914). We also clarified that if you change transports, the Via transport value needs to change.

* Section 19.1.4, 4th bullet, had made reference to characters in the unsafe character set, indicating that those needed to be escape-encoded in URLs. However, RFC 2396 doesn't define "unsafe" characters - that is legacy from RFC 1738, which is obsoleted by 2396. So, the mention of unsafe characters was removed.

* It was pointed out that the lexical reordering rules for converting a tel URL to a SIP URL could result in a user part that was not a valid telephone-subscriber as defined in RFC 2806. The specific problem is that 2806 requires the isdn-subaddress and post-dial parameters to appear before any extension parameters. If you simply order the parameters without excepting these two, you might place an extension param before post-dial or isdn-subaddress, which is illegal. This has been fixed, including an example which had this problem. See Section 19.1.6.

* It was pointed out that the definition of "optional" headers in table 2/3 only discussed UA insertion of the header. However, some optional headers are only inserted by proxies (such as Record-Route). So, the definition of optional in Section 20 was updated to include any element, not just a UA.

* There were a bunch of places were the spec said "the syntax of this header is defined in Section XXX of [HXXX], referring to RFC 2616. However, we incorporated most of that syntax into bis, so these statements were no longer correct. They were removed.

* Rules for equality matching of From and To header fields were absent, even though there were references elsewhere in the text to the existence of such rules. They were added. See Sections 20.20 and 20.39.

* Section 20.22 indicated that the recommended value for Max-Forwards is 70. Of course, that is the recommended INITIAL value. That was clarified.

* The qop="auth" attribute was missing from the example Proxy-Authenticate message in Section 20.27. It was added. It was also missing from Section 20.44, and was added there too.

* The spec was inconsistent on the maximum value of the expires Contact parameter and the Expires header field. They were made consistent. The maximum value is (2**32)-1.

* Table 2/3 indicated that Retry-After was allowed in the 500 and 503 response codes, but Section 20.33 only mentioned the 503 response code. Section 20.33 was updated to include the 500 code as well.

* Section 20.35, on the Server header, had an example which led you to believe that the field was used by proxy servers. Its not - its just UAS. The example was updated to fix that.

* Section 20.37, on the Unsupported header field, failed to mention that a compact form was defined (the other headers with compact forms explicitly mention it in their section 20's). A mention was added.

* The transaction matching algorithm requires rules for equality of Via header fields, but none was defined. A rule was added, see Section 20.42.

* Section 21.4.15 indicated that inclusion of the unsupported extensions in a 420 response was a SHOULD. This is inconsistent with other text that said it was a MUST. Its a MUST. Section 21.4.15 was updated to reflect that.

* Section 22.3 mentioned that "Proxy-Authentication" header, which doesn't exist. Its "Proxy-Authenticate". It was fixed.

* Some text in Section 23.2, paragraph 3, was missing in bis-09 because of a latex conversion error. Specifically, the text should have said that the body is structured as an S/MIME multipart/signed CMS SignedData body. Its been fixed.

* Section 23.3 had an example with the Content-Transfer-Encoding header in it. This header is no longer used, and so was removed.

* Section 24.1, last paragraph, message F2, was missing the tag in the To field. It was added.

* Section 26.2.1 had a mention of the TLS_RSA_WITH_AES_128_CBC_SHA ciphersuite, but had no reference to where such a suite is defined. Its RFC 3268, and a reference to that was added.

* The BNF had this construct where there was a list of choices, and one of the elements in the choice was optional:

foo = bar / baz / [boo]

turns out, this is actually not right, since it allows for an empty value for foo, which is not what is intended. Therefore, the text that described this convention, and all usages of it in the BNF, were removed.

* The BNF for the user part of the SIP/SIPS URI allowed for an empty username and an @ sign; that is "sip:@foo.com" was valid according to the BNF. Its not. The BNF for the SIP-URI and SIPS-URI constructions was updated to correct this. Here is the change that was made (^ characters indicate where the change is):

OLD SIP-URI = "sip:" [ userinfo "@" ] hostport uri-parameters [ headers ] SIPS-URI = "sips:" [ userinfo "@" ] hostport uri-parameters [ headers ] userinfo = [ user / telephone-subscriber [ ":" password ]] user = *( unreserved / escaped / user-unreserved )

NEW SIP-URI = "sip:" [ userinfo ] hostport ^^ delete "@" uri-parameters [ headers ] SIPS-URI = "sips:" [ userinfo ] hostport ^^ delete "@" uri-parameters [ headers ] userinfo = ( user / telephone-subscriber ) [ ":" password ] "@" ^ ^ ^^^^ user = 1*( unreserved / escaped / user-unreserved ) ^

* The Accept, Accept-Encoding, and Accept-Language and Allow BNF were all updated to allow for the header to have an empty value.

* The BNF for rfc1123-date was wrong. It was missing a space after the comma. It was corrected thusly:

OLD rfc1123-date = wkday "," date1 SP time SP "GMT"

NEW rfc1123-date = wkday "," SP date1 SP time SP "GMT" ^^

* The BNF for the Timestamp header was wrong. It was missing an explicit LWS between the the send time and the delay. It was added. The BNF was changed thusly:

OLD Timestamp = "Timestamp" HCOLON 1*(DIGIT) [ "." *(DIGIT) ] [ delay ]

NEW Timestamp = "Timestamp" HCOLON 1*(DIGIT) [ "." *(DIGIT) ] [ LWS delay ] ^^^