Walk me through the TCP header. What does each field do?
Show the answer
Say this first
The TCP header is 20 bytes without options and up to 60 with them. It carries source and destination ports, a 32-bit sequence number, a 32-bit acknowledgment number, the data offset (header length in 4-byte words), the flags, a 16-bit receive window, a checksum, the urgent pointer, and then options such as MSS, window scale, SACK and timestamps.
Go deeper
Fields in order
| Field | Bits | What it does |
|---|---|---|
| Source port | 16 | Sender's port, usually ephemeral on the client |
| Destination port | 16 | Receiver's port, for example 443 |
| Sequence number | 32 | Byte number of the first data byte in this segment (or the ISN in a SYN) |
| Acknowledgment number | 32 | Next byte the sender of this segment expects to receive, valid when ACK is set |
| Data offset | 4 | Header length in 32-bit words, 5 to 15, so 20 to 60 bytes |
| Reserved | 4 | Must be zero |
| Flags | 8 | CWR, ECE, URG, ACK, PSH, RST, SYN, FIN |
| Window | 16 | Receive window in bytes, shifted left by the window scale factor if one was agreed |
| Checksum | 16 | Covers a pseudo-header (source IP, destination IP, protocol, TCP length), the header and the data |
| Urgent pointer | 16 | Only meaningful with URG, almost never used |
| Options | 0 to 320 | Up to 40 bytes |
Options worth knowing by number
| Kind | Option | Where |
|---|---|---|
| 0 | End of option list | Padding |
| 1 | NOP | Alignment padding |
| 2 | MSS (4 bytes) | SYN and SYN-ACK only |
| 3 | Window scale (3 bytes) | SYN and SYN-ACK only |
| 4 | SACK permitted (2 bytes) | SYN and SYN-ACK only |
| 5 | SACK blocks (variable) | Any segment after the handshake |
| 8 | Timestamps (10 bytes) | SYN, then every segment if both agreed |
TCP has no length field of its own: the segment length is the IP total length minus the IP header minus the TCP data offset.
They will ask next
What is the pseudo-header and why does TCP checksum it?
It is the source IP, destination IP, protocol number and TCP length, included in the checksum but never sent. It lets the receiver detect a segment delivered to the wrong address. It is also why NAT must update the TCP and UDP checksums when it rewrites an IP address.
Why can a segment carry only three SACK blocks when timestamps are on?
Options are capped at 40 bytes. Timestamps take 10 bytes plus 2 NOPs for alignment, leaving 28. A SACK option is 2 bytes plus 8 per block, so 3 blocks fit. Without timestamps, 4 blocks fit.
What do timestamps give you besides RTT measurement?
PAWS, protection against wrapped sequence numbers. At 10 Gbit/s the 32-bit sequence space wraps in about 3.4 seconds, so an old delayed segment could look valid. The timestamp tells old from new.
Traps
- Calling the window field "the congestion window". It is the receive window. The congestion window is never sent on the wire.
- Forgetting that the header length field counts 4-byte words, so a value of 5 means 20 bytes.