Why TCP has options
The TCP header is 20 bytes and has no spare fields. Features invented later, such as bigger windows, had to go somewhere. The answer is the options area after the fixed header. The data offset field says how long the whole header is, in 4-byte words, so a receiver always knows where the options end and the data begins. The header, options included, can be up to 60 bytes.
Options are offered by each side in its SYN and a feature is used only if both sides offered it. Most options appear only in the handshake; a few (SACK blocks, timestamps) travel in later segments too.
The options you meet every day
On small screens, swipe sideways or focus the diagram and use the arrow keys.
Maximum segment size (MSS)
MSS is the biggest amount of data an end will accept in one segment, not counting headers. Each side announces its own. On Ethernet with a 1500-byte MTU it is normally 1460: 1500 minus 20 bytes of IP header and 20 bytes of TCP header. The sender uses the smaller of its own limit and the one the other side announced. This avoids fragmentation: splitting an IP packet because it is too big for a link.
A tunnel, VPN or PPPoE link uses some of those 1500 bytes for its own header, so a full-size packet no longer fits. If a router in the path drops it and the ICMP message that would warn the sender is filtered, large downloads hang while small pages load. The fix is to rewrite the MSS in the SYN as it passes through:
interface GigabitEthernet0/1
ip tcp adjust-mss 1360Cisco IOS: the router lowers the MSS in TCP SYNs that cross this interface to 1360, leaving room for tunnel headers. Pick a value for your link; 1360 is only an example.
Window scale
The window field is 16 bits, so it tops out at 65,535 bytes. On a fast link with a long round trip, that is too little to keep the pipe full. The window scale option sends a shift count, from 0 to 14. The real window is the field value multiplied by 2 to that power. A window field of 502 with a shift of 7 means 502 × 128 = 64,256 bytes. The largest possible shift gives a window of about 1 GiB. See windowing for what the window does.
SACK and timestamps
- Selective acknowledgement lets a receiver say which byte ranges it did get after a gap. Without it a single lost segment makes the sender guess which later ones also need resending. With SACK the sender resends only the hole.
- Timestamps carry the sender's clock value and echo the other side's. They give TCP a round-trip time sample for every acknowledgement and guard against old duplicate segments being mistaken for new ones on very fast links.
$tcpdump -nn -v 'tcp[tcpflags] & tcp-syn != 0' IP 192.0.2.10.51514 > 198.51.100.20.443: Flags [S], seq 1000, win 64240, options [mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 7], length 0
When options cause problems
- A firewall or NAT device that strips unknown options can switch off window scaling or SACK and cut throughput without any error.
- A wrong MSS on a tunnel makes only big transfers fail. Test with
ping -M do -s 1472 hoston Linux to see the largest packet that passes a 1500-byte path. - Reading options needs a capture of the handshake; options in later segments do not repeat the scale factor.
TCP options in short
- Options follow the 20-byte header; data offset gives the full header length.
- MSS = MTU minus IP and TCP headers (1460 on plain Ethernet).
- Window scale multiplies the 16-bit window by 2 to the shift; set only in the SYN.
- SACK and timestamps improve loss recovery and round-trip measurement.
Test yourself
On a 1500-byte Ethernet MTU, what is the normal TCP MSS?
In which segments can the window scale option be sent?
A window field of 100 with a window scale shift of 4 means a real window of:
Large downloads over a VPN stall, while small pages work. What is the best first fix?
What does the data offset field tell the receiver?