RFC 2140
TCP Control Block Interdependence
๐ Quick heads-up, bestie: RFC 2140 doesn't have a section 4.1.3. Its headings aren't numbered at all, so I didn't invent one. Everything else is here, with the technical bits kept exact.
Status of this Memo ๐ธ
Okay so this memo is giving information for the Internet community ๐ . It does not specify an Internet standard of any kind, so nobody has to implement anything from it. Distribution of this memo is unlimited, so share it with everyone ๐ซถ.
Abstract โจ
Okay this doc makes the case for interdependent TCP control blocks ๐ฆ. The idea is that part of the TCP state gets shared among similar concurrent connections, or across similar connection instances. TCP state is a whole mix of stuff: connection state, current round-trip time estimates, congestion control information, and process information ๐ง. Right now all of that lives per-connection in the TCP control block, but the paper argues it should be shared across connections to the same host ๐. The goal is better transient transport performance while staying backward-compatible with existing implementations ๐ฅ.
This document is a product of the LSAM project at ISI ๐.
Introduction ๐
So TCP is a connection-oriented reliable transport protocol layered over IP [9] ๐. Each TCP connection keeps its own state, usually in a data structure called the TCP Control Block (TCB) ๐ฆ. The TCB holds info about the connection state, its associated local process, and feedback parameters about how the connection's transmission is going โจ. As originally specified and usually implemented, the TCB is maintained on a per-connection basis, and this doc talks about what that choice means ๐.
The author argues for an alternate approach that shares some of this state across similar connection instances and among similar simultaneous connections ๐ง. The payoff is better transient performance, especially for the many short-lived and simultaneous connections you get on the World-Wide Web [1] ๐ธ๏ธ. Fun detail: these changes only touch TCB initialization, so the long-term behavior of TCP after a connection is established has no effect ๐ .
The TCP Control Block (TCB) ๐ฆ
Okay, so a TCB is associated with each connection, which just means each association of a pair of applications across the network ๐ซ. The TCB can be summarized as containing [9]:
Local process state
pointers to send and receive buffers
pointers to retransmission queue and current segment
pointers to Internet Protocol (IP) PCB
Per-connection shared state
macro-state
connection state
timers
flags
local and remote host numbers and ports
micro-state
send and receive window state (size*, current number)
round-trip time and variance
cong. window size*
cong. window size threshold*
max windows seen*
MSS#
round-trip time and variance#
The per-connection info gets split into macro-state and micro-state, terminology borrowed from [5] ๐. Macro-state describes the finite state machine, and we include the endpoint numbers and components (timers, flags) that help maintain that state ๐ง . This also covers the protocol for establishing and maintaining shared state about the connection. Micro-state describes the protocol after a connection is established, and it's what keeps the data transfer reliable and congestion-controlled ๐ฅ.
There are two more classes of shared micro-state that are more about host-pairs than application pairs ๐. One class is clearly host-pair dependent (marked #, like MSS and RTT) ๐ท. The other is host-pair dependent only in its aggregate (marked *, like congestion window info and current window sizes) ๐.
TCB Interdependence ๐
Okay this part is so iconic ๐ญ. The idea that some TCB state is host-pair specific rather than application-pair dependent isn't new at all, and it's a pretty common engineering choice in layered protocol implementations โจ. Sharing RTT info among protocols layered over IP, including UDP and TCP, was discussed in [8] ๐. T/TCP uses caches to keep TCB info across instances, like smoothed RTT, RTT variance, congestion avoidance threshold, and MSS [3] ๐ฆ. These values sit alongside the connection counts T/TCP uses to speed up data delivery before the full three-way handshake during an OPEN ๐ง.
The whole goal is to aggregate TCB components where they reflect one association, which is the host-pair, instead of artificially splitting those components up by connection ๐.
At least one current T/TCP implementation saves the MSS and aggregates the RTT parameters across multiple connections, but skips caching the congestion window information [4], as originally specified in [2] ๐. There may be other values worth caching, like current window size, so new connections get full access to accumulated channel resources ๐ซถ.
Now here's the key bit ๐: there are two cases of TCB interdependence. Temporal sharing happens when the TCB of an earlier (now CLOSED) connection to a host gets used to initialize some parameters of a new connection to that same host โณ. Ensemble sharing happens when a currently active connection to a host gets used to initialize another (concurrent) connection to that host ๐ฏ. T/TCP documents only considered the temporal case, but this memo considers both ๐ .
An Example of Temporal Sharing ๐
Temporal sharing of cached TCB data has been implemented in the SunOS 4.1.3 T/TCP extensions [4] and the FreeBSD port of the same [7] ๐. Like we said before, only the MSS and RTT parameters are cached, as originally specified in [2]. Later discussion of T/TCP suggested adding congestion control parameters to this cache [3] ๐ธ.
The cache gets accessed in two ways: it's read to initialize new TCBs, and written when more current per-host state is available ๐. New TCBs are initialized like this. Note that snd_cwnd reuse isn't implemented yet, though it was discussed in the T/TCP concepts [2] ๐:
TEMPORAL SHARING - TCB Initialization
Cached TCB New TCB
----------------------------------------
old-MSS old-MSS
old-RTT old-RTT
old-RTTvar old-RTTvar
old-snd_cwnd old-snd_cwnd (not yet impl.)
Most cached TCB values get updated when a connection closes ๐. The one exception is MSS, which gets updated whenever the MSS option is received in a TCP header ๐ซ.
TEMPORAL SHARING - Cache Updates
Cached TCB Current TCB when? New Cached TCB
---------------------------------------------------------------
old-MSS curr-MSS MSSopt curr-MSS
old-RTT curr-RTT CLOSE old += (curr - old) >> 2
old-RTTvar curr-RTTvar CLOSE old += (curr - old) >> 2
old-snd_cwnd curr-snd_cwnd CLOSE curr-snd_cwnd (not yet impl.)
MSS caching is super simple: reported values get cached, and the most recent value is used ๐ง. The cache is updated whenever the MSS option is received, so it always has the most recent MSS value from any connection ๐. The cache is only consulted at connection establishment and isn't otherwise updated, which means MSS options don't affect current connections ๐ โโ๏ธ. The default MSS is never saved, since only reported MSS values update the cache, so you need an explicit override to reduce the MSS ๐ง.
RTT values get updated by a more complicated mechanism [3], [8] ๐งฎ. Dynamic RTT estimation needs a sequence of RTT measurements, even though a single T/TCP transaction might not collect enough samples ๐ฅบ. So the cached RTT (and its variance) is an average of its previous value with the contents of the currently active TCB for that host, when a TCB closes โ๏ธ. RTT values only update when a connection closes. Also, the way the RTT values get averaged isn't the same as the way they're computed within a connection, so the cached value might not be appropriate ๐คทโโ๏ธ.
For temporal sharing, the cache only needs updating when a connection closes, because the cached values won't be used to initialize a new TCB yet โฐ. For ensemble sharing it's different, as discussed below ๐.
Other TCB variables can also be cached between sequential instances, like the congestion control window information ๐ช. Old cache values can be overwritten with the current TCB estimates, or a MAX or MIN function can merge the results, depending on how optimistic or pessimistic you want to be about the reused values ๐ค. For example, the congestion window can be reused if there are no concurrent connections ๐.
An Example of Ensemble Sharing โจ
okay bestie, so sharing cached TCB data across concurrent connections needs extra care ๐ซถ some of the shared state is really an aggregate thing. MSS and RTT values can just be copied over ๐ but copying congestion window info? not so simple ๐ for now we're only going to cover the MSS and RTT rules ๐
ENSEMBLE SHARING - TCB Initialization
Cached TCB New TCB
----------------------------------
old-MSS old-MSS
old-RTT old-RTT
old-RTTvar old-RTTvar
ENSEMBLE SHARING - Cache Updates
Cached TCB Current TCB when? New Cached TCB
-----------------------------------------------------------
old-MSS curr-MSS MSSopt curr-MSS
old-RTT curr-RTT update rtt_update(old,curr)
old-RTTvar curr-RTTvar update rtt_update(old,curr)
Okay so for ensemble sharing, the TCB info needs to get cached as early as possible ๐ฆ sometimes even before a connection closes. Otherwise, if you open a bunch of concurrent connections and none of them close before the others open, you literally get zero TCB sharing ๐ The optimistic move is updating the cached data as early as you can, not just when a connection is closing. Some T/TCP implementations already do this for MSS when the TCP MSS header option comes in [4] ๐ it just isn't addressed specifically in the concepts or functional specification [2][3] ๐ธ
In current T/TCP, RTT values only get updated after a CLOSE, which means concurrent sessions get nothing out of it ๐ญ As we mentioned in the temporal case, averaging values across concurrent connections means you have to fold in new RTT measurements ๐ง The work needed to update that aggregate average should be kept as small as possible, but the result should be the same as if every value had been measured inside one single connection โจ The function "rtt_update" in the ensemble sharing table is what handles this. It runs whenever the RTT would have been updated in the individual TCP connection ๐ So the cache ends up holding the shared RTT variables, which means they don't need to live in the TCB anymore [8] ๐
Congestion window aggregation is way messier in the concurrent case ๐ฅบ With an ensemble of connections, we have to figure out how that ensemble would have shared the congestion window, so we can derive the initial values for new TCBs ๐ฅ Here's the thing: concurrent connections between two hosts (usually) share the same network paths, so they also share whatever capacity is available along that path ๐ When it comes to congestion, the set of connections might behave as if it were multiplexed before TCP, like all the data was part of one single connection ๐ So the current window sizes would keep a constant sum, assuming there's enough offered load ๐ This would be going beyond caching and into truly sharing state, unlike the RTT case โญ
We have to pause and say: any assumption about this sharing can be wrong, including this one ๐ In current implementations, new congestion windows start at an initial value of one segment, so the sum of the current windows goes up for every new connection ๐ฌ That can cause real trouble when several connections share a highly congested link, like with trans-Atlantic Web access ๐
There are a few ways to initialize the congestion window in a new TCB among an ensemble of current connections to a host, as shown below ๐ฆ Current TCP implementations start it at one segment [9], and T/TCP hinted that it should start at the old window size [3] ๐ With the first option, the assumption is that new connections should behave as conservatively as possible ๐ซถ With the second, there's zero accommodation for concurrent aggregate behavior ๐
Either way, the sum of the window sizes can go up instead of staying put ๐ญ Another option is to give each pending connection its "fair share" of the available congestion window, then let the connections balance out from there ๐ The assumption here is that new connections are basically implicit requests for an equal share of the available link bandwidth, and that share should be granted at the expense of the current connections ๐ This may or may not be the right function, so we're proposing it gets examined further ๐
ENSEMBLE SHARING - TCB Initialization
Some Options for Sharing Window-size
Cached TCB New TCB
-----------------------------------------------------------------
old-snd_cwnd (current) one segment
(T/TCP hint) old-snd_cwnd
(proposed) old-snd_cwnd/(N+1)
subtract old-snd_cwnd/(N+1)/N
from each concurrent
ENSEMBLE SHARING - Cache Updates
Cached TCB Current TCB when? New Cached TCB
----------------------------------------------------------------
old-snd_cwnd curr-snd_cwnd update (adjust sum as appropriate)
Compatibility Issues ๐
Okay so current TCP implementations don't use TCB caching, except for T/TCP variants [4][7] ๐ง New connections just use the default initial values for every non-instantiated TCB variable ๐ That means each connection works out its own RTT measurements, MSS value, and congestion info from scratch ๐ Eventually those values get updated for each connection ๐ธ
For the congestion and current window info, the initial values might not match the long-term aggregate behavior of a set of concurrent connections ๐ฌ Say a single connection has a window of 4 segments. New connections assume initial windows of 1 segment (the minimum), but the existing connection's window doesn't shrink to make room for that extra load ๐ So connections end up interfering with each other ๐ญ We've actually seen this on trans-Atlantic links, where concurrent connections carrying Web traffic collide because their initial windows are too big, even when they're set to one segment ๐
Because this proposal tries to anticipate the aggregate steady-state values of TCB state across a group or over time, it should avoid the transient effects of new connections ๐ฆ Plus, since it looks at the ensemble and temporal properties of those aggregates, it should also keep the transients of short-lived or multiple concurrent connections from hurting overall network performance ๐ We are running analysis and experiments to validate these assumptions ๐ฌโจ
Performance Considerations ๐
Here we're trying to optimize the transient behavior of TCP without messing with its long-term properties ๐ซถ The biggest cost is maintaining the cached values, or using per-host state instead of per-connection state ๐ธ Where performance does take a hit, though, the per-host info can be kept in per-connection copies (like it is now), because higher performance should mean less interference between concurrent connections ๐
Sharing TCB state should only happen at connection establishment and close (to update the cache), so overhead stays low, transient behavior gets optimized, and the effect on the steady-state stays minimal ๐ It's possible that sharing state during a connection, like the RTT or window-size variables, could be useful too, as long as the implementation cost isn't high ๐ง
Implications ๐ฎ
Okay there are a few implications to baking TCB interdependence into TCP implementations ๐ First, it might mean you don't need application-layer multiplexing for performance boosts [6] ๐ Protocols like persistent-HTTP dodge connection reestablishment costs by serializing or multiplexing a bunch of per-host connections over one TCP connection ๐ That skips TCP's per-connection OPEN handshake, and it also skips recomputing MSS, RTT, and congestion windows ๐ง By avoiding the so-called "slow-start restart," performance can get optimized ๐ Our proposal gives you the MSS, RTT, and OPEN handshake avoidance of T/TCP, plus the "slow-start restart avoidance" of multiplexing, without needing a multiplexing mechanism at the application layer ๐ Multiplexing is going to get complicated once quality-of-service mechanisms (e.g., "integrated services scheduling") show up later โก
Second, we're trying to push some of the TCP implementation down from the traditional transport layer (in the ISO model [10]) to the network layer ๐ This acknowledges that some state we currently keep per-connection is actually per-path, which we simplify as per-host-pair ๐ซง Transport protocols usually manage per-application-pair associations (per stream), and network protocols manage per-path associations (routing) ๐บ๏ธ So round-trip time, MSS, and congestion info is handled more appropriately in a network-layer way: aggregated across concurrent connections and shared across connection instances ๐ฆ
An earlier version of RTT sharing suggested implementing RTT state at the IP layer, not the TCP layer [8] ๐ง Our observations are about sharing state among TCP connections, which avoids some of the difficulties with an IP-layer solution ๐ One of those difficulties is figuring out which prior outgoing packet goes with an incoming packet, so you can infer the RTT from the exchange ๐ Because RTTs are still determined inside the TCP layer, this is way simpler than doing it at the IP layer ๐ธ It's a case where information should be computed at the transport layer but shared at the network layer โจ
We also want to note that per-host-pair associations aren't the only place these techniques apply ๐ TCBs could be shared in a similar way between hosts on a LAN, since the predominant path can be LAN-LAN instead of host-host ๐
There may be other info that can be shared between concurrent connections too ๐ For example, if another connection has just tried to expand its window size and failed, a connection may hold off on trying the same thing for a while ๐ซถ The idea is that existing TCP implementations infer the behavior of all competing connections, including those on the same host or LAN ๐ต๏ธโโ๏ธ One possible optimization is making that implicit feedback explicit, through extended information in the per-host TCP area ๐๐ฅ
Security Considerations ๐
okay bestie, this part gets a little serious ๐ but I'll make it make sense. These suggested enhancements don't add any new ramifications for direct attacks ๐ซถ. They can be open to denial-of-service attacks if they aren't secured some other way. Like, an application can open a connection and set its window size to 0, and that literally denies service to any other connection between those same hosts ๐ญ.
TCB sharing might be vulnerable to DoS attacks wherever the TCB is shared: between connections inside one host, or between hosts if TCB sharing is implemented on the LAN (check the Implications section ๐ ). Some shared TCB parameters are only used to create new TCBs, and others are shared among the TCBs of ongoing connections. New connections can join that ongoing set, e.g., to optimize send window size across a group of connections to the same host ๐ง.
Attacks on parameters used only for initialization only affect the transient performance of a TCP connection ๐ฆ. For short connections, the performance hit can get really close to a denial-of-service attack, ngl. For example, if an application changes its TCB to have a false and small window size, later connections would be slow until their window grew appropriately ๐.
The solution is to limit the effect of compromised TCB values ๐ก๏ธ. TCBs count as compromised when they're modified directly by an application or sent between hosts through unauthenticated means (e.g., by using a dirty flag). TCBs that aren't compromised by application modification don't have any unique security ramifications ๐. Note that the proposed parameters for TCB sharing aren't currently modifiable by an application ๐.
All shared TCBs MUST be validated against default minimum parameters before they're used for new connections. This validation won't impact performance, because it only happens at TCB initialization ๐ธ. This limits the effect of attacks on new connections to reducing the benefit of TCB sharing, which leaves you with the current default TCP performance. For ongoing connections, the effect of incoming packets on shared information should be both limited and validated against constraints before use. This is a beneficial precaution for existing TCP implementations as well ๐.
TCBs modified by an application SHOULD not be shared, unless the new connection sharing the compromised information has been given explicit permission to use such information by the connection API ๐ซ. No mechanism for that indication currently exists, but it could be supported by an augmented API โจ. This sharing restriction SHOULD be implemented in both the host and the LAN. Sharing on a LAN SHOULD utilize authentication to prevent undetected tampering of shared TCB parameters ๐. These restrictions limit the security impact of modified TCBs both for connection initialization and for ongoing connections ๐.
Finally, shared values MUST be limited to performance factors only ๐จ. Other information, such as TCP sequence numbers, is already known to compromise security when shared, so absolutely not ๐ญ๐ โโ๏ธ.
Acknowledgements ๐
The author wants to thank the members of the High-Performance Computing and Communications Division at ISI, notably Bill Manning, Bob Braden, Jon Postel, Ted Faber, and Cliff Neuman, for all their help developing this memo ๐ซถ.
References ๐
[1] Berners-Lee, T., et al., "The World-Wide Web," Communications of
the ACM, V37, Aug. 1994, pp. 76-82.
[2] Braden, R., "Transaction TCP -- Concepts," RFC-1379,
USC/Information Sciences Institute, September 1992.
[3] Braden, R., "T/TCP -- TCP Extensions for Transactions Functional
Specification," RFC-1644, USC/Information Sciences Institute,
July 1994.
[4] Braden, B., "T/TCP -- Transaction TCP: Source Changes for Sun OS
4.1.3,", Release 1.0, USC/ISI, September 14, 1994.
[5] Comer, D., and Stevens, D., Internetworking with TCP/IP, V2,
Prentice-Hall, NJ, 1991.
[6] Fielding, R., et al., "Hypertext Transfer Protocol -- HTTP/1.1,"
Work in Progress.
[7] FreeBSD source code, Release 2.10, <http://www.freebsd.org/>.
[8] Jacobson, V., (mail to public list "tcp-ip", no archive found),
1986.
[9] Postel, Jon, "Transmission Control Protocol," Network Working
Group RFC-793/STD-7, ISI, Sept. 1981.
[10] Tannenbaum, A., Computer Networks, Prentice-Hall, NJ, 1988.
Author's Address ๐
Joe Touch
University of Southern California/Information Sciences Institute
4676 Admiralty Way
Marina del Rey, CA 90292-6695
USA
Phone: +1 310-822-1511 x151
Fax: +1 310-823-6714
URL: http://www.isi.edu/~touch
Email: touch@isi.edu
๐ฆ where this page comes from
- ietf: rfc2140 1997-04
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms