For the last week or so, I’ve been tasked with implementing Application Simulators in the BreakingPoint product for the OWAMP and TWAMP protocols, RFC 4656 and RFC 5357, respectively. These are honestly two of the most poorly written protocol specifications that I’ve ever read. Luckily, they’re rather short. Not only are many parts vague and ambiguous, but some parts read like a stream-of-consciousness dump directly to a text editor.
Things not to do when writing a protocol specification:
- Don’t write a specification where every other paragraph says something like “X in this protocol works exactly like X in this other protocol [reference]” (occasionally with a very slight modification). TWAMP does this, since it’s essentially just a slightly modified version of OWAMP. Just update the other protocol’s spec and re-name the protocol if necessary. If I were this protocol’s designer, I would have just shortened the protocol name to AMP and updated the single spec to define it operating in two modes, one-way and two-way, and conveyed the few differences in the single spec.
- Along that same line of reasoning, if you’re going to make a slight modification to something in that other protocol for your new protocol, do it consistently. In this section, TWAMP describes a slightly modified version of a message from OWAMP, completely omitting some fields that are no longer necessary while nulling out other fields that are also no longer necessary. Why the distinction? If this truly is a new and separate protocol, just remove all the unnecessary fields…
- Be clear in what something means. Perhaps define terminology used in your specification. In this section, OWAMP describes a Set-Up-Response message where depending on the mode value, some other fields are “unused.” What exactly does that mean? Does it mean they’re present, but nulled out or otherwise ignored, or does it mean that the fields are completely omitted from the message? This kind of information is important for someone trying to implement your protocol. When shown this paragraph, I’ve had friends and colleagues (test subjects) interpret this either way in roughly equal numbers.
- When something from the other spec you’re essentially copying is not used at all in your new spec, why even mention it? This further confirms my belief that these two specs really should have just been one single spec in the first place.
- Don’t make a single message structure so dynamic and multi-purposed that it has a large number of conditionals attached to it. Just make smaller, individual messages that are consistent in how they appear on the wire and are interpreted for each situation. In this section, the OWAMP spec describes the Request-Session message. Note toward the end of the fields descriptions where it gets to talking about Type-P descriptors and the avalanche of conditionals that follow relating to both that field and the Port, Conf-Sender, and Conf-Reciever fields. This makes for really ugly implementation code which in turn is more likely to contain bugs.
- I could go on, but I won’t.
From what I can tell of the protocol itself (yes, I consider both to basically be a single protocol), it’s actually fairly well thought-out, it’s just presented and described horribly by the specification and some of it’s message structures seem a bit convoluted. That’s also assuming that I’m interpreting the protocol correctly, which I may not be; it’s rather hard to tell from the specification…