rfc-5681

TCP Congestion Control

M. Allman, V. Paxson, E. Blanton
date2009-09 streamIETF areawit wgtcpm statusDRAFT STANDARD pages18 canonicalhttps://www.rfc-editor.org/rfc/rfc5681 doi10.17487/RFC5681 errataview
This document defines TCP's four intertwined congestion control algorithms: slow start, congestion avoidance, fast retransmit, and fast recovery. In addition, the document specifies how TCP should begin transmission after a relatively long idle period, as well as discussing various acknowledgment generation methods. This document obsoletes RFC 2581. [STANDARDS-TRACK]

obsoletes

updated by

Extracted elements (31)

design-rationale §3.1

Byte counting (cwnd += min(N, SMSS)) is recommended over incrementing by a fixed constant per ACK because it defeats ACK Division attacks, where a misbehaving receiver sends multiple partial ACKs for a single segment to artificially inflate cwnd.

tcp, congestion, security

design-rationale §3.2

Fast recovery skips slow start because receipt of duplicate ACKs indicates segments are still leaving the network and being buffered at the receiver — the ACK clock is preserved. Slow start would be overly conservative since the network is not fully congested.

tcp, congestion

design-rationale §3.1

ssthresh on timeout uses FlightSize rather than cwnd because cwnd can incidentally grow beyond rwnd in some implementations. Using FlightSize ensures ssthresh reflects the actual amount of data believed to be in the network at the time of loss.

tcp, congestion

design-rationale §4.1

The restart window RW is defined as min(IW, cwnd) rather than IW alone, because using the last received segment time (rather than last sent) to detect idleness can fail for persistent HTTP connections where the server receives a request before sending data, bypassing the idle check.

tcp, congestion, http

interoperability-note §2

A TCP using SACK (RFC 2018, RFC 2883) can use SACK information to determine duplicate ACKs, e.g., if an ACK contains previously unknown SACK information, instead of relying solely on the five-condition definition of a duplicate ACK.

tcp, congestion

interoperability-note §4.2

When a sender's MSS is smaller than the receiver's RMSS (e.g., due to path MTU discovery), receivers that wait for 2*RMSS bytes before ACKing will generate stretch ACKs spanning more than 2 sender segments, impairing congestion control. Receivers should ACK at least every second segment regardless of size.

tcp, congestion

interoperability-note §3.1

When using integer arithmetic for equation (3) (cwnd += SMSS*SMSS/cwnd) during congestion avoidance, the result can be zero when cwnd > SMSS*SMSS. Implementations SHOULD round up to 1 byte in this case to ensure cwnd continues to grow.

tcp, congestion

normative-requirement §2 MUST NOT

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. This makes the minimum of cwnd and rwnd the governing constraint on data transmission.

tcp, congestion

normative-requirement §4.2 MUST NOT

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.

tcp

normative-requirement §4.1 SHOULD

A TCP SHOULD set cwnd to no more than RW = min(IW, cwnd) before beginning transmission if TCP has not sent data in an interval exceeding the retransmission timeout, to avoid inappropriate cwnd-sized bursts after idle periods.

tcp, congestion

normative-requirement §4.2 MUST

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. An ACK MUST NOT be delayed more than 500 ms waiting on a second full-sized segment.

tcp, congestion

normative-requirement §4.3 MUST

During advanced loss recovery, when the first loss in a window is detected ssthresh MUST be set per equation (4); transmission MUST be no more than half the outstanding segments per RTT until all losses are repaired; and cwnd MUST be set to no more than ssthresh after recovery with congestion avoidance used thereafter.

tcp, congestion

normative-requirement §3.1 MUST NOT

During congestion avoidance, cwnd MUST NOT be incremented by more than SMSS bytes per RTT. The RECOMMENDED approach counts acknowledged bytes and increments cwnd by up to SMSS when the count reaches cwnd.

tcp, congestion

normative-requirement §3.1 RECOMMENDED

During slow start, TCP SHOULD increment cwnd per 'cwnd += min(N, SMSS)' where N is the number of previously unacknowledged bytes newly acknowledged. This Appropriate Byte Counting approach provides robustness against ACK Division attacks.

tcp, congestion, security

normative-requirement §3.2 MUST

For each additional duplicate ACK received after the third, cwnd MUST be incremented by SMSS to reflect each additional segment known to have left the network. A TCP MAY limit this inflation to the number of outstanding segments to guard against duplicate ACK spoofing.

tcp, congestion, security

normative-requirement §3.1 MUST

