TCP Accelerated Open (TAO)


T/TCP introduces a 32-bit incarnation number, called a "connection count" (CC), that is carried in a TCP option in each segment. A distinct CC value is assigned to each direction of an open connection. A T/TCP implementation assigns monotonically increasing CC values to successive connections that it opens actively or passively.

T/TCP uses the monotonic property of CC values in initial SYN segments to bypass the 3WHS, using a mechanism that we call TCP Accelerated Open (TAO). Under the TAO mechanism, a host caches a small amount of state per remote host. Specifically, a T/TCP host that is acting as a server keeps a cache containing the last valid CC value that it has received from each different client host. If an initial SYN segment (i.e., a segment containing a SYN bit but no ACK bit) from a particular client host carries a CC value larger than the corresponding cached value, the monotonic property of CC's ensures that the SYN segment must be new and can therefore be accepted immediately. Otherwise, the server host does not know whether the SYN segment is an old duplicate or was simply delivered out of order; it therefore executes a normal 3WHS to validate the SYN. Thus, the TAO mechanism provides an optimization, with the normal TCP mechanism as a fallback.

Protocol Correctness

CC values are 32-bit integers. The essential requirement for correctness of T/TCP is this:

CC values must advance at a rate slower than 2^32-1 counts per 2MSL--[R1] where MSL denotes the maximum segment lifetime in the Internet--[R2].

The requirement [R1] is easily met with a 32-bit CC. For example, it will allow 10^7 transactions per second with the very liberal MSL of 1000 seconds [RFC-1379]. This is well in excess of the transaction rates achievable with current operating systems and network latency. Suppose x(n) is the most recent acceptable CC value carried in an initial SYN segment from a remote host and is cached by the server.If the server host receives a SYN segment containing a CC option with value y where y > x(n), that SYN must be newer; an antique duplicate SYN with CC value greater than x(n) must have exceeded its MSL and vanished. Hence, monotonic CC values and the TAO test prevent erroneous replay of antique SYNs.

There are two possible reasons for a client to generate non-monotonic CC values:

(a) the client may have crashed and restarted, causing the generated CC values to jump backwards; or (b) the generated CC values may have wrapped around the finite space.

Wraparound may occur because CC generation is global to all connections. Suppose that host A sends a transaction to B, then sends more than 2^32-1 transactions to other hosts, and finally sends another transaction to B. From B's viewpoint, CC will have jumped backward relative to its cached value. In either of these two cases, the server may see the CC value jump backwards only after an interval of at least MSL since the last SYN segment from the same client host. In case (a), client host restart, this is because T/TCP retains TCP's explicit "Quiet Time" of an MSL interval. In case (b). wrap around, [R1] ensures that a time of at least MSL must have passed before the CC space wraps around. Hence, there is no possibility that a TAO test will succeed erroneously due to either cause of non-monotonicity; i.e., there is no chance of replays due to TAO.

However, although CC values jumping backwards will not cause an error, it may cause a performance degradation due to unnecessary 3WHS's. This results from the generated CC values jumping backwards through approximately half their range, so that all succeeding TAO tests fail until the generated CC values catch up to the cached value. To avoid this degradation, a client host sends a CC.NEW option instead of a CC option in the case of either system restart or CC wraparound. Receiving CC.NEW forces a 3WHS, but when this 3WHS completes successfully the server cache is updated to the new CC value. To detect CC wraparound, the client must cache the last CC value it sent to each server. It therefore maintains cache.CCsent[B] for each server B. If this cached value is undefined or if it is larger than the next CC value generated at the client, then the client sends a CC.NEW instead of a CC option in the next SYN segment.