
We have developed a declarative domain-specific language, Zebu, for describing protocol message formats and related processing constraints. Based on a Zebu specification, the Zebu compiler generates custom, fine-tuned protocol-handling layers for HTTP-like protocols. Zebu is based on the ABNF notation and therefore enables developers to reuse existing grammar specifications available in RFCs. The Zebu language provides annotations to express the message memory layout and protocol-specific constraints. These annotations decouple the message memory layout from the message format. The developer thus expresses his own view of the message, in terms of data structures and types, that will be available in the application. In addition, annotations allow the developer to express various kinds of constraints on a message and potential optimizations. For instance, the mandatory attribute marks headers that must be part of a message. This annotation leads to the generation of run-time presence verifications and validations. The lazy attribute requests on-demand parsing. When specified as lazy, a rule is decoded only when it is explicitly requested by the application.
The following excerpt of a Zebu specification illustrates the use of some of the Zebu annotations:
An important benefit of using Zebu as opposed to hand-crafted implementations is robustness. This robustness is provided by the Zebu compiler, which automatically checks specification consistency and generates parsing stubs that include validation of the message structure. We performed a mutation analysis, consisting in injecting invalid SIP messages, which showed that a Zebu-based protocol-handling layer detects every mutants. Typical SIP implementations could not detect more than 25% of them. We performed the same study with RTSP. There again, a Zebu-based protocol-handling layer detected every mutants. Tested RTSP implementations detected from 0.1% to 27% of the injected mutants. Furthermore, this robustness does not come at the expense of efficiency. Zebu-based protocol-handling layers are memory-efficient, as the memory usage is tailored to application needs. They are also as time-efficient as hand-crafted ones mainly thanks to on-demand parsing.