TCP receiver should send window update upon receive buffer space becoming available
When TCP fills up the receivers' TCP receive buffer, the window closes. If the receiver's application subsequently empties the receive buffer by reading from the corresponding socket, no window update is sent to the sender, and thus it does not resume sending. Instead the TCP connection remains stalled apparently forever.
To reproduce, please see the attached two files; the first one is a patch to the PacketSink application, adding an attribute that allows delaying the first read from the socket. The second, simple_tcp.cc is a reduced test case involving the BulkSendApplication and a PacketSink application, with the first socket read delayed by 2 sec.
The simple_tcp test case is the following: A BulkSendApplication sends Bulk data to a PacketSink which accepts the TCP connection, but delays reading from the socket for 2 sec. After the 2 seconds mark, it reads greedily, just like the unmodified PacketSink. What should happen is that in the beginning, the buffer at the receiver end should fill up quickly, since it is not being drained. Once it's full, the Receive window is closed and thus BulkSendApplication should cease sending. Then, 2 sec into the simulation, the receiver starts reading, thus draining the receive buffer at which point the sender should resume sending.
However, the simulator behaves differently: It does fill up the receive buffer fine and also stops sending, but it does not resume sending once the receive buffer has been drained. Instead the TCP connection remains stalled.
The simple_tcp produces a line of output for every successful packet read, with a timestamp and payload size received. It currently produces a single line of output:
2 130784
This indicates, that at second 2, the entire TCP buffer was read out of the socket, and subsequently nothing more was received. I would expect the first read to yield the entire buffer, but subsequently it should receive further data. The wireshark trace produced by the simulation ends as follows:
368 0.163622 10.1.1.2 → 10.1.1.1 TCP 54 1000 → 49153 [ACK] Seq=1 Ack=130249 Win=824 Len=0 TSval=165 TSecr=119
369 0.164212 10.1.1.1 → 10.1.1.2 TCP 590 49153 → 1000 [ACK] Seq=130249 Ack=1 Win=131072 Len=536 TSval=120 TSecr=118
370 0.364212 10.1.1.2 → 10.1.1.1 TCP 54 1000 → 49153 [ACK] Seq=1 Ack=130785 Win=288 Len=0 TSval=366 TSecr=120
371 9.997942 10.1.1.2 → 10.1.1.1 TCP 54 1000 → 49153 [FIN, ACK] Seq=1 Ack=130785 Win=131072 Len=0 TSval=10000 TSecr=120
372 10.002050 10.1.1.1 → 10.1.1.2 TCP 54 49153 → 1000 [ACK] Seq=130785 Ack=2 Win=131072 Len=0 TSval=10002 TSecr=10000
This indicates that the last data packet was received at second 0.36; a window update should have been sent out at second 2 but does not appear in the trace. Therefore, the sender does not know that space has become available to send more data. (The last two entries in the PCAP are the closing of the connection at the end of the simulation, at time 10s.)