TCP Congestion Control
obsoleted by
- rfc-5681 — TCP Congestion Control
obsoletes
- rfc-2001 — TCP Slow Start, Congestion Avoidance, Fast Retransmit, and Fast Recovery Algorithms
updated by
- rfc-3390 — Increasing TCP's Initial Window
Extracted elements (25)
cwnd inflation by 3*SMSS at the start of fast recovery (and 1*SMSS per additional duplicate ACK) artificially accounts for the segments that have left the network and are buffered at the receiver, allowing the sender to continue transmitting new data during recovery.
Fast recovery does not revert to slow start after fast retransmit because the receipt of duplicate ACKs indicates that segments are still leaving the network and the receiver is buffering them—so the ACK clock is preserved and the pipe is not empty, justifying continued transmission at a reduced rate.
Slow start after an idle period restarts the ACK clock; without it, TCP could transmit a full cwnd-sized burst at line rate after the ACK drain, since no ACKs remain in the network to strobe new segments. RW is set equal to IW for this standard.
Using last-segment-received time to detect idle connections fails for persistent HTTP: the server receives a request before transmitting, which resets the idle timer and allows transmission with a potentially oversized cwnd; hence the standard bases idleness on last-data-sent time instead.
Fast retransmit/fast recovery is known to recover inefficiently from multiple packet losses in a single flight; implementations may use enhanced algorithms (e.g., NewReno, SACK-based) provided they obey the general principles of the four base algorithms.
Older TCP implementations include an additional additive constant in the congestion avoidance cwnd update formula; this is incorrect and can lead to diminished performance.
Some implementations maintain cwnd in units of full-sized segments rather than bytes; when cwnd is very large, the integer division in equation 2 (cwnd += SMSS*SMSS/cwnd) may yield 0, and the result SHOULD be rounded up to 1 byte to ensure progress.
The experimental extension in RFC 2414 allows IW = min(4*SMSS, max(2*SMSS, 4380 bytes)) and RW = min(IW, cwnd), but this is explicitly NOT part of the standard defined by RFC 2581; implementations conforming to this document must use IW <= 2*SMSS.
A TCP MUST NOT send data with a sequence number higher than the sum of the highest acknowledged sequence number and the minimum of cwnd and rwnd.
A TCP receiver MUST NOT generate more than one ACK for every incoming segment, other than to update the offered window as the receiving application consumes new data.
A TCP receiver SHOULD send an immediate duplicate ACK when an out-of-order segment arrives, and SHOULD send an immediate ACK when an incoming segment fills in all or part of a gap in the sequence space.
A TCP SHOULD set cwnd to no more than the restart window (RW = IW) before beginning transmission if the TCP has not sent data in an interval exceeding the retransmission timeout.
An ACK SHOULD be generated for at least every second full-sized segment, and MUST be generated within 500 ms of the arrival of the first unacknowledged packet.
During congestion avoidance, cwnd MUST NOT be increased by more than the larger of either 1 full-sized segment per RTT or the value computed using equation 2 (cwnd += SMSS*SMSS/cwnd).
Loss in two successive windows of data, or the loss of a retransmission, MUST cause cwnd and ssthresh to be lowered twice.
The initial window (IW) MUST be less than or equal to 2*SMSS bytes and MUST NOT be more than 2 segments.
The slow start and congestion avoidance algorithms MUST be used by a TCP sender to control the amount of outstanding data being injected into the network.
The TCP sender SHOULD use the fast retransmit algorithm: after receiving 3 duplicate ACKs, retransmit the missing segment without waiting for the retransmission timer to expire.
When a TCP sender detects segment loss via retransmission timer, ssthresh MUST be set to no more than max(FlightSize/2, 2*SMSS), and cwnd MUST be set to no more than the loss window (1 full-sized segment).
When the first loss in a window is detected, ssthresh MUST be set per equation 3; until all lost segments are repaired, segments transmitted per RTT MUST be no more than half of outstanding segments when loss was detected; after repair, cwnd MUST be set to no more than ssthresh.
FlightSize is the amount of data sent but not yet acknowledged, and is the correct value to use (rather than cwnd) when computing the new ssthresh upon loss detection.
The congestion window (cwnd) is a sender-side state variable limiting data in flight; the slow start threshold (ssthresh) determines which algorithm governs cwnd growth. Together they control the rate at which TCP injects data into the network.
An attacker can impair TCP performance by causing data packets or ACKs to be lost, or by forging excessive duplicate ACKs, triggering congestion control and cutting ssthresh to its minimum of 2*SMSS. More broadly, forging acknowledgments could cause TCP endpoints to send more aggressively and potentially drive a portion of the network into congestion collapse.
Fast retransmit/fast recovery: on 3rd duplicate ACK, set ssthresh per equation 3, retransmit lost segment, set cwnd to ssthresh+3*SMSS; increment cwnd by SMSS for each additional duplicate ACK; on new ACK, deflate cwnd to ssthresh and resume congestion avoidance.
TCP uses slow start when cwnd < ssthresh and congestion avoidance when cwnd > ssthresh; when equal, either algorithm may be used. Slow start increments cwnd by at most SMSS per ACK; congestion avoidance increments by approximately 1 full-sized segment per RTT.