Transmission Control Protocol (TCP)
obsoletes
- rfc-2873 — TCP Processing of the IPv4 Precedence Field
- rfc-6093 — On the Implementation of the TCP Urgent Mechanism
- rfc-6429 — TCP Sender Clarification for Persist Condition
- rfc-6528 — Defending against Sequence Number Attacks
- rfc-6691 — TCP Options and Maximum Segment Size (MSS)
- rfc-793 — Transmission Control Protocol
- rfc-879 — The TCP Maximum Segment Size and Related Topics
updates
- rfc-1011 — Official Internet protocols
- rfc-1122 — Requirements for Internet Hosts - Communication Layers
- rfc-5961 — Improving TCP's Robustness to Blind In-Window Attacks
also
- std-7
Extracted elements (30)
The ISN formula ISN = M + F(..., secretkey) was chosen to combine a monotonically increasing timer (preventing sequence number reuse within an MSL for the same connection incarnation) with a per-connection cryptographic PRF (preventing off-path attackers from predicting ISNs). Without the PRF component, an attacker observing one connection's ISN could guess ISNs for other connections.
The quiet time concept requires a host that loses sequence number state to wait one MSL before sending segments, allowing old duplicates to drain. This is now considered largely unnecessary in modern networks because ISN randomization, longer 32-bit sequence spaces relative to faster link speeds using PAWS/timestamps, and reboots often lasting longer than an MSL together make the risk negligible.
The three-way handshake is necessary because sequence numbers are not tied to a global clock and different implementations select ISNs independently. Without a third message, the receiver of a SYN cannot determine if it is from a new or old connection incarnation; the 3WHS enables RST-based rejection of old duplicates before data is delivered.
For IPv6 Jumbograms (payloads exceeding 64 KB), an advertised MSS value of 65,535 is treated as infinity and Path MTU Discovery is used to determine the actual MSS, since the 16-bit MSS Option field cannot represent values larger than 65,535.
When an interface has a variable effective MTU (e.g., due to header compression schemes like ROHC that occasionally must transmit full headers), TCP implementations SHOULD advertise an MSS based on the smallest effective MTU of the interface (SHLD-6) to avoid retransmission interference during compressor resynchronization.
A TCP implementation MUST support simultaneous open attempts (MUST-10) and MUST track whether SYN-RECEIVED was reached via a passive or active OPEN (MUST-11), since this determines whether a received RST causes a return to LISTEN or an abort to CLOSED.
A TCP implementation MUST support the three mandatory options: End of Option List (Kind=0), No-Operation (Kind=1), and Maximum Segment Size (Kind=2) (MUST-4). It MUST be able to receive any option in any segment (MUST-5), MUST ignore unknown options that have a length field (MUST-6), and MUST handle illegal option lengths such as zero by resetting the connection (MUST-7).
A TCP implementation MUST use a clock-driven mechanism for ISN selection (MUST-8) and SHOULD generate ISNs as ISN = M + F(localip, localport, remoteip, remoteport, secretkey), where M is a 4-microsecond timer and F() is a pseudorandom function of the 4-tuple and a secret key (SHLD-1). F() MUST NOT be computable externally (MUST-9).
A TCP implementation SHOULD implement the Nagle algorithm (SHLD-7), but there MUST be a way for an application to disable it on an individual connection (MUST-17). A TCP receiver MUST process RST and URG fields of all incoming segments even when the receive window is zero (MUST-66).
TCP endpoints MUST implement both sending and receiving the MSS Option (MUST-14). If no MSS Option is received at connection setup, the implementation MUST assume a default send MSS of 536 bytes for IPv4 or 1220 bytes for IPv6 (MUST-15).
The effective send MSS MUST be the minimum of the send MSS and the largest IP-layer transmission size, computed as Eff.snd.MSS = min(SendMSS+20, MMS_S) − TCPhdrsize − IPoptionsize (MUST-16). The MSS value advertised in the MSS Option must be at most MMS_R − 20 (MUST-67).
The TCP checksum is never optional: the sender MUST generate it (MUST-2) and the receiver MUST check it (MUST-3). The checksum is the 16-bit ones' complement of the ones' complement sum of all 16-bit words in the pseudo-header, TCP header, and data, with the checksum field set to zero during computation.
The Window field MUST be treated as an unsigned number (MUST-1); treating it as signed causes large window sizes to appear negative, breaking flow control. Implementations are RECOMMENDED to use 32-bit fields internally for send and receive window sizes and perform all window computations in 32 bits (REC-1).
When a connection is actively closed, it MUST linger in TIME-WAIT for 2×MSL (Maximum Segment Lifetime) before transitioning to CLOSED (MUST-13). The MSL is defined as 2 minutes. An implementation MAY accept a new SYN from TIME-WAIT to reopen the connection if it assigns a larger ISN than any used on the previous incarnation (MAY-2).
Connection close uses a FIN handshake: the active closer sends FIN and enters FIN-WAIT-1; receiving ACK advances to FIN-WAIT-2; receiving remote FIN sends ACK and enters TIME-WAIT for 2×MSL before CLOSED. Simultaneous close causes both sides to enter CLOSING after FIN exchange, then TIME-WAIT after receiving the final ACK.
Half-open connections arise when one peer reboots or closes without the other's knowledge. They are detected when a synchronized peer receives an out-of-window SYN, responds with an ACK indicating its expected sequence, and the initiator — seeing an unacceptable acknowledgment — sends RST to abort. The surviving peer then returns to CLOSED.
RST generation rules depend on state: (1) CLOSED — send RST for any non-RST incoming segment; (2) non-synchronized states — send RST for unacceptable ACK or security mismatch; (3) synchronized states — respond with empty ACK for out-of-window segments, and send RST only for security level mismatch, transitioning to CLOSED.
RST validation: in all states except SYN-SENT, a RST is valid only if SEG.SEQ falls within the receive window. In SYN-SENT, a RST is acceptable if its ACK field acknowledges the SYN. On valid RST reception: LISTEN — ignore; SYN-RECEIVED after passive OPEN — return to LISTEN; all other states — abort connection and notify user.
Segment acceptability against the receive window uses four cases: a zero-length segment to a zero window is acceptable only if SEG.SEQ = RCV.NXT; a non-zero-length segment to a zero window is never acceptable; otherwise, a segment is acceptable if any part (SEG.SEQ or SEG.SEQ+SEG.LEN-1) falls within [RCV.NXT, RCV.NXT+RCV.WND).
The Nagle algorithm buffers outgoing user data whenever SND.NXT > SND.UNA (unacknowledged data exists) until either all outstanding data is acknowledged or a full-sized segment (Eff.snd.MSS bytes) can be sent. This coalesces small writes into fewer, larger segments, reducing network overhead for interactive applications.
The three-way handshake (3WHS) establishes a connection: peer A sends SYN with ISN X; peer B responds with SYN-ACK (SEQ=Y, ACK=X+1); A sends ACK (ACK=Y+1). Simultaneous open is also supported, where both peers transition CLOSED→SYN-SENT→SYN-RECEIVED→ESTABLISHED after exchanging SYN-ACK segments.
The Transmission Control Block (TCB) stores per-connection state including local/remote IP addresses and ports, send/receive buffer pointers, and key sequence variables: SND.UNA (oldest unacknowledged), SND.NXT (next to send), SND.WND (send window), RCV.NXT (next expected), RCV.WND (receive window), ISS, and IRS.
The 'TCP Header Flags' registry (IANA) controls assignment of the 8 control bits in the TCP header. Currently assigned flags are CWR, ECE, URG, ACK, PSH, RST, SYN, and FIN. A separate IANA registry manages all defined TCP Options, including experimental option space defined in RFC 6994.
Blind RST attacks exploit the fact that any segment with RST set and a sequence number within the receive window aborts the connection. RFC 5961 (partially updated by this document with a clarification for SYN-RECEIVED state) addresses this by narrowing what constitutes a valid RST; implementations should consider challenge ACK mechanisms to mitigate off-path injection.
Predictable ISN values allow off-path attackers to forge TCP segments or hijack connections without observing traffic. RFC 9293 mandates a cryptographic PRF incorporating connection 4-tuple and a secret key, so that observing one connection's ISN yields no information about ISNs of other connections.
A TCP connection progresses through states CLOSED, LISTEN, SYN-SENT, SYN-RECEIVED, ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, and TIME-WAIT. Triggers are user calls (OPEN, SEND, RECEIVE, CLOSE, ABORT), incoming segments with SYN/ACK/RST/FIN flags, and timeouts. RST from any synchronized state causes a transition to CLOSED; receiving FIN in ESTABLISHED transitions to CLOSE-WAIT.
TCP options occupy space after the fixed header, sized as (DOffset-5)*32 bits. Each option is either a single kind byte (EOL, NOP) or a kind byte followed by a length byte and data. All options except EOL and NOP MUST have a length field; the length counts the kind and length bytes themselves.
The Maximum Segment Size Option has Kind=2, Length=4, and a 2-byte MSS field encoding the maximum receive segment size at the sending endpoint. It MUST NOT be sent in segments without the SYN control bit set.
The TCP checksum covers a pseudo-header prepended to the segment: for IPv4, 96 bits comprising Source Address, Destination Address, zero byte, protocol number, and TCP length; for IPv6, 320 bits as defined in RFC 8200 Section 8.1, including the IPv6 source and destination addresses and upper-layer packet length.
The TCP header contains: Source Port (16 bits), Destination Port (16 bits), Sequence Number (32 bits), Acknowledgment Number (32 bits), Data Offset (4 bits indicating 32-bit words in header), Reserved (4 bits, must be zero), control bits CWR/ECE/URG/ACK/PSH/RST/SYN/FIN (1 bit each), Window (16 bits, unsigned), Checksum (16 bits), Urgent Pointer (16 bits), followed by variable-length Options padded to 32-bit boundary, then Data.