TCP zero windows

Yet another reason downloads can fail…

Issue :

Large file is being downloaded (eg an ISO running above 500MBs). The file starts off downloading fine, but eventually stops downloading, leaving the file incomplete.

Cause (in this case) :

TCP zero windows caused the server to reset the connection

Troubleshooting :

In wireshark, run the following filter:

tcp.analysis.flags or tcp.flags.reset==1 and ip.addr==77.67.2.51

where 77.67.2.51 is the IP address of the server you are downloading from. The filter showed this:

zerowindow

Note how the client is sending the TCP ZeroWindow, and eventually the server sends a RESET packet. The solution in this case was to reduce the tcp window size on the client (effectively slightly slowing down the connection)

Theory behind this :

The TCP window size is, in  a nutshell, the receive buffer size of a host. So, for example if the window size is set to 65535, then the sending host can send 65535 bytes of data to the receiver and only then wait for an acknowledgement. So, the larger the window size, the less times the sender has to stop and wait for an acknowledgement, speeding things up.

(FYI there is plenty of reading on TCP flow control, such as windows scaling, selective acknowledgements and so on…)

Conversely, a smaller window size means the sender must stop more often to wait for an ACK. At the extreme, when the receiver sends a TCP ZeroWindow it effectively is telling the sender:

“My receive buffer is full… wait until I can clear it”

The server waits a while, then checks the window size again (that’s the TCP ZeroWindowProbe), and if the client still has a window size of 0 (that’s the TCP ZeroWindowProbeAck), then it has to wait some more before sending data.

If this goes on long enough, the server will reset the connection.