Monday, February 12, 2018
Tough love, or stultifying ossification? I don't know
There is “Postel's Law” in protocol design that states:
2.10. Robustness Principle
TCP implementations will follow a general principle of robustness: be conservative in what you do, be liberal in what you accept from others.
TRANSMISSION CONTROL PROTOCOL—DARPA INTERNET PROGRAM—PROTOCOL SPECIFICATION
But then there's this:
4.5 Robustness
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.
On the Design of Application Protocols
I bring this up because I recently came across this:
… The first byte of the clear data was a flags field which, he said, was promptly ossified by a middlebox vendor, leading to packets being dropped when a new flag was set.
That was a classic example of why changing network protocols is hard and what needs to be done to improve the situation. Middleboxes are the control points for the Internet as we know it now. The only defense against ossification of network protocols by middleboxes, he said at the conclusion of the talk, is encryption.
Via Hacker News, QUIC as a solution to protocol ossification [LWN.net]
And I thought, Oh crap! I do that!
More specifically, in SPCDNS
where I explicitly check for unused bits being
zero.
Am I ossifying the DNS protocol by doing this?
I did encounter this a few months ago. I was playing around with
monitoring the traffic on the home network and saw a bunch of MDNS requests flying around. I thought I
would decode them using SPCDNS
to see what exactly was being
queried when I hit a snag—some of the packets were invalid! Upon
investigation, it came down to that single undefined bit in the DNS packet being set. I quickly patched
the code (privately) to accept the packets but I didn't release the changes
since at the time, that last undefined bit was still undefined.
I didn't know how to deal with the situation then, and I still don't.
SPCDNS
can handle records it doesn't understand, but
that one undefined bit has me stymied. I could define the flag and
let a user of my code check for it, but when it does become defined, that
flag name will obviously have to change and that could be a breaking change.
But as of right now, any user code that wants to check for that bit has no
way of doing so (not that I've received any requests for it).
Then there's the fact that because my code was so fussy with verifying the packet, that bugs in other DNS implementations were found via my code. And at work, I put up a fight to remain picky in processing network packets for “Project: Sippy-Cup.” I mean, what's the point of a protocol specification if you don't follow it? I even referenced RFC-3177 (quoted above) as part of my argument for being picky. But I was overridden and had to carry on in the face of utter garbage (and yes, some of what we get is utter garbage). I did however keep track of each violation and we are in the process of talking with a vendor who is sending us garbage as I type.
This is tough.
At the time I wrote SPCDNS
, there was only one undefined bit
left in the DNS packet. Had I
written it back when RFC-1035 was written, there would have
been three undefined bits, and I ask myself how I would have handled that
over the years. I'm not even sure if I would have thought to include those
bits in what is decoded (I don't now).
This will require some thought.