TCP sliding window is very crucial concept in understanding how TCP behaves. In order to see how this mechanism works, I have rate limited an HTTP download and observed what happens during this scenario in which we will see reports from Wireshark that [TCP Window Full] and [TCP ZeroWindow]. The aim of this post is to try to show how wireshark understands that Window is full.
We have a web server and a client machine on this setup. We intentionally rate limit the traffic by using wget to allow us investigate this scenario.
root@LAB1021-PC10:~# wget http://10.11.5.2/test.iso --limit-rate=50K
Connecting to 10.11.5.2:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1048576 (1.0M) [application/x-iso9660-image]
Saving to: test.iso
100%[================================================================>] 1,048,576 50.3KB/s in 20s
(50.1 KB/s) - test.iso saved [1048576/1048576]
Yes we have downloaded the the file. During the download I also took packet capture on the client side. In order to understand the behaviour, first this rate limiting needs a bit of explanation. When you set the option “–limit-rate” on wget, software in order to sustain the throughput you set, sends a TCP segment with Window Size set to 0 which literally instructs the sender to pause. As my aim is to try to understand how Wireshark notices window full situation, we are starting to investigate the packet capture right after client sends a TCP ACK with Window Size zero.
We should better zoom into particular time frame in order to understand this event easier as the whole story is developed between Pkt 181 and Pkt 200 in this capture. You need to take a look at this screenshot before going further in the article since it shows how we go from “Window Zero” to Window full state.
Packet no: 181 is sent from client with Win=0 as you can see. At that particular moment, sender knows that it isn’t allowed to send any more packets.
Packet no: 182 client this time decides to accept packets because of which sets the WindowSize to 22656 (Win=22656). What does this mean practically? As window size is a number which tells the sender that “You can send this number of bytes without expecting any acknowledgement from me“, sender resumes sending segments as fast as it can from this point on.
Packet no: 183 – 197 In a normal TCP communication you don’t see this number of segments which aren’t acknowledged. This is because of our rate limiting actually.
Now we stop the clock right after packet 197 is received i.e T=0.653210000 and take a closer look at the status of the window or we somehow take a snapshot of the receive window at this point.
Have you stopped the clock at Time = 0.653210000. Remember! client had told sender that your window is 22656Bytes. You can only send this amount with no ACK from me. What we see here is that packets from 183 to 197 didn’t receive any ACK from client (receiver). Hence number of bytes sent but not ACKed are 20272Bytes. This means sender can send 22656 – 20272 = 2280Bytes more and if doesn’t receive any feedback(ACK), then it will stop.
Packet 198: but something happens here. Receiver(client) decides to acknowledge some of the bytes by setting ACK=4109684389. What does really this mean? With this single number, Receiver is telling the Sender that “I have received all the bytes up to this byte”. By this announcement, Receiver has actually acknowledged Pkt 183 sent from the sender. Not clear? Maybe I can show it like this. Let’s open the bytes on Pkt 183 and see how the bytes are counted.
SEQ number (4109683925) is the first byte in the TCP segment which is an inclusive number and our packet’s TCP payload has 464 bytes which means the last byte number is (4109684388). Hence on the ACK Pkt 198, receiver says that it is acknowledging the last byte 4109684388 by setting the ACK to 4109684389. It is important to understand that ACK number is the next expected sequence number of the TCP segment from the other side.
Now what happens. This is really important to understand the whole topic. At the beginning of the transaction on Pkt 183, receiver had set the Window to 22656 but now on this latest ACK (Pkt 198), it is reducing the window size further to 22272 (Win=22272) hence sender should send less bytes and the below image shows both how window is sliding and reduced at the same time.
What does this snapshot of the Receive window mean?
It means sender can send 2000 Bytes more without any acknowledgement from the receiver.
Pkt 199 (1448 Bytes) and Pkt 200 (552 Bytes) are sent from the sender which fills this usable window 2000Bytes. Therefore there isn’t any available space left in the receive window and Wireshark immediately detects and displays you the message [TCP Window Full]
I must say that it is really cool! Wireshark is doing a wonderful job to help people troubleshooting network issues.
I am hoping I haven’t done any conceptual mistake here. This is how I understand this behaviour. If you have anything to add or correct, please do let me know.