Monday, Debtember 14, 2015
It's amazing that email even works at all
In general, an implementation should be conservative in its sending behavior, and liberal in its receiving behavior. That is, it should be careful to send well-formed datagrams, but should accept any datagram that it can interpret (e.g., not object to technical errors where the meaning is still clear).
That is otherwise known as Postel's Law and I contend that Law (which really isn't a “law-law” per se but more of a suggestion) has caused more bugs and interroperability issues than it prevented.
If you read the linked aritlcles (and yes, it's quite a lot of read) it becomes apparent (to me) that a lot of the issues causing issues can be directly laid at the feet of Postel's Law (and the rest to the insane design of Internet headers that came out of the “we want theoretical mathematical purity and complete flexibility in what we allow in our parsers!” school of thought popular in the 60s and 70s—which is why The Dragon Book is so hard to understand and why parsers are thought of as “things mere programmers are not meant to write” but I digress). Parsing email (heck, parsing email addresses) is difficult because the early standards were too hard to follow, and because of that, most programs were too liberal in what was accepted to the point where it may be impossible to have a properly formed email message that follows all the relevant RFCs.
I'm also reminded of a conversation I had with my manager at The Ft. Lauderdale Office of the Corporation. As I was writing “Project: Sippy-Cup” my manager kept telling me to stop being so pedantic in parsing SIP messages because it was causing issues with The Monopolistic Phone Company. Even though technically we were right and following the specifications, we were dealing with The Monopolistic Phone Company (motto: “We don't have to care!”) where what they do is right (specs be damned!). I kept complaining about it (“What's the point of a specification if no one follows it?”) but nope—I had to be more liberal in what I accepted (specs be damned!).
A well-designed protocol is robust.
Robustness and efficiency are often at odds. For example, although defaults are useful to reduce packet sizes and processing time, they tend to encourage implementation errors.
Counter-intuitively, Postel's robustness principle ("be conservative in what you send, liberal in what you accept") often leads to deployment problems. Why? When a new implementation is initially fielded, it is likely that it will encounter only a subset of existing implementations. If those implementations follow the robustness principle, then errors in the new implementation will likely go undetected. The new implementation then sees some, but not widespread deployment. This process repeats for several new implementations. Eventually, the not-quite-correct implementations run into other implementations that are less liberal than the initial set of implementations. The reader should be able to figure out what happens next.
Accordingly, explicit consistency checks in a protocol are very useful, even if they impose implementation overhead.
And yet, when I wrote SPCDNS, I was very strict in what I accepted back, to the point of sending an error if the one last reserved bit in the DNS header isn't zero. And a funny thing about that—again, at The Ft. Lauderdale Office of the Corporation, such strictness found implementation issues in other components that didn't use SPCDNS.
The email specifications have been tightened up over the years, but they still require the ability to handle older emails. But given that RFC-724 (the RFC that started us down the crazy parsing rules for email) was thirty-eight years ago, you'd think that some of the crazier parsing rules would be dropped. But no, Postel's Law and all that.