awesome-everything RU
↑ Back to the climb

Networking & Protocols

Sequence numbers and connection state

Crux How ISN randomisation hardens TCP against injection attacks, and the full state machine from CLOSED to TIME-WAIT.
Your altitude — climbing toward senior
ZeroJuniorMiddleSenior
You are at middle altitude — in the sky
◷ 14 min

You know the three steps of the handshake. Now look at what those steps actually exchange: random 32-bit counters whose specific values are not arbitrary — they are a security mechanism, a timing mechanism, and a state machine checkpoint all at once.

The three-step dance in detail

Bea sends SYN seq=X. She moves to state SYN-SENT. Sven receives it, allocates a buffer for the incoming direction, moves to state SYN-RECV, and replies SYN-ACK seq=Y ack=X+1. The ack=X+1 means “I saw your sequence number X; the next byte I expect from you is X+1.” (The SYN flag itself consumes one sequence number even though no data byte is sent.) Bea then sends ACK seq=X+1 ack=Y+1 and moves to state ESTABLISHED. Sven receives it, moves to state ESTABLISHED, and the connection is live.

Sequence number negotiation

1/3

Initial Sequence Numbers (ISN) — why random?

RFC 6528 specifies that ISN is computed as:

ISN = M + F(saddr, sport, daddr, dport, secret_key)

where M increments once per ~4 µs (making it hard to guess from the outside), and F is a hash of the 4-tuple and a secret key. Older implementations used a simple counter, which attackers exploited: an attacker could guess the next ISN, forge a packet with the right sequence number, and inject commands into an established connection. Modern ISNs are cryptographically random per connection, making blind injection impossible without eavesdropping.

The 1-RTT cost

Bea sends SYN, waits for SYN-ACK (1 RTT), sends ACK, and only then can she send an HTTP request. If the RTT is 100 ms (across a continent), 100 ms of latency is baked into the connection before the first application byte lands. This RTT matters because it decides the cadence of the entire application.

Handshake RTT costs
LAN RTT (cold)
0.1–1 ms
Regional RTT
20–40 ms
Intercontinental RTT
100–300 ms
TFO cold start
1 RTT + data
TFO warm start
0 RTT (data in SYN)
HTTP/2 benefit
1 connection, many streams

Connection close: FIN and TIME-WAIT

Closing is the mirror of opening: each side independently sends FIN to signal “I have no more data,” and the peer ACKs. Connections sit in TIME-WAIT for 2×MSL (~120 s typical) so any straggler retransmission can land harmlessly instead of being mistaken for a new connection’s data. The side that initiates close pays the TIME-WAIT cost; on busy clients this is fine, on busy servers it can become a problem — see the lesson on SYN cookies and TFO for TIME-WAIT exhaustion at scale.

The state machine

The states you will see in ss -tan output:

StateMeaning
LISTENServer waiting for SYN
SYN-SENTClient has sent SYN
SYN-RECVServer has sent SYN-ACK
ESTABLISHEDHandshake done, normal traffic
FIN-WAIT-1Close initiator sent FIN
FIN-WAIT-2Received ACK of own FIN
CLOSE-WAITReceived FIN from peer, must call close()
LAST-ACKSent FIN, awaiting final ACK
TIME-WAITPost-close cooldown (2×MSL)
CLOSEDNo connection

An accumulation of CLOSE-WAIT on a server usually means the application is not calling close() on accepted sockets — a resource leak.

Trace it
1/5

Trace a successful TCP three-way handshake and the first data byte.

1
Step 1 of 5
Client sends SYN. What state is the client in?
2
Locked
Server receives SYN. What does it allocate and what does it reply?
3
Locked
Client receives SYN-ACK. What does the ACK number tell the client?
4
Locked
Client sends ACK. What does the server do?
5
Locked
Client's first data byte. What sequence number does it carry?
Trace it
1/4

Trace what happens when the SYN packet is lost on the way to the server.

1
Step 1 of 4
Client sends SYN. Server never sees it. What does the client do?
2
Locked
After two more retries the SYN still fails. What happens?
3
Locked
What if the SYN reached the server but SYN-ACK was lost?
4
Locked
Why is this safe even on a flaky network?
Order the steps

Order the TCP state transitions for a client opening then closing a connection:

  1. 1 CLOSED
  2. 2 SYN-SENT (after send(SYN))
  3. 3 ESTABLISHED (after receive(SYN-ACK) and send(ACK))
  4. 4 FIN-WAIT-1 (after send(FIN))
  5. 5 FIN-WAIT-2 (after receive(ACK of FIN))
  6. 6 TIME-WAIT (after receive(FIN) and send(ACK))
  7. 7 CLOSED (after 2×MSL expires)
Quiz

Why is the SYN flag treated as consuming one sequence number even though no data byte is sent?

Why this works

Why older ISN implementations were dangerous. Before RFC 6528, many TCP stacks incremented the ISN by a fixed amount per second (~250,000 per second on BSD-derived systems). An attacker who could observe the timing of one connection could predict the next ISN with reasonable accuracy and forge an ACK or data segment — the classic TCP sequence number prediction attack. Randomised ISNs, combined with cryptographic mixing of the 4-tuple, make this attack computationally infeasible without being able to observe the actual SYN-ACK.

Recall before you leave
  1. 01
    Why are Initial Sequence Numbers (ISNs) randomised rather than starting from zero or incrementing globally?
  2. 02
    What does TIME-WAIT mean, how long does it last, and why does it exist?
  3. 03
    What does a large number of CLOSE-WAIT sockets on a server almost always indicate?
Recap

The three-way handshake exchanges Initial Sequence Numbers (ISNs) in both directions. ISNs are computed as a time-based counter plus a cryptographic hash of the connection 4-tuple (RFC 6528), making injection attacks infeasible. The SYN flag consumes one sequence number so the exchange is individually acknowledgeable. Once ESTABLISHED, both sides track the connection through an 11-state machine: LISTEN, SYN-SENT, SYN-RECV, ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT, CLOSED. TIME-WAIT persists for 2×MSL (~120s) to absorb delayed retransmissions. CLOSE-WAIT accumulation is the most common socket-leak symptom — the application is not calling close() on accepted sockets.

Connected lessons
appears again in258
Continue the climb ↑Flow control and congestion control
shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.