TCP Handshake & Control Flags
The Conversation Before the Conversation
TCP's reliability is famous, but it starts with a formal negotiation. Before two hosts exchange a single byte of application data, they perform a three-way handshake to synchronize sequence numbers and agree the connection exists. Understanding the handshake and the flags that govern it is the foundation of network debugging.
The Three-Way Handshake
- SYN: The client sends a segment with the
SYNflag and an initial sequence number (ISN), e.g.SEQ=1000. "I want to talk, and my first byte will be 1000." - SYN-ACK: The server replies with both
SYNandACK: its own ISN (SEQ=5000) plus an acknowledgment of the client's (ACK=1001). "I hear you; my first byte will be 5000, and I expect yours at 1001." - ACK: The client acknowledges (
SEQ=1001,ACK=5001). The connection is now ESTABLISHED.
The random ISNs are a security feature: predictable sequence numbers historically allowed TCP sequence prediction attacks that could inject forged data into a connection.
Sequence and Acknowledgment Numbers
Every byte in the stream is numbered. The sequence number says "this segment starts at byte N"; the acknowledgment number says "I have received everything up to byte M-1, send me M next." This sliding window is how TCP tracks what has arrived and what is missing, enabling retransmission of only the lost segments.
The Control Flags
- SYN: Synchronize sequence numbers; initiates a connection.
- ACK: Acknowledgment field is valid.
- FIN: Graceful close; "I have no more data to send."
- RST: Reset; abort the connection immediately (used for refused connections and protocol errors).
- PSH: Push buffered data to the application without waiting.
- URG: Urgent pointer is meaningful (rarely used).
Connection Teardown
Closing is a four-way process: one side sends FIN, the other ACKs it, then the other sends its own FIN, which is ACKed back. The side that sends the first FIN enters TIME_WAIT for a fixed interval (typically 2× the maximum segment lifetime) to ensure any delayed duplicate segments are drained before the port is reused.
Flow Control and the Window
The receive window field advertises how much buffer space the receiver has. If a receiver's application is slow, it advertises a smaller window, and the sender slows down. When the window hits zero, the sender pauses and periodically probes until the window opens—TCP flow control preventing a fast sender from drowning a slow receiver.
Congestion Control
Separate from flow control, TCP also estimates the network's capacity. Algorithms like slow start, congestion avoidance, fast retransmit, and modern variants (CUBIC, BBR) grow the sending rate when the network is healthy and back off when packets are lost. This is why a bulk download ramps up gradually over the first second—the sender is probing how much capacity the path can absorb.
Reading a Handshake While Debugging
When a request hangs, the handshake tells the story: - No SYN-ACK, just SYN retries: the server is unreachable or its firewall is dropping packets. - Immediate RST: the port is closed—nothing is listening. - SYN-ACK but no final ACK: an on-path device is filtering. - Handshake completes but data stalls: look at the window size and retransmissions.
Tools like tcpdump, Wireshark, and ss -tan expose exactly these flags in real time, turning a vague "the network is slow" into a specific diagnosis.