I’ve written about TCP and the often-dubious wisdom of trying to replace it with something else many times – starting with TCP Considered Annoying in July of ’02, through TCP Apologists Considered Annoying and Messages vs. Streams to Live from (TCP) Vegas. It looks like it’s time for another round.

Reinventing (an inferior version of) TCP seems to be one of those rites of passage for many programmers, like designing your own programming language. Most often it’s a form of the “rewrite bug” that afflicts many junior programmers: due to a single problem (or sometimes mere “not invented here” aesthetic dislike) the programmer sets out to replace an entire complex system instead of adopting a simpler in situ solution. Usually such programmers end up creating more bugs than they fix/avoid, and at work a large part of my job is to discourage such counterproductive behavior.

In the current case, the impetus for reinventing TCP seems to be the tricky problem of “NAT traversal” in which two systems each behind an address-translating gateway or firewall are unable to establish a TCP connection. This is at least a real problem, but the proposal for “fixing” it is defective. My objection to TCP is that it only models one kind of communications behavior – two way stream-oriented communication over long links. If that’s not what you’re doing, by all means design a different protocol. If it is what you’re doing, however, I believe you should use TCP – if not an existing implementation (which might not be possible in the NAT-traversal case) then at least the protocol and thought behind it. There’s nothing wrong with implementing TCP over UDP in user space, reusing 99% of the code and replacing a tiny bit of connection-setup glop as needed, if that’s what’s necessary. It’s better than having someone with a proven bad record at protocol design create a new protocol to do the exact same thing, and commit for the hundredth time the freshman mistake of relying on IP fragmentation and reassembly to make it work.