2ping 0.0.3 has been released, with the following fixes and improvements:
- Large cleanup and documentation push -- code is now "acceptable"
- Fixed calculation of opcode data area lengths on some opcodes; implementation now incompatible with 0.0.2
- Added more checks against malformed packets; 2ping no longer produces produces Perl warnings when fuzzing
- Added a preload (-l) option, mimicking ping's -l functionality
- Added a 2ping6 symlink; 2ping will now assume -6 if called as 2ping6
- Added a message authentication code (MAC) option with a pre-shared key (--auth=key), allowing for message authentication and verification while in transit
- Added a timed interval of brief statistics output (--stats=int)
- STDOUT buffering is disabled in all modes now
- Added compatibility down to Perl 5.6.0
- Cleaned up distribution tarball, added a Makefile
- Changed man section from 1 to 8
While the draft 2ping protocol specification hasn't been changed in an incompatible way since the last release, a bug in 2ping 0.0.2 was found where length fields of some opcode data areas were not being created properly according to spec. This was fixed and now makes the 2ping 0.0.3 implementation incompatible with 2ping 0.0.2. As a reminder, protocol or implementation compatibility is not a design goal until 2ping hits version 1.0 (soon, hopefully).
Please download 2ping 0.0.3 and give it a try, thanks.
The message authentication code (MAC) feature is interesting, though not terribly useful. Its primary purpose is to prevent man-in-the middle injection attacks, though I don't suspect teh hax0rz will want to disrupt your ping stream. An IANA representative got back to me about the 2ping port application, and (among other questions) asked if 2ping supports or plans to support encryption. His angle was whether I'd come back to the IANA in the future and ask for a separate registered UDP port for an encrypted version of 2ping. (It is their policy that such applications are no longer accepted.) I replied that there is not currently a desire for an encrypted version, though the nature of the protocol would allow for adding features like encryption or authentication in the future simply by extending the protocol.
After that, I started thinking. Encryption would certainly be doable, but would require a lot of code. However cryptographic authentication would be somewhat easy to implement, similar to how the packet checksums were built.
However, there was one coding problem that would need to be overcome, and it was something I had been thinking about for awhile, so it was nice to tackle it head on. You see, in the 2ping protocol, opcode data areas are arranged in the packet by flag order. Before this release, the flags just happened to be arranged ascending in decreasing order of priority (1 is most important, 64 is least important):
- 1 - Reply requested
- 2 - In reply to
- 4 - RTT enclosed
- 8 - Investigation complete, originally replied to as requested
- 16 - Investigation complete, request never received
- 32 - Expected reply never received, please investigate
- 64 - Courtesy message ID expiration
This is important since there is limited space available in a message. 1 and/or 2 are present in virtually all messages. 4 is only a few bytes. 8, 16, 32 and 64 are groups of message IDs, and can grow quite large. However, 8 and 16 can be resent, 32 can be queued for later transmission, and 64 is optional and opportunistic. Therefore, the logic in building a message has been "run through the opcode flags order, appending opcode data areas to the end of the message packet, stopping when we run out of space".
MAC was added as flag 128, and if MAC is enabled, it must always be sent, even though its physical place is near the end of the packet. So obviously the old logic would not work. The new logic stores the computed opcode data areas in an array, but still keeping track of how long the final message will be, and stopping where appropriate. Then the contents of the array are combined to form the completed message. With that in place, it was a simple order to logically build the array in order of priority (128, 1, 2, 4, 8, 16, 32, 64), then physically arrange it according to the spec (1, 2, 4, 8, 16, 32, 64, 128).
All currently supported MAC digests in 2ping use HMAC, though supporting additional HMAC or non-HMAC digests is possible in the future. The current list is: HMAC-MD5 (default since Digest::MD5 is part of base Perl), HMAC-SHA1 and HMAC-SHA256 (Digest::SHA), and HMAC-CRC32 (Digest::CRC). If you know cryptography, you should be chuckling at that last one right about now.
Shortly after writing this, I went back and implemented optional packet CBC encryption with Blowfish, DES or AES. It actually didn't require much code. The entire packet payload was built like normal, encrypted, then wrapped in a stub 2ping-compatible packet with a single opcode indicating an encrypted payload was enclosed. Quite elegant, really.
Then I threw it all away. After talking with some friends, I confirmed that it's just too dangerous implementing an encryption model if you're not an expert on the subject. And I'm not an expert on the subject. Having no encryption is better than having encryption that gives you a false sense of security. Still, perhaps some day, and it's nice to know that I verified the core 2ping protocol design could accommodate it.