Thu 22 Oct 2009 09:19:50 PM UTC, original submission:
Kieran Mansley wrote:
> There were two changes in 1.3.1 [in the area of receive window management]:
> - only send an explicit window update if the change is greater than TCP_WND_UPDATE_THRESHOLD.
> - only change the window advertised (including in normal ACKs) if the change is greater than 1 MSS.
> This is silly window avoidance, and designed to prevent the sender getting small amounts of window
> and then sending small packets.
The description of silly window avoidance in RFC1122 (section 4.2.3.3) says that there is supposed to be a second test.
The threshold to advertise an increase in window size should be the lesser of MSS and WND/2 (assuming the recommended fraction of 1/2). This would allow the use of window sizes smaller than MSS*2. The absolute minimum (but horribly inefficient) value of WND would be 2.
Assuming WND is set equal to MSS:
1. If the application is reading data slowly a few bytes at a time with a sender able to supply data continuously, then the typical pattern should be to get an initial transmit burst of the full window size, followed by half-full segements (WND/2 = MSS/2) once the receiver has processed half the initial data.
2. If the sender is delivering small packets at a moderate pace and the receiver is able to keep up, the expected pattern should be to see the window size decreasing in each ACK until just after half the window is gone, then it should advertise an almost full window again.
It seems reasonable for LWIP to recommend that users set WND to at least MSS*2, but unless LWIP enforces this minimum, the silly window avoidance code should allow for small windows by checking WND/2 as well as MSS.
As it stands, the code has a degenerate case when WND = MSS, which in (2) results in the window closing all the way to zero before opening up to full again. It isn't quite as bad for MSS < WND < MSS*2, but still results in the window getting smaller than TCP says it should.
|