RFC 1263
TCP Extensions Considered Harmful
TCP EXTENSIONS CONSIDERED HARMFUL ๐
okay bestie, this is RFC 1263 ๐ Here's the title block so you know what you're looking at:
- Network Working Group, Request for Comments: 1263
- Written by S. O'Malley and L. Peterson, both at the University of Arizona
- Dated October 1991 ๐ฆ
- Its header has no Obsoletes or Updates line, so it doesn't list anything it replaces or changes
Status of this Memo โจ
This memo gives information to the Internet community. It isn't an Internet standard. Distribution of this document is unlimited, so share away ๐
Abstract ๐ธ
This RFC is commenting on recent proposals to extend TCP. Its argument is that the backward compatible extensions proposed in RFC's 1072 and 1185 shouldn't be pursued, and it suggests a different way to evolve the Internet protocol suite. The whole point is to get the Internet community talking about it ๐ฃ๏ธ
1. Introduction ๐ธ
The Internet has gotten so big, so fast, with so much more capacity and complexity, that the protocol suite needs to change. Take the maximum TCP window size: it's no longer enough to efficiently support the high capacity links that are being planned and built right now. So you're stuck choosing between two options. You can leave the protocol alone and accept that TCP will run no faster on high capacity links than on low capacity ones, or you can change TCP. And this isn't a one-off situation. We've counted at least eight other proposed changes to TCP (some deserve more serious attention than others) ๐ญ So the real question isn't whether to change the protocol suite. It's what the most cost effective way to change it is.
This RFC compares the costs and benefits of three approaches: creating new protocols, backward compatible protocol extensions, and protocol evolution. The next section introduces all three and lists the strengths and weaknesses of each. The section after that describes how we believe these three approaches are best applied to the many proposed TCP changes. Heads up, though: we didn't write this as an academic exercise ๐ Our goal is to argue against accepting the various TCP extensions, most notably RFC's 1072 and 1185 [4,5], by presenting a more palatable alternative ๐ฅ
2. Creation vs. Extension vs. Evolution โญ
2.1. Protocol Creation ๐ฆ
Protocol creation means designing, implementing, standardizing, and distributing an entirely new protocol. There are two basic reasons to do this. The first is replacing an old protocol that's so outdated it can't be effectively extended to do its original job. The second is adding a new protocol because users are making demands on the original protocol that the designer never imagined, and those demands can't be handled efficiently within the original protocol. For example, TCP was designed as a reliable byte-stream protocol, but it's commonly used as a reliable record-stream protocol and a reliable request-reply protocol too, because the Internet protocol suite doesn't have those. The performance demands placed on a byte-stream protocol in the new Internet environment make it hard to extend TCP to meet these new application demands ๐
The upside of creating a new protocol is getting to start with a clean sheet of paper when you're tackling a complex network problem โจ The designer, free from the constraints of an existing protocol, can take maximum advantage of modern network research in the basic algorithms needed to solve the problem. Even better, the implementor is free to steal from the large number of academic protocols that have been developed over the years ๐ง And if truly new functionality is wanted, creating a new protocol is sometimes the only viable approach.
The most obvious downside is the high cost of standardizing and distributing an entirely new protocol. Second, there's the issue of making the new protocol reliable. New protocols haven't gone through years of network stress testing, so they often contain bugs that need backward compatible fixes, and the designer ends up right back where they started ๐ฉ A third disadvantage is that new protocols generally come with new interfaces, and those take significant effort from the Internet community to adopt. Honestly, that alone is often enough to kill a new protocol ๐
Finally, there's a subtle problem caused by the very freedom this approach gives you. Being able to introduce a new protocol often results in protocols that go far beyond the basic needs of the situation. New protocols are like Senate appropriations bills: they pile up amendments that have nothing to do with the original problem ๐ A good example of this phenomenon is the attempt to standardize VMTP [1] as the Internet RPC protocol. VMTP was already a large protocol to begin with, but the closer it got to standardization, the more features got added until it essentially collapsed under its own weight ๐ As we argue below, new protocols should initially be minimal, and then evolve as the situation dictates ๐ธ
2.2. Backward Compatible Extensions ๐
With a backward compatible extension, the protocol is modified so the new version can transparently inter-operate with existing versions. This generally means no changes to the protocol's header. TCP slow start [3] is an example of this kind of change. In a slightly more relaxed version of backward compatibility, nothing changes in the fixed part of the header. Instead, either some fields get added to the variable length options field at the end of the header, or existing header fields get overloaded (meaning used for multiple purposes). Still, we can find no real advantage to this technique over simply changing the protocol ๐ค
Backward compatible extensions are widely used to modify protocols because there's no need to synchronize the distribution of the new version. The new version is basically allowed to diffuse through the Internet at its own pace, and at least in theory, the Internet keeps working as before ๐ So the explicit distribution costs are limited. Backward compatible extensions also dodge the bureaucratic costs of standardizing a new protocol. TCP is still TCP, and the approval cost of modifying an existing protocol is much less than that of a new one ๐ Finally, the sheer difficulty of making these changes tends to keep them down to the minimal set needed to solve the current problem. So it's rare to see unneeded changes made with this technique ๐
Unfortunately, this approach has several drawbacks. First, the time to distribute the new version to all hosts can be quite long (forever, in fact) ๐ญ This leaves the network in a heterogeneous state for long periods of time. If there's the slightest incompatibility between old and new versions, chaos can result. So the implicit cost of this type of distribution can be quite high ๐ซ Second, designing a backward compatible change to a new protocol is extremely difficult, and the implementations "tend toward complexity and ugliness" [5]. The need for backward compatibility means no code can ever really be eliminated from the protocol. Since that vestigial code is rarely executed, it's often wrong ๐ Finally, most protocols have limits, based upon the design decisions of their inventors, that simply cannot be side-stepped this way.
2.3. Protocol Evolution ๐
Protocol evolution is an approach to protocol change that tries to escape the limits of backward compatibility without taking on all the costs of creating new protocols ๐ฆ The basic idea is for the protocol designer to take an existing protocol that needs modification and make the desired changes without maintaining backward compatibility. This drastically simplifies the designer's job. For example, the limited TCP window size could be fixed by changing the window size in the header from 16-bits to 32-bits, and then recompiling the protocol. The effect of backward compatibility would be ensured by simply keeping both the new and old versions running until most machines use the new version. Since the change is small and invisible to the user interface, it's a trivial problem to dynamically select the correct TCP version at runtime. How this is done is discussed in the next section ๐ง
Protocol evolution has several advantages. First, it's by far the simplest type of modification to make to a protocol, so the modifications can be made faster and are less likely to contain bugs ๐โโ๏ธ There's no need to worry about the effects of the change on all previous versions of the protocol. Also, most of the protocol is carried over into the new version unchanged, which avoids the design and debugging cost of creating an entirely new protocol. Second, there's no artificial limit to how much change can be made, so the protocol's useful lifetime can be extended indefinitely โพ๏ธ Through a series of evolutionary steps, it's possible to make fairly radical changes without greatly upsetting the Internet community. Specifically, you can both add new features and remove features that are no longer required for the current environment. So the protocol isn't condemned to grow without bound ๐ Finally, by keeping the old version around, backward compatibility is guaranteed. The old code will work as well as it ever did ๐
Assuming the infrastructure described in the following subsection, the only real disadvantage of protocol evolution is the memory required to run several versions of the same protocol. Luckily, memory isn't the scarcest resource in modern workstations (it may, however, be at a premium in the BSD kernel and its derivatives) ๐ป Since old versions may rarely, if ever, be executed, they can be swapped out to disk with little performance loss. Finally, since this cost is explicit, there's a huge incentive to eliminate old protocol versions from the network ๐ฅ
2.4. Infrastructure Support for Protocol Evolution โจ
okay so the whole point of protocol evolution is that every protocol is basically a vector of implementations that all share the same top level interface, and maybe not much else ๐
. TCP[0] is the current implementation of TCP and it's there to keep backward compatibility with all the existing machines ๐ซถ. TCP[1] is a version optimized for high-speed networks ๐. TCP[0] is always present, while TCP[1] may or may not be ๐ธ. Treating TCP as a vector of protocols only takes three changes to how we design and implement things ๐.
First, each version of TCP gets its own unique id, but that id is not given as an IP protocol number ๐. This is because IP's protocol number field is only 8 bits long and could easily run out ๐. The "obvious" fix would be to make that field 32 bits, but here the obvious solution is wrong ๐. It's not because changing IP is hard. It's because there's a better approach โจ. The best way to handle this is to increase the IP protocol number field to 32 bits and move it to the very end of the IP header (i.e., the first four bytes of the TCP header). A backward compatible modification would be made to IP so that for all packets with a special protocol number, say 77, IP looks into the four bytes following its header for its de-multiplexing information. On systems that don't support a modified IP, an actual protocol 77 would be used to do the de-multiplexing to the correct TCP version ๐ง.
Second, a version control protocol called VTCP is used to pick the right version of TCP for a particular connection ๐. VTCP is an example of a virtual protocol, as introduced in [2]. Application programs reach the various versions of TCP through VTCP. When a TCP connection is opened to a specific machine, VTCP checks its local cache to find the highest common version shared by the two machines ๐ฅ. If the target machine is in the cache, VTCP opens that version, hands the connection back to the protocol above, and doesn't affect performance โญ. If the target machine isn't in the cache, VTCP sends a UDP packet to the other machine asking which versions of TCP it supports ๐ฆ. If it gets a response, it uses that info to pick a version and stores it in the cache ๐. If no reply is forthcoming, VTCP assumes the other machine doesn't support VTCP and tries to open a TCP[0] connection ๐ญ. VTCP's cache gets flushed occasionally so that its information stays current ๐.
Note that this is only one possible way for VTCP to decide which version of TCP to use ๐. Another option is for VTCP to learn the right version for a particular host when it resolves the host's name. That is, version information could be stored in the Domain Name System ๐. It's also possible that VTCP takes the performance characteristics of the network into account when picking a version. TCP[0] may actually turn out to be the correct choice for a low-bandwidth network ๐ข.
Third, because our proposal would lead to a more dynamically changing network architecture, we'll need a mechanism for distributing new versions ๐ฆ. This is clearly the hardest requirement of the infrastructure ๐ค, but we believe it can be addressed in stages ๐ช. More importantly, we believe this problem can be addressed after the decision has been made to go the protocol evolution route ๐ .
In the short term, we're only considering a single new version of TCP, which is TCP[1] ๐. This version can be distributed in the same ad hoc way, and at exactly the same cost, as the backward compatible changes suggested in RFC's 1072 and 1185 ๐ซถ.
In the medium term, we picture the IAB approving new versions of TCP every year or so ๐ . Given that, a simple distribution mechanism can be designed based on software distribution mechanisms that have been developed for other environments, e.g., Unix RDIST and Mach SUP ๐ ๏ธ. Such a mechanism need not be available on all hosts. Instead, hosts get divided into two sets: those that can quickly be updated with new protocols, and those that cannot ๐ธ. High performance machines that use high performance networks will need the most current version of TCP as soon as it's available, so they have incentive to change ๐. Old machines that are too slow to drive a high capacity line can be ignored, and honestly, they probably should be ignored ๐.
In the long term, we picture protocols being designed on an application by application basis, without needing central approval ๐ฆ. In that world, a common protocol implementation environment, which we call a protocol backplane, is the right way to go ๐ง. Given a backplane like that, protocols can be automatically installed over the network ๐. We claim to know how to build such an environment, but that discussion is beyond the scope of this paper ๐.
2.5. Remarks ๐ญ
Each of these three methods has its advantages ๐. When they're used in combination, the result is better protocols at a lower overall cost ๐ค. Backward compatible changes are best reserved for changes that don't affect the protocol's header and don't require that the instance running on the other end of the connection also be changed ๐. Protocol evolution should be the primary way of dealing with header fields that are no longer large enough, or when one algorithm is substituted directly for another ๐. New protocols should be written to offload unexpected user demands on existing protocols, or, even better, to catch those demands before they start โจ.
There are also some synergistic effects, and they're honestly iconic ๐ฅ. First, since we know it's possible to evolve a newly created protocol once it's been put in place, the pressure to add unnecessary features should be reduced ๐งน. Second, the ability to create new protocols removes the pressure to overextend a given protocol ๐. Finally, the ability to evolve a protocol removes the pressure to maintain backward compatibility where it really isn't possible ๐ .
3. TCP Extensions: A Case Study ๐ฌ
This section looks at what happens when we use our proposed methodology to implement changes to TCP ๐. We'll start by analyzing the backward compatible extensions defined in RFC's 1072 and 1185, and then propose a set of much simpler evolutionary modifications ๐ง . We also analyze several more problematical extensions to TCP, such as Transactional TCP ๐ฌ. Finally, we point out some areas of TCP that may need changes in the future ๐ฎ.
The evolutionary modification to TCP that we propose includes all of the functionality described in RFC's 1072 and 1185, but it does not preserve the header format ๐. At the risk of being misunderstood as believing backward compatibility is a good idea (it's not, bestie ๐ญ), we also show how our proposed changes to TCP can be folded into a backward compatible implementation of TCP ๐ซถ. We do this as a courtesy for those readers who can't accept the possibility of multiple versions of TCP ๐ธ.
3.1. RFC's 1072 and 1185 ๐
3.1.1. Round Trip Timing โฑ๏ธ
In RFC 1072, a new ECHO option is proposed that lets each TCP packet carry a timestamp in its header ๐ฐ๏ธ. This timestamp is used to keep a more accurate estimate of the RTT (round trip time), which decides when to re-transmit segments ๐. In the original TCP algorithm, the sender manually times a small number of sends. The resulting algorithm was quite complex and doesn't produce an accurate enough RTT for high capacity networks ๐ต. Including a timestamp in every header both simplifies the code needed to calculate the RTT and improves the accuracy and robustness of the algorithm โจ.
The new algorithm proposed in RFC 1072 doesn't appear to have any serious problems ๐. However, the authors of RFC 1072 go to great lengths to keep this modification backward compatible with the previous version of TCP ๐. They place an ECHO option in the SYN segment and state, "It is likely that most implementations will properly ignore any options in the SYN segment that they do not understand, so new initial options should not cause problems" [4]. Ngl, this statement does not exactly inspire confidence ๐ฌ. We consider the addition of an optional field to any protocol to be a de-facto, if not a de-jure, example of an evolutionary change ๐งพ. Optional fields simply attempt to hide the basic incompatibility inside the protocol. They don't eliminate it ๐ โโ๏ธ. Therefore, since we're making an evolutionary change anyway, the only modification to the proposed algorithm is to move the fields into the header proper ๐ฆ. Thus, each header will contain 32-bit echo and echo reply fields ๐. Two fields are needed to handle bi-directional data streams ๐.
3.1.2. Window Size and Sequence Number Space ๐ช
Long Fat Networks (LFN's) are networks that contain very high capacity lines with very high latency ๐ฃ๏ธ. They introduce the possibility that the number of bits in transit (the bandwidth-delay product) could exceed the TCP window size, which would make TCP the limiting factor in network performance ๐. Worse yet, the time it takes the sequence numbers to wrap around could be reduced to a point below the MSL (maximum segment lifetime), which introduces the possibility of old packets being mistakenly accepted as new ๐ฑ.
RFC 1072 extends the window size through the use of an implicit constant scaling factor ๐งฎ. The window size in the TCP header is multiplied by this factor to get the true window size ๐ข. This algorithm has three problems, and I need you to pay attention, bestie ๐ซต. First, one must prove that at all times the implicit scaling factor used by the sender is the same as the receiver's ๐ค. The proposed algorithm appears to do so, but its complexity creates the opportunity for poor implementations to affect the correctness of TCP ๐ซ . Second, the use of a scaling factor complicates the TCP implementation in general, and it can have serious effects on other parts of the protocol ๐.
A final problem is what we characterize as the "quantum window sizing" problem ๐. Assuming the scaling factors will be powers of two, the algorithm right shifts the receiver's window before sending it. This effectively rounds the window size down to the nearest multiple of the scaling factor ๐. For large scaling factors, say 64k, this implies that window values are all multiples of 64k and that the minimum window size is 64k. Advertising a smaller window is impossible ๐ซ. While this isn't necessarily a problem (and it seems to be an extreme solution to the silly window syndrome), what effect this will have on the performance of high-speed network links is anyone's guess ๐คทโโ๏ธ. We can imagine this extension leading to future papers entitled "A Quantum Mechanical Approach to Network Performance" ๐งชโ๏ธ๐.
RFC 1185 is an attempt to get around the problem of the window wrapping too quickly, without explicitly increasing the sequence number space ๐. Instead, the RFC proposes using the timestamp from the ECHO option to weed out old duplicate messages ๐ต๏ธโโ๏ธ. The algorithm presented in RFC 1185 is complex and has been shown to be seriously flawed at a recent End-to-End Research Group meeting ๐จ. Attempts are currently underway to fix the algorithm presented in the RFC ๐ ๏ธ. Honestly? We believe this is a serious mistake ๐ค๐ซถ
We see two problems with this approach on a super fundamental level ๐ First, making TCP depend on accurate clocks for correctness is, honestly, a mistake ๐ The Internet community has NO experience with transport protocols that depend on clocks for correctness. Zero. Second, the proposal uses two distinct schemes to deal with old duplicate packets ๐ญ The sliding window algorithm handles the "new" old packets (packets from the current sequence number epoch), and the timestamp algorithm handles the "old" old packets (packets from previous sequence number epochs). Getting one of these schemes to work is hard enough, so getting two to work AND making sure they don't interfere with each other is giving chaos ๐
In RFC 1185, the statement is made that "An obvious fix for the problem of cycling the sequence number space is to increase the size of the TCP sequence number field." Using protocol evolution, the obvious fix is also the correct one ๐ The window size can be increased to 32 bits by simply changing a short to a long in the definition of the TCP header. At the same time, the sequence number and acknowledgment fields can be increased to 64 bits. This change is the minimum complexity modification to get the job done, and it requires little or no analysis to be shown to work correctly โจ
On machines that do not support 64-bit integers, increasing the sequence number size is not as trivial as increasing the window size ๐ฅบ However, it is identical in cost to the modification proposed in RFC 1185. The high order bits can be thought of as an optimal clock that ticks only when it has to โฐ Also, because we are not dealing with real time, the problems with unreliable system clocks are avoided ๐ธ On machines that support 64-bit integers, the original TCP code may be reused. Since only very high performance machines can hope to drive a communications network at the rates this modification is designed to support, and the new generation of RISC microprocessors (e.g., MIPS R4000 and PA-RISC) do support 64-bit integers, the assumption of 64-bit arithmetic may be more of an advantage than a liability ๐
3.1.3. Selective Retransmission ๐ฆ
Another problem with TCP's support for LFN's is that the sliding window algorithm used by TCP does not support any form of selective acknowledgment. So if a segment is lost, the total amount of data that must be re-transmitted is some constant times the bandwidth-delay product, even though most of the segments have actually arrived at the receiver ๐ค RFC 1072 proposes to extend TCP so the receiver can return partial acknowledgments to the sender, in the hope that the sender will use that info to avoid unnecessary re-transmissions ๐ซถ
It has been our experience on predictable local area networks that the performance of partial re-transmission strategies is highly non-obvious, and it generally takes more than one iteration to find a decent algorithm. So it's not surprising that the algorithm proposed in RFC 1072 has some problems ๐ The proposed TCP extension lets the receiver include a short list of received fragments with every ACK. The idea is that when the receiver sends back a normal ACK, it checks its queue of segments that were received out of order, and sends the relative sequence numbers of contiguous blocks of segments back to the sender. The sender then uses this info to re-transmit the segments that were transmitted but not listed in the ACK.
As specified, this algorithm has two related problems: (1) it ignores the relative frequencies of delivered and dropped packets, and (2) the list provided in the option field is probably too short to do much good on networks with large bandwidth-delay products ๐ฉ In every model of high bandwidth network that we have seen, the packet loss rate is very low, and so the ratio of dropped packets to delivered packets is very low too. An algorithm that returns ACKs as proposed is simply going to have to send more information than one in which the receiver returns NAKs.
This problem is compounded by the short size of the TCP option field (44 bytes). In theory, since we are only worried about high bandwidth networks, returning ACKs instead of NAKs is not really a problem, because the bandwidth is available to send any info that's needed ๐ธ The problem comes when you try to squeeze the ACK information into the 44 bytes allowed. The proposed extensions compress the ACK information by letting the receiver ACK byte ranges rather than segments, and by scaling the relative sequence numbers of the re-transmitted segments. This makes it much harder for the sender to tell which segments should be re-transmitted, and it complicates the re-transmission code ๐คฏ More importantly, one should never compress small amounts of data being sent over a high bandwidth network. It trades a scarce resource for an abundant resource, which is just not it ๐ โโ๏ธ On low bandwidth networks, selective retransmission is not needed, and the SACK option should be disabled.
We propose two solutions to this problem ๐ First, the receiver can examine its list of out-of-order packets, guess which segments have been dropped, and NAK those segments back to the sender. The number of NAKs should be low enough that one per TCP packet should be sufficient. Note that the receiver has just as much information as the sender about which packets should be retransmitted. In any case, the NAKs are simply suggestions, and they have no effect on correctness ๐ง
Our second proposed modification is to increase the offset field in the TCP header from 4 bits to 16 bits ๐ This allows 64k-bytes of TCP header, which lets us radically simplify the selective re-transmission algorithm proposed in RFC 1072. The receiver can now simply send a list of 64-bit sequence numbers for the out-of-order segments to the sender. The sender can then use that info to do a partial retransmission, without needing an ouji board to translate ACKs into segments ๐ฎ With the new header size, it may be faster for the receiver to send a large list than to attempt to aggregate segments into larger blocks.
3.1.4. Header Modifications ๐
The modifications proposed above drastically change the size and structure of the TCP header, so this is a good time to re-think the structure of the proposed TCP header ๐ง The primary goal of the current TCP header is to save bits in the output stream. When TCP was developed, a high bandwidth network was 56kbps, and the key use for TCP was terminal I/O. In both situations, minimal header size was important. Unfortunately, while the network has drastically increased in performance and its usage pattern is now vastly different, most protocol designers still consider saving a few bits in the header to be worth almost any price ๐ Our basic goal is different: to improve performance by eliminating the need to extract information packed into odd length bit fields in the header. Below is our first cut at such a modification ๐
The protocol id field is there to make further evolutionary modifications to TCP easier. This field basically subsumes the protocol number field contained in the IP header, with a version number. Each distinct TCP version has a different protocol id, and this field ensures that the right code is looking at the right header ๐ช The offset field has been increased to 16 bits to support the larger header size required, and to simplify header processing. The code field has been extended to 16 bits to support more options.
The source port and destination port are unchanged. The size of both the sequence number and ACK fields has been increased to 64 bits. The open window field has been increased to 32 bits. The checksum and urgent data pointer fields are unchanged. The echo and echo reply fields are added. The option field remains, but it can be much larger than in the old TCP. All headers are padded out to 32 bit boundaries. Note that these changes increase the minimum header size from 24 bytes (actually 36 bytes if the ECHO and ECHO reply options defined in RFC 1072 are included on every packet) to 48 bytes ๐ The maximum header size has been increased to the maximum segment size. We do not believe that the increased header size will have a measurable effect on protocol performance ๐
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Protocol ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Offset | Code |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source | Dest |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Seq |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Ack |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Window |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | Urgent |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Echo |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Echo Reply |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Pad |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3.1.5. Backward Compatibility ๐ซง
The most likely objection to the proposed TCP extension is that it is not backward compatible with the current version of TCP, and most importantly, TCP's header ๐ฌ In this section we will present three versions of the proposed extension, with increasing degrees of backward compatibility. The final version will combine the same degree of backward compatibility found in the protocol described in RFC's 1072/1185, with the much simpler semantics described in this RFC ๐ฅฐ
We believe that the best way to preserve backward compatibility is to leave all of TCP alone and support the transparent use of a new protocol when and where it is needed. The basic scheme is the one described in section 2.4. Those machines and operating systems that need to support high speed connections should implement some general protocol infrastructure that allows them to rapidly evolve protocols. Machines that do not require such service simply keep using the existing version of TCP. A virtual protocol is used to manage the use of multiple TCP versions ๐ฆโจ
The first sentence is a clear example of why careful wording matters, so here's the rewrite.
okay so this approach has a few big advantages ๐ First, it guarantees backward compatibility with ALL existing TCP versions, because those implementations will never see strange packets with new options ๐ซถ Second, it supports further modification of TCP with little additional cost โจ Finally, since our version of TCP will more closely resemble the existing TCP protocol than the one proposed in RFC's 1072/1185, the cost of maintaining two simple protocols will probably be lower than maintaining one complex protocol. (ngl, with high probability you still have to maintain two versions of TCP in any case ๐) The only additional cost is the memory required for keeping around two copies of TCP.
For the people who insist that the only efficient way to implement TCP modifications is in one single monolithic protocol ๐ง, or who believe that the space requirements of two protocols would be too great, we simply migrate the virtual protocol into TCP. TCP is modified so that when opening a connection, the sender uses the TCP VERSION option attached to the SYN packet to request using the new version. The receiver responds with a TCP VERSION ACK in the SYN ACK packet, after which point the new header format described in Section 3.1.4 is used. Thus, there is only one version of TCP, but that version supports multiple header formats ๐ The complexity of such a protocol would be no worse than the protocol described in RFC 1072/1185. It does, however, make it more difficult to make additional changes to TCP ๐ค
Finally, for those who believe that preserving the TCP header format has any intrinsic value (for example, for those who don't want to re-program their ethernet monitors ๐), a header compatible version of our proposal is possible. One simply takes all of the additional information contained in the header given in Section 3.1.4 and places it into a single optional field. Thus, one could define a new TCP option which consists of the top 32 bits of the sequence and ack fields, the echo and echo_reply fields, and the top 16 bits of the window field. This modification makes it more difficult to take advantage of machines with 64-bit address spaces, but at a minimum will be just as easy to process as the protocol described in RFC 1072/1185. The only restriction is that the size of the header option field is still limited to 44 bytes, and thus, selective retransmission using NAKs rather than ACKs will probably be required.
The key observation here is that one should make a protocol extension correct and simple before trying to make it backward compatible. As far as we can tell, the only advantage the protocol described in RFC 1072/1185 has is that its typical header, size including options, is 8 to 10 bytes shorter. The price for this "advantage" is a protocol of such complexity that it may prove impossible for normal humans to implement ๐
Trying to maintain backward compatibility at every stage of the protocol design process is a serious mistake. ๐ซ
3.2. TCP Over Extension ๐ธ
Another potential problem with TCP that has been discussed recently, but has not yet resulted in the generation of an RFC, is the potential for TCP to grab and hold all 2**16 port numbers on a given machine. This problem is caused by short port numbers, long MSLs, and the misuse of TCP as a request-reply protocol. TCP has to hold onto each port after a close until all possible messages to that port have died, about 240 seconds. Even worse, this time is not decreasing as network performance increases. With new fast hardware, it is possible for an application to open a TCP connection, send data, get a reply, and close the connection at a rate fast enough to use up all the ports in less than 240 seconds. This usage pattern is generated by people using TCP for something it was never intended to do โ guaranteeing at-most-once semantics for remote procedure calls. ๐ญ
The proposed solution is to embed an RPC protocol into TCP while preserving backward compatibility. This is done by piggybacking the request message on the SYN packet and the reply message on the SYN-ACK packet. This approach suffers from one key problem: it reduces the probability of a correct TCP implementation to near 0. The basic problem has nothing to do with TCP. Rather, it is the lack of an Internet request-reply protocol that guarantees at-most-once semantics.
We propose to solve this problem by creating a new protocol. This has already been attempted with VMTP, but the size and complexity of VMTP, coupled with the process currently required to standardize a new protocol, doomed it from the start. Instead of solving the general problem, we propose to use Sprite RPC [7], a much simpler protocol, as a means of off-loading inappropriate users from TCP. โจ
The basic design would attempt to preserve as much of the TCP interface as possible, so that current TCP (mis)users could be switched to Sprite RPC without requiring code modification on their part. A virtual protocol could be used to select the correct protocol, TCP or Sprite RPC, if it exists on the other machine. A backward compatible modification to TCP could be made which would simply prevent it from grabbing all of the ports by refusing connections. This would encourage TCP abusers to use the new protocol. ๐โโ๏ธ
Sprite RPC, which is designed for a local area network, has two problems when extended into the Internet. First, it does not have a useful flow control algorithm. Second, it lacks the necessary semantics to reliably tear down connections. The lack of a tear down mechanism needs to be solved, but the flow control problem could be dealt with in later iterations of the protocol, as Internet blast protocols are not yet well understood. For now, we could simply limit the size of each message to 16k or 32k bytes. This might also be a good place to use a decomposed version of Sprite RPC [2], which exposes each of these features as separate protocols. This would permit the quick change of algorithms, and once the protocol had stabilized, a monolithic version could be constructed and distributed to replace the decomposed version. ๐งฉ
In other words, the basic strategy is to introduce as simple an RPC protocol as possible today, and later evolve this protocol to address the known limitations. ๐ฆ
3.3. Future Modifications ๐
The header prediction algorithm should be generalized so as to be less sensitive to changes in the protocol's header and algorithm. There almost seems to be as much effort to make all modifications to TCP backward compatible with header prediction as there is to make them backward compatible with TCP. The question that needs to be answered is: are there any changes we can make to TCP to make header prediction easier, including the addition of information into the header? In [6], the authors showed how one might generalize optimistic blast from VMTP to almost any protocol that performs fragmentation and reassembly. Generalizing header prediction so that it scales with TCP modification would be a step in the right direction. ๐ง
It is clear that an evolutionary change to increase the size of the source and destination ports in the TCP header will eventually be necessary. We also believe that TCP could be made significantly simpler and more flexible through the elimination of the pseudo-header. The solution to this problem is to simply add a length field and the IP address of the destination to the TCP header. It has also been mentioned that better and simpler TCP connection establishment algorithms would be useful. Some form of reliable record stream protocol should be developed. Performing sliding window and flow control over records rather than bytes would provide numerous opportunities for optimizations, and allow TCP to return to its original purpose as a byte-stream protocol. ๐
Finally, it has become clear to us that the current Internet congestion control strategy is to use TCP for everything, since it is the only protocol that supports congestion control. One of the primary reasons many "new protocols" are proposed as TCP options is that it is the only way to get at TCP's congestion control. At some point, a TCP-independent congestion control scheme needs to be implemented, and one might then be able to remove the existing congestion control from TCP and radically simplify the protocol. ๐
4. Discussion โจ
okay so one obvious side effect of our changes is that the TCP header gets bigger ๐ญ. It's kinda inevitable tbh, because basically every field in the header has been pushed to its limit by how fast the network has grown ๐. BUT we honestly didn't try that hard to make the minimal changes that fix the current problem. We kept sacrificing header size to put off future changes for as long as possible ๐. The tea is that TCP's whole claim to fame is being super efficient at sending tiny one byte packets over slow networks ๐ข. A bigger header means more overhead on small packets on slow networks, no cap. Clark among others has said they see no fundamental performance limits stopping TCP from supporting very high speed networks. That's true as far as it goes โจ, but there's a direct trade-off between TCP performance on high speed networks and TCP performance on slow ones. The dynamic range is just too big for one protocol to support optimally ๐. So by keeping the old version of TCP around, we've basically split TCP into two protocols: one for high bandwidth lines and one for low bandwidth lines ๐ฆ.
Another possible argument is to package all the changes above as one new version of TCP, standardize it, and go back to the status quo of stable, unchanging protocols ๐ฅฑ. Like, to a certain extent that's inevitable (there's a backlog of necessary TCP changes because modifying protocols is logistically a mess), but it just begs the question ๐. The status quo is simply unacceptably static, and there will always be future changes to TCP. Evolutionary change also gives us a better and more reliable TCP โจ. Making small changes and distributing them at regular intervals means one change actually gets stabilized before the next one shows up. It also gives the protocol designer a more balanced workload: instead of designing one new protocol every 10 years, they make annual protocol extensions ๐ . It'll eventually make protocol distribution easier too. The basic problem with distribution right now is that it happens so rarely that nobody knows how to do it, and there's no incentive to build the infrastructure to do it efficiently ๐ค. The first protocol distribution is almost guaranteed to be a disaster, but the problem gets easier with each one after. Finally, a brand new TCP would have the same problems VMTP did: a radically new protocol is a bigger target ๐ฏ.
Breaking backward compatibility in systems as complex as the Internet is always a serious step ๐ฌ. But backward compatibility is a technique, not a religion ๐. Two facts get overlooked when backward compatibility gets out of hand. First, violating it is always a big win when you can get away with it ๐. One of the key advantages of RISC chips over CISC chips is simply that they weren't backward compatible with anything. So they weren't bound by design decisions made back when compilers were stupid and real men programmed in assembler ๐. Second, you're going to have to break backward compatibility at some point anyway. Every system has some headroom limitations, and those lead to either stagnation (IBM mainframe software ๐ฅ๏ธ) or, even worse, accidental violations of backward compatibility ๐ฑ.
Of course, the biggest problem with our approach is that it isn't compatible with the existing standardization process ๐. We hope to design and distribute protocols in less time than it takes a standards committee to agree on an acceptable meeting time ๐ญ. This is inevitable because the basic problem with networking is the standardization process. Over the last several years there's been a push in the research community for lightweight protocols, when what's actually needed is lightweight standards ๐ซถ. Also, we haven't proposed some entirely new set of "superior" communications protocols โจ. We've just proposed a system for making necessary changes to the existing protocol suites fast enough to keep up with the underlying change in the network ๐. The first standards organization that realizes the primary impediment to standardization is poor logistical support will probably win ๐.
5. Conclusions ๐
The most important conclusion of this RFC is that protocol change happens, and it's happening at a very respectable clip ๐. While all the examples in this document are from TCP, plenty of other protocols need modification too. In a more prosaic domain ๐, the telephone company is running out of phone numbers. They're getting overrun by fax machines, modems, and cars ๐๐. The underlying cause seems to be a consistent exponential increase in almost all network metrics (number of hosts, bandwidth, host performance, applications, and so on), combined with an attempt to run the network with a static set of unchanging network protocols ๐ต. This has been shown to be impossible, and you can almost feel the pressure for protocol change building ๐. We simply propose to explicitly deal with the changes rather than keep trying to hold back the flood ๐.
Of almost equal importance is the observation that TCP is a protocol and not a platform for implementing other protocols ๐ง. Because of a lack of any alternatives, TCP has become a de-facto platform for implementing other protocols anyway. It provides a vague standard interface with the kernel, it runs on many machines, and it has a well defined distribution path ๐ฃ๏ธ. Otherwise sane people have proposed Bounded Time TCP (an unreliable byte stream protocol), Simplex TCP (which supports data in only one direction) and Multi-cast TCP (too horrible to even consider) ๐. All of these protocols probably have their uses, but not as TCP options. The fact that so many people are willing to use TCP as a protocol implementation platform points to the desperate need for a protocol independent platform ๐ฅบ.
Finally, our research found very little difference in the actual technical work involved with the three proposed methods of protocol modification ๐. The work for a backward compatible change is often more than for an evolutionary change or for creating a new protocol. Even the distribution costs seem to be identical. The primary cost difference between the three approaches is the cost of getting the modification approved ๐งพ. A protocol modification, no matter how extensive or bizarre, seems to incur much less cost and risk. It's time to stop changing the protocols to fit our current way of thinking, and start changing our way of thinking to fit the protocols ๐.
6. References ๐
Here are the receipts ๐งพ, all of them, exactly as they were.
[1] Cheriton D., "VMTP: Versatile Message Transaction Protocol", RFC 1045, Stanford University, February 1988.
[2] Hutchinson, N., Peterson, L., Abbott, M., and S. O'Malley, "RPC in the x-Kernel: Evaluating New Design Techniques", Proceedings of the 12th Symposium on Operating System Principles, Pgs. 91-101, December 1989.
[3] Jacobson, V., "Congestion Avoidance and Control", SIGCOMM '88, August 1988.
[4] Jacobson, V., and R. Braden, "TCP Extensions for Long-Delay Paths", RFC 1072, LBL, ISI, October 1988.
[5] Jacobson, V., Braden, R., and L. Zhang, "TCP Extensions for High-Speed Paths", RFC 1185, LBL, ISI, PARC, October 1990.
[6] O'Malley, S., Abbott, M., Hutchinson, N., and L. Peterson, "A Transparent Blast Facility", Journal of Internetworking, Vol. 1, No. 2, Pgs. 57-75, December 1990.
[7] Welch, B., "The Sprite Remote Procedure Call System", UCB/CSD 86/302, University of California at Berkeley, June 1988.
7. Security Considerations ๐
Security issues are not discussed in this memo.
Yikes, bestie ๐: this memo does not discuss security issues at all. Keep that in mind before you build anything on top of it ๐ซถ.
8. Authors' Addresses ๐
Meet the authors, the two icons behind this memo ๐ง:
Larry L. Peterson
University of Arizona
Department of Computer Sciences
Tucson, AZ 85721
Phone: (602) 621-4231
EMail: llp@cs.arizona.edu
Sean O'Malley
University of Arizona
Department of Computer Sciences
Tucson, AZ 85721
Phone: 602-621-8373
EMail: sean@cs.arizona.edu
๐ฆ where this page comes from
- ietf: rfc1263 1991-10
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms