The trouble with TCP — It’s good but we’re stuck with it
TCP is possibly one of the most admired and least loathed protocols, you just have to find a bitter systems researcher and ask them what doesn’t suck that much. Sometimes they’ll say UTF-8, but TCP is also at the top of the list (which is good, because most of the internet is built atop of it).
TCP carries email, webpages, and a whole slew of data between computers, providing a reliable, ordered stream of data atop an unreliable, unordered IP network — but TCP isn’t perfect, and has a long history of unused or broken features.
For example: when the network became congested, older versions of TCP would retransmit aggressively, causing congestive collapse, bringing the entire internet to a halt.
Another problem was SYN flooding, where a computer could be tricked into exhausting all of its connections, but this was eventually solved by adding SYN Cookies. Some features, such as TCP urgent, have never worked in practice..
TCP has some design flaws, but sometimes the problems are with how TCP is implemented and used — TCP is a reliable ordered stream over a series of messages, but many protocols are a series of messages over TCP — forcing implementations to work around or re-implement TCP’s features.
Although TCP provides reliable delivery, an acknowledgement only says that the computer has received a message, not processed it. Applications must implement their own acknowledgements atop to ensure that the data has been processed.
Some protocols attempt multiplexing or pipelining too, issuing concurrent commands over a single connection, and encounter head of line blocking— where the ordered delivery gets in the way of multiplexing the messages. They also have to implement flow control, framing, and timeouts too.
There is an alternative protocol, SCTP, which promises to be a better transport for these messages, built around messages rather than streams, but it hasn’t taken off. Why? We’re stuck with TCP.
TCP’s greatest design decision was the end-to-end principle, in that only the computers communicating had to worry about reliability and ordering, and the computers in-between could pass around messages in delightful ignorance. This is no longer true.
Now TCP is burnt into the routers, firewalls, and home equipment, it’s really hard to send something that isn’t TCP (or UDP) over the network. TCP is also burnt into the operating systems too, it’s impossible for applications to change TCP’s behaviour to suit their needs.
If we admit TCP is fossilised, is this admitting defeat? Not yet. The TCP Minion project attempts to work around TCP as found to evolve the protocol, even if the wire format stays the same. Alternatively, we can just re-implement TCP over UDP, over and over again.