Thursday, August 17, 2006

RFC Speak

So, at the start of most modern RFCs there is a section called "Terminology" that refers back to RFC 2119. In there, there are definitions of "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" and "OPTIONAL". I have to read a LOT of RFCs as I build the SIP/RTP stuff for the mothership, and these always anger me.

To simplify things a little bit, here's the equivalence list:

  • "MUST", "SHALL" and "REQUIRED" are all the same
  • "MUST NOT" and "SHALL NOT" are the same
  • "SHOULD" and "RECOMMENDED" are the same
  • "SHOULD NOT" and "NOT RECOMMENDED" are the same
  • "MAY" and "OPTIONAL" are the same
That part is pretty obvious.

I have basically come to the conclusion that "SHOULD", "RECOMMENDED", "SHOULD NOT", "NOT RECOMMENDED", "MAY" and "OPTIONAL" should be removed from the list of available terms that people can use when writing an RFC.

Why?

RFCs have basically become requirements specifications for protocols, extensions, etc. They are not really "Requests For Comments" anymore, as the RFC Draft process has replaced that. Once something has become an RFC it has been vetted by peers in the field and has likely had at least some experimental (or otherwise) implementation. If we are specifying the behavior of a system we can't depend on any of the optional bits, nor can we expect anything we are integrating with to pay attention to them. Any portion of an RFC that is specified as a "SHOULD" should perhaps be an extension. The specification for that extension could then use "MUST" to more clearly specify its requirements.

As a simple example, take the interpretation of the "Expires" header in a REGISTER request from the SIP rfc:

Implementations MAY treat values larger than 232-1 (4294967295 seconds or 136 years) as equivalent to 232-1. Malformed values SHOULD be treated as equivalent to 3600.
This is what I would LOVE to have seen:
Values larger and 232-1 and malformed values MUST result in a 400 (Invalid Request)
or, "if you send garbage, I'm not going to process it". Why should every implementation out there have to "fix" things like this? This type of loose specification only serves to promote laziness, bad code, and unpredictable behavior.

0 comments: