Three segments to open a connection and four to close it. The fact that the server commits memory on the second of those three is the basis of one of the oldest attacks on the Internet.
Words you will meet
- SYN (synchronize) synchronize The TCP flag bit that marks a connection-establishment segment. Set in the first two segments of the three-way handshake (§3.5.6). introduced in ch. 3 segment — the first segment of a connection, with the SYN bit set.
- SYNACK — the server’s reply: SYN set, plus an acknowledgement.
- FIN segment — “I have no more data to send”; closes one direction.
- Reset segment — RST set: “there is no socket here”.
- Half-open connection — one the server has allocated for, whose client never finished.
- SYN cookie — answering a SYN with a computed sequence number instead of remembering anything.
Why this matters
This looks like plumbing, and it is not.
Connection establishment adds significantly to perceived delay — section 2.2.2 counted a round trip per connection, and it is a real part of why a web page feels slow. And many of the most common network attacks exploit vulnerabilities in connection management, including the SYN flood, which this section covers in full.
Opening and closing
The first two segments carry no application data. The third may.
Click any arrow to see what that message says and why it is sent.
Three segments to open, four to close. Click any arrow for what its header actually carries.
Read this diagram as text
- Client host sends SYN=1, seq=client_isn to Server host. The SYN bit is set and the sequence number field carries a randomly chosen initial value. No application data. Randomising client_isn properly matters for security — there has been considerable interest in getting it right [CERT 2001-09, RFC 4987].
- Server host sends SYN=1, seq=server_isn, ack=client_isn+1 to Client host. The connection-granted segment, called a SYNACK. Three pieces of information: the SYN bit set, an acknowledgement of client_isn + 1, and the server’s own randomly chosen initial sequence number. In the book’s words: "I received your SYN to start a connection with your initial sequence number. I agree. My own initial sequence number is server_isn." AND — the detail that matters — the server has already allocated its buffers and variables by now.
- Client host sends SYN=0, seq=client_isn+1, ack=server_isn+1 to Server host. The client allocates its own buffers and variables, then acknowledges the server’s initial sequence number. The SYN bit is now zero, and stays zero for the rest of the connection. This third segment MAY carry application data — which is how a client can get its first request out without waiting another round trip.
Lifelines, left to right: Client host (host), Server host (server).
The three steps, and what each one commits
Step 1. The client sends a segment with the SYN bit set to 1 and no
application data, carrying a randomly chosen
initial sequence number syn segment Simple The first segment of a connection, with the SYN bit set and no application data. Precise A TCP segment with the SYN flag set to 1, carrying the sender’s randomly chosen initial sequence number and no application data. Randomising the initial sequence number matters for security [RFC 4987]. A SYN arriving at a port where nothing is listening is answered with a reset segment.
introduced in ch. 3 — open in glossary
, client_isn.
Step 2. The server extracts the SYN and allocates the TCP (Transmission Control Protocol) Transmission Control Protocol The Internet transport protocol that delivers data reliably and in order, with flow control and congestion control.
introduced in ch. 1 buffers and
variables to the connection. It replies with a
SYNACK synack segment Simple The server’s reply that grants the connection: SYN set, plus an acknowledgement. Precise The connection-granted segment: SYN set to 1, the acknowledgement field set to the client’s initial sequence number plus one, and the server’s own randomly chosen initial sequence number in the sequence-number field. It says, in effect, "I have your SYN, I agree, and here is my starting number."
introduced in ch. 3 — open in glossary
: SYN bit set to 1, acknowledgement field
set to client_isn + 1, and its own randomly chosen server_isn in the sequence
number field. Still no application data.
Step 3. The client allocates its own buffers and variables, and sends a third
segment with server_isn + 1 in the acknowledgement field and the SYN bit back
to zero. This one may carry application data.
Read step 2 again. The server commits memory when it has heard exactly one segment from a host that has proved nothing at all. Hold that thought.
Closing takes four segments, and either side may start. The client issues a close, its TCP sends a FIN fin segment Simple A segment with the FIN bit set, meaning "I have no more data to send". Precise A TCP segment with the FIN flag set to 1, used to shut down one direction of a connection. A full teardown takes four segments: each side sends a FIN and each FIN is acknowledged. The side that closes first then waits in TIME_WAIT before releasing its resources. introduced in ch. 3 — open in glossary , the server acknowledges, the server sends its own FIN, and the client acknowledges that. Then all the resources at both hosts are deallocated.
Everyday picture
A rock climber and a belayer use a three-way handshake three-way handshake Simple The three segments — SYN, SYNACK, ACK — that open a TCP connection. Precise TCP’s connection-establishment procedure. The client sends a segment with the SYN bit set and a randomly chosen initial sequence number; the server replies with SYN set, its own initial sequence number and an acknowledgement of the client’s; the client acknowledges the server’s. The first two carry no application data; the third may. Both sides allocate buffers and variables during the exchange, which is what the SYN flood attack abuses. introduced in ch. 3 — open in glossary that is identical to TCP’s, and for the same reason. “On belay?” — “Belay on.” — “Climbing.” Neither moves until both have confirmed that the other has confirmed.
Where the picture breaks: the climber and belayer can see each other, and either can simply repeat themselves until they get an answer. TCP’s two ends cannot, which is why the third message exists at all — and why the book leaves “why is a two-way handshake not enough?” as a homework problem.
The real thing
| No. | Time | Source | Destination | Protocol | Length | Info |
|---|---|---|---|---|---|---|
| 1 | 0.000000 | 192.168.1.24 | 198.51.100.7 | TCP | 54 | 51874 → 12000 [SYN] Seq=0 Win=64240 Len=0 |
| 2 | 0.090400 | 198.51.100.7 | 192.168.1.24 | TCP | 54 | 12000 → 51874 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 |
| 3 | 0.180800 | 192.168.1.24 | 198.51.100.7 | TCP | 54 | 51874 → 12000 [ACK] Seq=1 Ack=1 Win=64240 Len=0 |
| 4 | 0.181100 | 192.168.1.24 | 198.51.100.7 | TCP | 72 | 51874 → 12000 [PSH, ACK] Seq=1 Ack=1 Len=18 |
| 5 | 0.271800 | 198.51.100.7 | 192.168.1.24 | TCP | 72 | 12000 → 51874 [PSH, ACK] Seq=1 Ack=19 Len=18 |
| 6 | 0.271900 | 198.51.100.7 | 192.168.1.24 | TCP | 54 | 12000 → 51874 [FIN, ACK] Seq=19 Ack=19 Len=0 |
| 7 | 0.362300 | 192.168.1.24 | 198.51.100.7 | TCP | 54 | 51874 → 12000 [FIN, ACK] Seq=19 Ack=20 Len=0 |
| 8 | 0.452700 | 198.51.100.7 | 192.168.1.24 | TCP | 54 | 12000 → 51874 [ACK] Seq=20 Ack=20 Len=0 |
Packet 1 — Packet 1 of 8. clientSocket.connect() produced this, and the client program has not yet sent a single byte of the sentence. The UDP version was already finished sending by now.
Protocol tree — click a field
The actual bytes
0000 aa bb cc 00 00 01 aa bb cc 00 00 11 08 00 45 00 ..............E.0010 00 28 1a 01 40 00 40 06 34 d4 c0 a8 01 18 c6 33 .(..@.@.4......30020 64 07 ca a2 2e e0 3f 8a 12 c0 00 00 00 00 50 02 d.....?.......P.0030 fa f0 7d 29 00 00 ..})..
TCPClient.py and TCPServer.py exchanging one sentence. Six of these eight packets carry no application data at all: three open the connection and three more close it.
A SYN consumes a sequence number, though it carries no data
Look at the first three packets. The client’s SYN has Seq=0; the server’s
SYNACK has Ack=1; the client’s ACK has Seq=1.
The SYN carried no bytes, so why did the numbering advance by one?
Because the SYN bit itself occupies a place in the sequence space. That is what lets the handshake be acknowledged and retransmitted with exactly the same machinery as data. FIN works the same way, which is why the teardown numbers in packets 6, 7 and 8 also advance by one per FIN.
(The capture shows relative sequence numbers, as packet analysers do by
convention. The real values are the random client_isn and server_isn.)
The two state machines
Outlined buttons are the events this state can actually handle. Try the others too — what cannot happen is as much of the protocol as what can.
Drive it round. Six states, and the connection spends essentially all of its life in one of them.
Outlined buttons are the events this state can actually handle. Try the others too — what cannot happen is as much of the protocol as what can.
The mirror of the client, with one asymmetry worth noticing: no TIME_WAIT. The side that closes first is the side that waits.
In plain words
Twelve states between the two machines, and a healthy connection spends essentially its entire life in ESTABLISHED. Everything else is the few milliseconds at each end.
Notice the asymmetry: the client machine has a TIME_WAIT time_wait state Simple A short wait after closing, in case the last acknowledgement needs sending again. Precise The state a TCP enters after acknowledging the other side’s FIN. It lets the host resend that final acknowledgement if it was lost. The duration is implementation-dependent — 30 seconds, 1 minute and 2 minutes are all common. Only when it ends are all resources, including the port number, released. introduced in ch. 3 — open in glossary state and the server machine does not. That is not about clients and servers — it is about who closes first. The side that sends the first FIN is the side that must wait afterwards.
Why wait at all?
TIME_WAIT lets the client resend the final acknowledgement in case it was lost. If it were lost and the client had already vanished, the server would retransmit its FIN forever and never close.
The duration is implementation-dependent; 30 seconds, 1 minute and 2 minutes are all typical. Only when it ends is the connection formally closed and all resources released, including the port number. That is why a busy server which has just restarted can find its own port apparently still in use.
Neither diagram shows the pathological cases: both sides closing at once, or both opening at once. Stevens covers them [Stevens 1994].
When there is no socket at all
Both machines above assume the server is listening on the port the client aimed at. What if it is not?
The host sends a reset segment reset segment Simple A segment with the RST bit set, meaning "there is no socket here — stop". Precise A TCP segment with the RST flag set to 1, sent when a host receives a segment whose port numbers or source address match no socket on that host. It tells the source not to resend. The UDP equivalent is not a transport-layer segment at all: the host sends an ICMP destination-unreachable message (Chapter 5). introduced in ch. 3 — open in glossary — a TCP segment with the RST flag set to 1. In effect: “I don’t have a socket for that segment. Please do not resend it.”
And the UDP (User Datagram Protocol) User Datagram Protocol A simple transport protocol with no reliability, no flow control and no congestion control. introduced in ch. 1 equivalent is not a UDP thing at all
A UDP segment may also arrive for a port with no open socket. The host cannot reply in kind, because the UDP header has only four fields and none of them is a flag. So the network layer reports it instead, with an ICMP (Internet Control Message Protocol) Internet Control Message Protocol Carries error and diagnostic messages between hosts and routers. A ping is an ICMP message. Covered in §5.6. introduced in ch. 2 destination-unreachable datagram. Chapter 5 covers ICMP.
Same condition, two layers, because one protocol had a spare bit and the other did not.
| What it means | nmap reports | |
|---|---|---|
Cells marked ⓘ have an explanation — click to read it. Sortable columns have a ↕ in the heading.
Three outcomes, and the second is more useful to an attacker than it looks.
Section 3.2 introduced nmap and promised to come back once you knew how connection management worked. This is it: nmap sends a SYN to the port it wants to test and reads which of the three replies comes back. Repeat that across every port and it can map open TCP ports, open UDP ports, firewalls and their configurations, and often the versions of applications and operating systems. Almost all of it comes from manipulating connection-management segments.
The SYN flood
A SYN arrives. The server allocates buffers and variables, sends a SYNACK, and waits for the ACK that completes the handshake.
Six steps. The turn comes at step 4, and it is a very small change with a very large consequence.
Read all steps as text
- 1 — The ordinary handshake, from the server’s side — A SYN arrives. The server allocates buffers and variables, sends a SYNACK, and waits for the ACK that completes the handshake.
- 2 — If the ACK never comes — The connection sits half open. Eventually — often after a minute or more — the server gives up and reclaims the resources. For one stalled client that is a harmless waste.
- 3 — The attack — An attacker sends a large number of SYNs and never completes the third step. The server’s connection resources are exhausted by half-open connections that will never be used, and legitimate clients are refused. This was among the first documented denial-of-service attacks [CERT SYN 1996].
- 4 — The fix: do not remember anything — When a SYN arrives, the server does NOT create a half-open connection. Instead it computes an initial sequence number that is a hash of the source and destination IP addresses and port numbers, plus a secret known only to the server. That value is the cookie. It goes in the SYNACK — and the server then forgets it completely.
- 5 — A legitimate client answers — The client returns an ACK whose acknowledgement field is the SYNACK’s initial sequence number plus one — that is, the cookie plus one. It has no idea it is carrying a cookie; it is simply following the protocol.
- 6 — And the server checks it without remembering — The four values needed to recompute the hash — both addresses and both ports — are all in the arriving ACK, and the secret is the server’s own. If the recomputed hash plus one matches the acknowledgement field, this ACK belongs to a SYN the server really did answer. Only then does it create the connection and the socket.
The whole attack is one line of the handshake
The server allocates at step 2. If the client never sends the ACK, that allocation sits in a half-open connection half-open connection Simple A connection the server has set up resources for, whose client never finished the handshake. Precise The state a server is left in after replying to a SYN with a SYNACK when the third segment of the handshake never arrives. The buffers and variables stay allocated, often for a minute or more, before the server gives up and reclaims them. Creating many of these deliberately is the SYN flood attack. introduced in ch. 3 — open in glossary for a minute or more before being reclaimed.
An attacker sends a great many SYNs and completes none of them. The server’s connection resources are consumed by half-open connections that will never carry a byte, and legitimate clients are denied service. The SYN flood syn flood attack Simple Flooding a server with connection requests that are never completed, to exhaust its memory. Precise A denial-of-service attack in which an attacker sends a large number of TCP SYN segments and never completes the third handshake step. The server’s connection resources are consumed by half-open connections that will never be used, and legitimate clients are refused. Among the first documented denial-of-service attacks [CERT SYN 1996]. introduced in ch. 3 — open in glossary was among the first documented denial-of-service attacks [CERT SYN 1996].
Note what is not required: no compromised software, no unusual traffic volume per packet, nothing malformed. Every SYN is perfectly valid. The attack is entirely in what is left undone.
SYN cookies — and why they work
SYN cookies syn cookie Simple Answering a SYN with a specially computed sequence number instead of remembering anything. Precise The standard defence against SYN flooding [RFC 4987]. Instead of allocating state for an arriving SYN, the server sets the SYNACK’s initial sequence number to a hash of the four-tuple and a secret known only to the server, and remembers nothing. A legitimate client’s ACK returns that value plus one; the server recomputes the hash and, if it matches, creates the connection then. A bogus SYN costs the server nothing. introduced in ch. 3 — open in glossary [RFC 4987] are now deployed in most major operating systems, and the idea is elegant.
When a SYN arrives, the server does not know whether it is legitimate. So rather than deciding, it declines to commit. It computes an initial sequence number that is a hash of the source and destination IP (Internet Protocol) Internet Protocol The network-layer protocol that defines the datagram format and addressing every Internet device must use. introduced in ch. 1 addresses and port numbers, plus a secret known only to the server. That value is the cookie. It goes in the SYNACK, and the server then remembers nothing at all.
A legitimate client returns an ACK whose acknowledgement field is, by the ordinary rule of the handshake, the SYNACK’s sequence number plus one. Every value needed to recompute the hash is present in that arriving segment — both addresses, both ports — and the secret is the server’s own. If the recomputed hash plus one matches, the ACK corresponds to a SYN the server really did answer, and only then is a fully open connection and socket created.
And if the client never answers, the original SYN has done no harm, because nothing was ever allocated.
A slip in the book’s description
The sidebar says the server compares its recomputed value against “the acknowledgment (cookie) value in the client’s SYNACK”.
Clients do not send SYNACKs — the server does. The value being checked is in the client’s ACK, the third segment of the handshake. Everything else in the description is right, and the surrounding sentences make the intent clear.
Check yourself
Check yourself
0 of 6 answered1.At which step of the three-way handshake does the server allocate buffers and variables?
This is the detail the whole SYN flood attack turns on.
2.predictIn the packet capture, segment 2 carries Seq=0 and Ack=1 while the client's SYN carried Seq=0. Why does the acknowledgement say 1?
3.Why does the client wait in TIME_WAIT rather than closing immediately?
4.predictnmap sends a SYN to port 6789 and receives an RST. What has it learned?
5.How does a SYN cookie let a server verify a returning ACK without having remembered anything?
6.A host receives a TCP SYN for port 80, but nothing is listening there. What does it send back? And what if it had been a UDP segment?
What to remember
- Three segments to open — SYN, SYNACK, ACK — and four to close: FIN, ACK, FIN, ACK, with either side able to start. A SYN consumes one sequence number even though it carries no bytes, and so does a FIN.
- The server allocates at step 2, before the handshake completes. That single fact is the SYN flood, and SYN cookies answer it by hashing the state into the sequence number instead of storing it.
- The side that closes first enters TIME_WAIT, for 30 s, 1 min or 2 min, so it can resend the final acknowledgement. Its port is held until then.