The three-way handshake
“Explain the TCP three-way handshake. Why three packets, what state exists on each side, and what can go wrong before a byte of data is sent?”
What this tests
- The purpose of each packet, not just their names
- Kernel state: SYN queue, accept queue, sequence numbers
- The distinction between timeout, refused and reset during connect
Answers by level
Read the beginner answer first and notice what is missing.
Each side needs to tell the other its initial sequence number and learn that the other heard it. The client sends SYN with ISN *x*; the server replies SYN-ACK — its own ISN *y*, and ack *x+1* to prove it received the SYN; the client sends ACK *y+1*. Three packets is the minimum for both sides to have their ISN acknowledged — two would leave the server unsure the client received its ISN. The SYN also carries options that shape the whole connection: MSS, window scaling, SACK permitted, timestamps. ISNs are randomised so old duplicates from a previous connection and off-path attackers cannot be confused with the live stream.
State on the server (Linux): a SYN creates a mini-socket in the SYN queue (SYN_RECV); the final ACK moves a full socket into the accept queue, where accept() picks it up. If the accept queue is full because the application is slow to call accept(), the kernel drops the final ACK (or the SYN) and the client retransmits — a slow connect with a healthy-looking server, visible as overflows in ss -ltn (Recv-Q vs Send-Q on the listener) and nstat -az TcpExtListenOverflows. SYN floods exploit the SYN queue; SYN cookies avoid storing state until the ACK arrives.
What can go wrong is a diagnostic ladder. No SYN-ACK at all → the client retransmits with exponential backoff (1, 2, 4, 8… s; ~2 minutes total by default on Linux) and reports "connection timed out": the SYN was dropped by a firewall, no route, host down, or the SYN-ACK was lost on an asymmetric return path. RST in reply to SYN → "connection refused", immediately: the host is reachable, no socket listens on that port (or a firewall *rejects* rather than drops). Handshake completes then RST → a stateful middlebox lost state, or the application closed instantly. Each is a different layer, and the client error names which.
Green flags · Red flags
- Explains why three (both ISNs acknowledged) and what the SYN options carry
- Names the SYN queue and accept queue and the symptom of an accept-queue overflow
- Maps timeout → dropped SYN, refused → RST, reset-after-connect → middlebox/app
- Counts the handshake as an RTT and relates it to TLS and QUIC
- Mentions SYN cookies or
ssstates as tools
- Recites SYN / SYN-ACK / ACK with no notion of sequence numbers or state
- Thinks "connection refused" means a firewall
- Cannot say what the client does when no SYN-ACK arrives
- Unaware the application must call
accept()for the connection to be usable
Follow-up questions
ss -ltn shows Recv-Q at the backlog limit. What is happening?