The three questions cover when a TCP receiver sends an ACK and how three
duplicate ACKs make the sender retransmit; what goes wrong when a two-message handshake meets a
request that was delayed in the network, and how TCP's three-message handshake avoids it; and why
the server's starting number y has to be new and unpredictable.
The strip is a receiver's copy of the byte stream, numbered from byte 1 and cut into 50-byte segments (these are not the worksheet's numbers). A shaded box is a segment the receiver has; the dashed box is a segment that has not arrived.
A TCP ACK number is the number of the next byte the receiver expects §3.5.2, which is the first byte it is still missing, not the last byte it got. Here that is byte 51. The ACK is cumulative: one number says "everything before this has arrived", so the segments the receiver holds past the gap do not change it.
Host A is uploading a file to host B over a connection that is already established. Every segment A sends carries 100 bytes. The capture uses relative sequence numbers, so the first byte of the connection is byte 1. B sends no data of its own and has plenty of free buffer space.
A sends six segments back to back. The third of them, carrying bytes 201–300, is lost; every other segment arrives in the order it was sent. An ACK number names the next byte B expects. B decides what to send back using four rules:
| Rule | What arrives at B | What B does |
|---|---|---|
| R1 | In-order segment, the byte B expected next. Nothing else is waiting to be ACKed. | Wait up to 500 ms for another segment. If none comes, send the ACK. |
| R2 | In-order segment, the byte B expected next. One earlier segment is still waiting to be ACKed. | Immediately send one cumulative ACK covering both. |
| R3 | Out-of-order segment: a higher sequence number than expected, so a gap has opened. | Immediately re-send the ACK for the last in-order byte. |
| R4 | A segment that fills or partly fills the gap. | Immediately send an ACK, provided the segment starts at the low end of the gap. |
For each segment that reaches B, give the rule that fires and the Ack number B puts in its reply. Write "none yet" where B does not send one. Row 1 is filled in as an example.
| # | Arriving at B | Bytes it carries | Rule | Ack number B sends |
|---|---|---|---|---|
| 1 | 1st segment | 1–100 | R1 | none yet |
| 2 | 2nd segment | 101–200 | ||
| 3 | 4th segment | 301–400 | ||
| 4 | 5th segment | 401–500 | ||
| 5 | 6th segment | 501–600 | ||
| 6 | 3rd segment, resent by A | 201–300 |
At the moment A decides to retransmit, which bytes does B actually have? Can A know that from the ACKs it has received?
1R2 201 · R3 201 · R3 201 · R3 201 · R4 601
| # | Arriving at B | Bytes it carries | Rule | Ack number B sends |
|---|---|---|---|---|
| 1 | 1st segment | 1–100 | R1 | none yet |
| 2 | 2nd segment | 101–200 | R2 | 201 |
| 3 | 4th segment | 301–400 | R3 | 201 |
| 4 | 5th segment | 401–500 | R3 | 201 |
| 5 | 6th segment | 501–600 | R3 | 201 |
| 6 | 3rd segment, resent by A | 201–300 | R4 | 601 |
Rows 1 and 2 belong together. When the first segment arrives nothing else is pending, so R1 holds its ACK back. The second segment arrives inside that wait with an ACK already pending, so R2 sends one cumulative ACK for both: Ack 201, the next byte B expects. This delayed ACK §3.5.4 is why a real capture shows about one ACK for every two segments.
Rows 3, 4 and 5 each bring a segment that starts past byte 201, so a gap is open and R3 fires every time: B immediately repeats the ACK for the last in-order byte, which is Ack 201 again. Row 6 is the resent segment, and it starts exactly at the low end of the gap, so R4 fires. It fills the only hole, B now holds every byte through 600, and one ACK, Ack 601, covers all of it.
If you wrote 200 in row 2, you gave the last byte B received rather than the next byte it expects. An ACK number is always the first byte the receiver is still missing (Figure 1). This is the same slip as on the Week 4 quiz.
The two vertical lines are hosts A and B, with time running downward. Each arrow is one segment: data from A on the left, labelled with the bytes it carries, and ACKs from B on the right, labelled with the rule that produced them. The ✕ is where the third segment is lost.
Count the arrows that carry Ack 201: there are four, and only the last three are duplicates.
Four ACKs carry Ack 201. The first, from row 2, is an ordinary cumulative ACK: it is new information, telling A that bytes 1–200 arrived. The three after it, from rows 3, 4 and 5, are duplicate ACKs, because they repeat a number A has already seen. TCP's fast retransmit §3.5.4 resends the oldest unACKed segment when three additional ACKs for the same data arrive. So A resends 201–300 when the third duplicate arrives, which is the fourth Ack 201 overall, and it does so without waiting for its timeout.
If you expected A to resend after three Ack 201s in total, you counted row 2's ACK as the first duplicate. It is not one: it was the first time A heard 201. The rule asks for three ACKs beyond that one, and an earlier trigger would resend segments that were only reordered, not lost.
2B has 1–200 and 301–600; A cannot tell
B has delivered bytes 1–200 and is holding 301–600 out of order. It is missing only 201–300. But every ACK A has received says the same thing, "the next byte I want is 201". From that A learns that something is missing and which byte it starts at, and nothing about what arrived after it. That is the cost of a cumulative ACK.
So A resends only the oldest unACKed segment and waits. The Ack 601 in row 6 is the first moment A learns that B already had 301–600. Had A also resent 301–600, it would have spent three segments on data the receiver was already holding.
If you said A knows B has 301–600 because it received three duplicates, you have read more into them than they carry. Three duplicates tell A that three later segments arrived, but not which ones; a duplicate ACK names only the gap.
The worksheet left two things out. It assumed A's window let it send six segments back to back, and it never let A's timeout fire. How large that window may be is flow control §3.5.5 and congestion control §3.7; how the timeout is set from measured round-trip times is §3.5.3.
§3.5 Connection-oriented Transport: TCP · video · video (part 2) · knowledge checks · practice problems
Figures after the authors' Chapter 3 slides, copyright © 1996–2025 J.F. Kurose and K.W. Ross.
Each box is a state the server can be in, and each arrow is a move between states, labelled with the message or event that causes it and what the server does as it moves. The dashed arrow is the move made when a timer runs out. These are the same rules the question states in words below, drawn so the two servers can be compared.
The 2-way server has one arrow out of LISTEN, and it leads straight to
ESTAB, where the connection is allocated. The 3-way server stops halfway, in
SYN_RCVD §3.5.6, holding only x and its own new
y, and it has a way back to LISTEN that does not need the client.
A connection cannot start until both sides agree they want it and agree on the sequence number each will start from. The network in this question may delay a message for a very long time without losing it, and either side retransmits anything it thinks went missing. Nothing is corrupted and nothing is lost forever. Here are both protocols.
x and sends req_conn(x).
Retransmits it if no reply comes back in time. Enters ESTAB when
acc_conn(x) arrives.req_conn(x): records x, allocates the
connection's buffers, enters ESTAB immediately, and replies
acc_conn(x).LISTEN → ESTAB. The server leaves
ESTAB only when the connection is closed by a client, and it runs no timer while
in ESTAB.x and sends SYN(x). On receiving
SYN-ACK(y, ack = x+1): enters ESTAB and replies
ACK(ack = y+1).SYN(x): records x, picks a brand-new
number y that it has never used before, replies SYN-ACK(y, ack = x+1),
and enters SYN_RCVD. It does not allocate the connection yet. It enters
ESTAB only when an ACK carrying ack = y+1 arrives.LISTEN → SYN_RCVD → ESTAB. A
SYN_RCVD entry has a timer running, and is thrown away if no matching
ACK arrives. After a client closes the connection, the server returns to
LISTEN.Run this scenario for both protocols: The client's first request is delayed in the network. It retransmits, the connection is established, data is exchanged, and the client closes. Long afterwards, the delayed packet finally reaches the server.
Each half has two vertical lines, the client on the left and the server on the right, with time running downward; each arrow is one message. The long dashed arrow is the client's first request, which leaves at the top and is not delivered until the bottom. The seven boxes, L1–L3 and R1–R4, are where the server's state is asked for. A ✕ on the client's line marks the client closing and, lower down, the point where there is no client any more. The dotted grey arrow at the bottom right is the message part 4 asks about.
Write the server's state in each of the seven boxes, using only LISTEN,
SYN_RCVD and ESTAB.
Compare L1 and R1. The same message has just arrived at both servers. What resources has the 2-way server committed that the right-hand one has not?
On the 2-way side, the server ends in the state you wrote in L3. Will it release any reserved resources?
On the 3-way side, write on the dashed arrow the message that would have to arrive for the server
to reach ESTAB. Give two reasons it never will — one about the client, and one
about the number y′ itself.
ESTAB, and check which of them can happen when nobody is on the other end. For part 4,
ask when y′ was chosen, and whether anything sent before that moment could contain
y′+1.1The seven states
The sheet's diagram with the seven states and part 4's missing message filled in.
Both servers see exactly the same arrivals; only their rules differ. When the retransmitted request
arrives, the 2-way server's rule sends it straight to ESTAB (L1), while the 3-way server
only enters SYN_RCVD (R1) and waits for an ACK carrying y+1,
which arrives at R2. Both go back to LISTEN when the client closes (L2, R3). When the
delayed copy finally arrives, each server does exactly what it did the first time:
ESTAB at L3, SYN_RCVD at R4.
If you wrote ESTAB at R1, you read the 3-way handshake as the 2-way one with an extra message added on the end. The difference comes earlier than that: the 3-way server does not commit to anything on the first message (Figure 3).
2The whole connection
The 2-way server has allocated the connection — its buffers, its sequence-number state, an entry
in its connection table — and declared it open, all on the strength of one message that it has no
way to date. The 3-way server has recorded x and picked y, and that is
all: a small tentative record with a timer on it. It has promised nothing and allocated
nothing.
This is the point the question is built on. The 3-way handshake's first gain is not that it recognises the old copy; it is that it refuses to commit until something proves the request is current.
3No — nothing ever releases it
By the rules above, a 2-way server leaves ESTAB only when the client closes the
connection, and there is no client to close it. No message is outstanding, so no timer is running.
The entry survives until someone restarts the server. This is a half-open connection
§3.5.6, and every old duplicate that arrives creates another one. Worse, a
delayed copy of the old data(x+1) can now arrive and be accepted as new data, because
as far as the server is concerned this is a live connection whose next expected byte is
x+1.
If you answered that it times out, you gave the server a timer its rules say it
does not have. The question's 2-way server runs no timer in ESTAB, and that single
clause is the difference between the two servers.
4ACK(ack = y′+1)
The client. It closed long ago. Nobody at that address is expecting a
SYN-ACK, so nobody will answer it; a host that is there but was not expecting one
replies with a reset, which ends the attempt sooner still.
The number y′. This is the reason that matters. The server invented
y′ at the moment the delayed SYN arrived, so it has never appeared on the
network before. No message that was already travelling — however long it was delayed, and however
many copies of it exist — can contain y′+1. Old traffic cannot answer the question the
server has just asked. That is why the server can safely throw the SYN_RCVD entry away
when its timer runs out: it knows exactly what it is waiting for, and that nothing in flight can
supply it.
The question drew the client's close as a single ✕. How a TCP connection actually closes, with a
FIN from each side, is §3.5.6, and the Timeline worksheet
draws it in full.
§3.5 Connection-oriented Transport: TCP · video · video (part 2) · knowledge checks · practice problems
y must be newThe boxes are three machines on the Internet, and the arrows are the three handshake messages, numbered in the order they are sent. The attacker sends message ① with the trusted client's address written in as its source, so the server takes it for a request from the client. Message ② goes to the address it came "from", which is the trusted client, so the attacker never receives it. The dashed arrow ③ is the message the attacker needs to send next.
The attack succeeds only if the attacker can fill in ③ without ever having seen ②. Part 5
asks which choices of y let it.
Q2 showed that the 3-way handshake survives an old duplicate. This question is about why, and about what would break if one detail changed.
For each message of the 3-way handshake, what does the side that receives it now know for certain?
| Message | Received by | What the receiver now knows for certain |
|---|---|---|
SYN(x) | server | |
SYN-ACK(y, ack = x+1) | client | |
ACK(ack = y+1) | server |
Messages 2 and 3 do the same job in opposite directions. Say what that job is in one sentence, and explain why message 1 cannot do it for either side.
A lazy server always uses y = 100 for every connection instead of picking a
new number each time. A client opened a connection to this server earlier, so copies of
SYN(x), SYN-ACK(100, ack = x+1) and ACK(ack = 101) have all
crossed the network at some point — and the network may still deliver an old copy of any of
them.
Complete the timeline by filling in the boxes.
Three messages were exchanged in part 3, exactly as the protocol requires, and the server still
ended up connected to nobody. What property must y have for the 3-way handshake to
do its job?
What we mean by an attack
Everything so far went wrong by accident — an old copy turned up at a bad moment. Now add a third machine that is doing it deliberately.
There are three parties: the server; a client the server trusts, perhaps because the server only accepts connections from inside the university; and an attacker somewhere else on the Internet. Neither the client nor the server is misbehaving — the attacker is a stranger to both. What the attacker wants is for the server to open a connection that it believes belongs to the trusted client, so that it can then send data the server would never accept from the attacker's own address.
The attacker can write any source address into the packets it sends, so it puts the
trusted client's address on a SYN(x). But it has stolen the address, not the
path: the server's reply, SYN-ACK(y, ack = x+1), is delivered to the trusted
client, not to the attacker. The attacker never sees y. So the whole attack
comes down to one question — can it produce ack = y+1 without having seen message 2? If
it can, the server completes the handshake and believes the trusted client is on the other end. If it
cannot, the attacker is stuck and the server's SYN_RCVD entry simply times out.
Which of these choices of y would be safe? For each, say what an attacker or an old
copy would have to do to defeat it.
Choice of y | Safe? | Why / how it is defeated |
|---|---|---|
y = x (reuse the client's number) | ||
| A counter the server increases by 1 per connection | ||
| A number the server picks at random |
After message 3 arrives, the server knows the client is live. Does the client know that the
server received its ACK? If not, why is the handshake still finished?
y+1 on a
message? And what could you write without having seen anything?y+1. For part 5, apply the test from the note to
each row: can someone produce ack = y+1 without ever receiving message 2?1Only 2 and 3 prove anything about now
| Message | The receiver now knows |
|---|---|
SYN(x) → server | That someone, at some time, asked to open a
connection proposing x. Not that they are still there, and not when it was sent: an
old copy looks exactly like a fresh request. |
SYN-ACK(y, ack = x+1) → client | That the server is alive
right now, is willing, and actually received x — it could not have written
x+1 without seeing x. And that the server's number is y. |
ACK(ack = y+1) → server | That the client is alive right
now and actually received y: nobody who has not seen this SYN-ACK can
produce y+1. |
The words "right now" in the second and third rows are the whole difference from the first. They are what an old copy can never supply.
The client and server lines, with time running downward and one arrow per message, as in Figure 2. On the right, beside each arrow, is what that message proves to the side that receives it.
Messages ② and ③ each carry back a number the other side chose a moment earlier. Message ① carries back nothing.
2Each proves the other side is alive now
Messages 2 and 3 each prove to one side that the other side is alive at this moment, by echoing
back a number that the receiving side has only just chosen. Message 1 echoes nothing; it only
proposes x. Nothing in it is something the sender had to have just learned, so the
network can hand the server a copy from an hour ago and it will look exactly like a fresh request.
A message that carries no evidence of recent contact cannot prove recent contact.
This pattern has a name: challenge and response. One side sends a number the other could not have known in advance, and the other proves it is present by sending it back.
3Box 1: SYN_RCVD · Box 2: ESTAB
The server follows its rules perfectly. The old SYN puts it in SYN_RCVD,
and it replies with y = 100. Then the old ACK(ack = 101) arrives, and 101
is y+1, because y is always 100. The rule says enter
ESTAB, so it does. The server is now half-open with no client, exactly like the left
half of Q2, despite having run a three-message handshake.
4Fresh and unpredictable
y must be a value that nothing already on the network could contain — one the server
has never used before — and that no one else can predict. Its only job is to be evidence of recent
contact that cannot be guessed.
If you answered only "different every time", you have the first half. A counter is different every time too, and part 5 shows why that is not enough.
5Only the random y is safe
Choice of y | Safe? | Why |
|---|---|---|
y = x | No | x is written in the
SYN itself. The attacker chose x, so it already knows x+1; and
a delayed copy of an old ACK carries exactly the x+1 that an old
SYN would now be challenged with. The challenge contains its own answer. |
| Counter, +1 per connection | No | Better than a constant,
because old copies no longer match. But an attacker can open one connection of its own, see the
current value in the SYN-ACK it receives, and predict the next few. It can then forge
message 3 without ever receiving message 2. |
| Random | Yes | To answer the challenge you must actually have
received the SYN-ACK, which means being at the address you claim, and being there
now. |
The test for every row is the one in the note: could someone produce ack = y+1 without
ever receiving message 2? For the first two rows the answer is yes. "Safe" here means only that; it
does not mean the data is encrypted or that the server knows who it is talking to.
This is not hypothetical. Predictable starting sequence numbers were the basis of real TCP sequence-number prediction attacks, and TCP implementations are now required to choose their initial sequence number unpredictably. Attacks of this kind are Chapter 8.
6No, and it does not need to
The client cannot know its ACK arrived. That ACK could have been lost, and
no confirmation can settle it for good, since every confirmation would need a confirmation of its
own.
The handshake is finished anyway because nobody needs that knowledge to make progress. If the
ACK was lost, the server is still in SYN_RCVD; its timer fires, it
retransmits the SYN-ACK, and the client answers again. And any data the client sends
will be acknowledged, which settles the matter in passing. The protocol is built so that the only
unconfirmed message is one whose loss corrects itself. The authors' climbing analogy is the same
shape: "On belay?" — "Belay on." — "Climbing." The climber does not wait for a fourth message
confirming that "Climbing" was heard.
If you answered yes, the client knows, ask what message would have told it. The server sends nothing in reply to message 3 as part of the handshake.
§3.5 Connection-oriented Transport: TCP · video · video (part 2) · knowledge checks · practice problems
GW CSCI 4431/6431 Computer Networks · TCP Worksheet