What happens
When a client calls connect() to a server, the kernels exchange three packets:
Client Server
| ── SYN seq=X ──────► | (1)
| |
| ◄── SYN-ACK | (2)
| seq=Y ack=X+1 |
| |
| ── ACK ack=Y+1 ─────► | (3)
| |
| <════════════════════════> | ESTABLISHED, ready to send data
What each packet contains
- SYN - flag
Sintcpdump. Client: "I want to open a connection, my ISN = X" - SYN-ACK - flags
S+A. Server: "agreed, my ISN = Y, I acknowledge your X+1" - ACK - flag
A. Client: "I acknowledge Y+1"
After the third packet both sides consider the connection Established.
The kernel on the server side adds it to the accept-queue, from which the accept() syscall
delivers it to the application.
ISN: Initial Sequence Number
Each side picks a random 32-bit ISN. This is not byte numbering starting from zero. The randomness protects against:
- Sequence-prediction attacks (injecting packets into someone else's connection)
- Confusion with stale packets after a crash
From there the sequence number increments by the payload size of each data packet.
Where to see it
In tcpdump each packet carries flags:
Flags [S], seq 1000 ← SYN
Flags [S.], seq 5000, ack 1001 ← SYN-ACK
Flags [.], ack 5001 ← ACK
Flags [P.], seq 1001:1041, ack 5001 ← data with PUSH (HTTP request)
A dot after a letter ([.]) means ACK.
When something goes wrong
- Connection refused - port is closed. The server sends RST instead of SYN-ACK.
- Connection timeout - packets are lost or a firewall drops them. The client retransmits SYN several times and gives up (about 3 minutes by default).
- SYN but no ACK - half the handshake is stuck. On the server side this is the SYN_RECV state. Many such entries indicate a SYN-flood attack.
- SYN cookies - defense against SYN-flood: the server does not allocate state until it receives ACK, encoding the ISN into a cookie instead.
What comes next
Immediately after the ACK the first data packet usually follows (HTTP GET, TLS ClientHello, etc.). On loopback this all takes microseconds. Over a WAN link you add at least RTT x 1.5 (handshake plus the first request).