Understanding TCP Window Full in Wireshark


1. Introduction

By default, Wireshark’s TCP dissector tracks the state of each TCP session and provides additional information when it detects problems or potential issues. When a capture file is first opened, each TCP packet undergoes analysis in the order it appears in the packet list. This feature can be enabled or disabled via the “Analyze TCP sequence numbers” TCP preference setting.

2. TCP Analysis Display

When conducting TCP analysis on packet files, the “TCP Window Full” alert typically appears as follows:

  • 2.1 Packet List Window: In the Info column, “[TCP Window Full]” is highlighted in red text on a black background.
  • 2.2 Packet Details Window: In the TCP protocol tree, under [SEQ/ACK analysis] -> [TCP Analysis Flags], the analysis of the TCP packet is explained.

3. Defining TCP Window Full

In simple terms, a “TCP Window Full” condition occurs when the size of a TCP segment sent by the sender exceeds the receiver’s advertised window size. This limitation is due to the receiver’s window size, which is a condition marked by the sender, not the receiver.

When the segment size is non-zero, and the window size in the reverse direction is known, if the segment size exceeds the reverse window size, the “TCP Window Full” flag is set.

Here’s an example of code that detects the “Window Full” condition in TCP data streams. The flag is set when the current data segment reaches the boundary of the receiver’s advertised window:

4. Packetdrill Example

The logic for TCP analysis is straightforward, making it easy to simulate the “TCP Window Full” condition using packetdrill. Here’s an example:

After capturing packets with tcpdump and analyzing them in Wireshark, it becomes evident that since the client (No. 5) advertised a window size (Win) of 1000, the server can only send data segments up to 1000 bytes. Consequently, the server sends two packets (No. 6 and No. 7), each with a length (Len) of 500 bytes. In packet No. 7, Wireshark flags it as “[TCP Window Full]” because the total size of the sent bytes has reached the window size advertised by the client.

The BIF size is 1000, and the expert information indicates that the TCP window specified by the receiver is now completely full.

TCP Window Full

5. Case Studies

Regarding examples of TCP Window Full, under normal circumstances, considering the release speed of the receiver’s window and the presence of Window Scaling, the occurrence of a TCP Window Full condition is relatively uncommon. However, in different scenarios, related events such as TCP Window Update, TCP ZeroWindow, TCP ZeroWindowProbe, and TCP ZeroWindowProbeAck may also appear.

5.1 Window Full

It can be seen that the client at No. 277 declared a window size (Win) of 8712, while the server at No. 278 marked [TCP Window Full] because the in-flight bytes reached 8712.

Later in the communication process, the client’s window size dropped to 0, leading to the marking of [TCP ZeroWindow] at No. 281. As the receive window was released, an ACK with a window size of 4356 was sent at No. 282. When the server sent the next data segment at No. 283, [TCP Window Full] was once again marked, for the same reason: the in-flight bytes reached 4356.

In this case, the client does not support Window Scaling, as the option was not included in the TCP SYN.

5.2 Special Cases of Window Full

When the TCP communication rate is slow, and you suspect that one end’s receive window is full or problematic, but there’s no clear [TCP Window Full] indication, trust your judgment—it could very well be a TCP window full issue. The absence of a [TCP Window Full] marker might simply mean that the packet capture or TCP stream is incomplete, missing information from the TCP three-way handshake. Without this data, you can’t determine whether the stream supports Window Scaling or know its exact value. Without this info, it’s impossible to calculate the actual window size based on the Win field in the packet, so you can’t assess when a window full event occurs. For instance, if the only information available is a receive window of 250, without knowing that the Window Scale factor is 4, how would you calculate the Win size as 1000?

In such cases, what you observe is one side announcing a small Win value, but the other side sending in-flight data that exceeds this value. You can infer that the TCP three-way handshake is missing. It’s important to note that Wireshark cannot make this judgment because the packet capture is incomplete. However, in a real data stream where both sides support Window Scaling, the communication flow would proceed with both sides using their respective scaling factors to calculate and transmit data. This can be easily simulated by omitting the first three packets of the TCP handshake in the packetdrill example. In such a case, by No. 7, the [TCP Window Full] marker no longer appears, even though the peer at No. 5 advertised a Win of 1000. The Window size scaling factor is marked as -1 (unknown), and the [TCP Window Full] code (tcpd->rev->win_scale = -1) has no further basis for judgment, so the marker doesn’t reappear. Note the distinction from a Window size scaling factor of -2 (no window scaling used), which indicates that the packet capture is complete, including the TCP three-way handshake, but both sides opted not to use Window Scaling.

How do you verify this? If possible, reproduce the TCP connection and capture the TCP three-way handshake again. Whether the scaling factor is -2 (not supported) or some other value, knowing this won’t allow you to manually set the Window Scale value and trigger the [TCP Window Full] marker again.

5.3 First ACK and Window Full

This brings us to the earlier code segment involving tcpd->rev->is_first_ack. As shown below, if is_first_ack is true, the offset for the Window, i.e., the Window Scale, is set to 0 instead of using the Window Scale value from the TCP three-way handshake.

The is_first_ack flag is specifically set during the TCP three-way handshake, meaning it’s initialized as True for both SYN and SYN/ACK packets.

In the following case, No. 79 is marked as [TCP Window Full]. At first glance, this seems odd since the TCP three-way handshake clearly indicates that both sides support Window Scaling, and both have a large scaling factor of WS 128. Yet, after transmitting just 10 MSS 1448 segments between No. 70 and No. 79, the window full condition occurs.

No. 79 shows a BIF size of 14480, which equals the Win value advertised in the SYN/ACK (Win 14480), but Window Scaling was not applied. Instead, for the [TCP Window Full] evaluation, a scaling factor of 0 was used rather than WS 128.

This happens because, for the client at No. 79, tcpd->rev->is_first_ack corresponds to the is_first_ack value on the server side. Since the only packet in the rev direction is the No. 68 SYN/ACK, is_first_ack remains True. As a result, the Window offset (i.e., Window Scale) is set to 0, leading to the final determination of [TCP Window Full].

5.4 Continuing the Discussion on Special Cases of Window Full

Here’s another case: the server’s packet No. 5 is flagged as [TCP Window Full]. This occurs because the client’s packet No. 3 advertised a Win of 1000, which means the Win value of 250 was multiplied by a Window Scale of 4. As a result, the server could send two 500-byte data segments in packets No. 4 and No. 5, and No. 5 was marked with [TCP Window Full].

This means that when analyzing packet No. 5 on the server side, the Window Scale value in the reverse direction was correctly interpreted as 4, not 0, which indicates that the client’s is_first_ack value was False. This is achieved while analyzing the client’s ACK packet No. 3 through the following code:

6. Conclusion

In summary, understanding the “TCP Window Full” condition and its implications in TCP analysis is crucial for effective troubleshooting. By carefully interpreting window sizes and packet flows, Wireshark users can identify bottlenecks and optimize network performance.