IW MUST be set as an upper bound: 2*SMSS (max 2 segments) if SMSS > 2190 bytes; 3*SMSS (max 3 segments) if 1095 < SMSS <= 2190; 4*SMSS (max 4 segments) if SMSS <= 1095. The SYN/ACK and its acknowledgment MUST NOT increase cwnd.

tcp, congestion

normative-requirement §3.2 SHOULD

On the first and second duplicate ACKs, a TCP SHOULD send a segment of previously unsent data per Limited Transmit (RFC 3042), provided the receiver's window allows and FlightSize would not exceed cwnd plus 2*SMSS. The sender MUST NOT change cwnd for these two segments.

tcp, congestion

normative-requirement §4.2 SHOULD

Out-of-order data segments SHOULD be acknowledged immediately. A receiver SHOULD send an immediate duplicate ACK on a gap, and an immediate ACK when an incoming segment fills all or part of a gap, to accelerate loss recovery.

tcp, congestion

normative-requirement §3.1 MUST

ssthresh SHOULD be set arbitrarily high initially but MUST be reduced in response to congestion. Setting it high allows network conditions rather than arbitrary host limits to dictate the sending rate.

tcp, congestion

normative-requirement §3 MUST

The slow start and congestion avoidance algorithms MUST be used by a TCP sender to control the amount of outstanding data injected into the network. A TCP MUST NOT be more aggressive than these algorithms allow.

tcp, congestion

normative-requirement §3.1 MUST

Upon a retransmission timeout, cwnd MUST be set to no more than the loss window LW, which equals 1 full-sized segment regardless of IW. TCP then uses slow start to increase cwnd back to ssthresh.

tcp, congestion

normative-requirement §3.1 MUST

When segment loss is detected by the retransmission timer and the segment has not yet been retransmitted via that timer, ssthresh MUST be set to no more than max(FlightSize/2, 2*SMSS). On subsequent retransmissions of the same segment, ssthresh is held constant.

tcp, congestion

normative-requirement §3.2 MUST

When the next ACK arrives acknowledging previously unacknowledged data after fast retransmit, cwnd MUST be set to ssthresh (the value set when the third duplicate ACK was received). This 'deflates' the artificially inflated window.

tcp, congestion

normative-requirement §3.2 MUST

When the third duplicate ACK is received, ssthresh MUST be set to no more than max(FlightSize/2, 2*SMSS), the lost segment MUST be retransmitted, and cwnd set to ssthresh plus 3*SMSS to reflect the three segments that have left the network.

tcp, congestion

protocol-element §2

Congestion Window (cwnd): a sender-side state variable limiting how much data may be in flight. Combined with rwnd (receiver window), the minimum of the two governs how much data can be sent before receiving an ACK.

tcp, congestion

protocol-element §2

FlightSize is the amount of data that has been sent but not yet cumulatively acknowledged. It is used rather than cwnd in equation (4) for ssthresh computation to avoid inflating ssthresh when cwnd has grown beyond rwnd.

tcp, congestion

protocol-element §3.1

Slow Start Threshold (ssthresh): a sender-side state variable that determines the boundary between slow start (cwnd < ssthresh) and congestion avoidance (cwnd > ssthresh). When equal, either algorithm may be used.

tcp, congestion

security-consideration §5

An attacker can impair TCP performance by causing packet or ACK loss, or by forging excessive duplicate ACKs, forcing the sender to reduce its congestion window. Byte counting (ABC) is recommended to counter the ACK Division attack where bogus partial ACKs artificially inflate cwnd.

tcp, security, congestion

security-consideration §5

The Internet relies on correct TCP congestion control implementation to prevent congestion collapse. An attacker forging excessive duplicate ACKs or ACKs for new data could drive portions of the network into congestion collapse by inducing TCP endpoints to behave more aggressively.

tcp, security, congestion

state-machine §3.2

Fast retransmit/fast recovery: triggered by 3 duplicate ACKs — ssthresh set, lost segment retransmitted, cwnd = ssthresh + 3*SMSS; each further dup ACK increments cwnd by SMSS; on new ACK cwnd deflated to ssthresh and congestion avoidance resumes.

tcp, congestion

state-machine §3.1

TCP transitions between slow start (cwnd < ssthresh, exponential growth: cwnd += min(N, SMSS) per ACK) and congestion avoidance (cwnd > ssthresh, linear growth: ~1 SMSS per RTT). On retransmission timeout, TCP returns to slow start with cwnd = LW = 1 segment.

tcp, congestion