diff options
author | Bhasker Hariharan <bhaskerh@google.com> | 2020-09-28 23:29:36 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-09-28 23:31:43 -0700 |
commit | 028e045da93b7c1c26417e80e4b4e388b86a713d (patch) | |
tree | 9a32ac8b14ec75745902a7e9188781085c248931 | |
parent | ba44298a390c69dcf33ae591b9ddc6b3514cc9b3 (diff) |
Fix 1 zero window advertisement bug and a TCP test flake.
In TestReceiveBufferAutoTuning we now send a keep-alive packet to measure the
current window rather than a 1 byte segment as the returned window value in the
latter case is reduced due to the 1 byte segment now being held in the receive
buffer and can cause the test to flake if the segment overheads were to change.
In getSendParams in rcv.go we were advertising a non-zero window even if
available window space was zero after we received the previous segment. In such
a case newWnd and curWnd will be the same and we end up advertising a tiny but
non-zero window and this can cause the next segment to be dropped.
PiperOrigin-RevId: 334314070
-rw-r--r-- | pkg/tcpip/transport/tcp/rcv.go | 7 | ||||
-rw-r--r-- | pkg/tcpip/transport/tcp/tcp_test.go | 8 |
2 files changed, 12 insertions, 3 deletions
diff --git a/pkg/tcpip/transport/tcp/rcv.go b/pkg/tcpip/transport/tcp/rcv.go index 4aafb4d22..48bf196d8 100644 --- a/pkg/tcpip/transport/tcp/rcv.go +++ b/pkg/tcpip/transport/tcp/rcv.go @@ -88,6 +88,13 @@ func (r *receiver) acceptable(segSeq seqnum.Value, segLen seqnum.Size) bool { // segments to send. func (r *receiver) getSendParams() (rcvNxt seqnum.Value, rcvWnd seqnum.Size) { avail := wndFromSpace(r.ep.receiveBufferAvailable()) + if avail == 0 { + // We have no space available to accept any data, move to zero window + // state. + r.rcvWnd = 0 + return r.rcvNxt, 0 + } + acc := r.rcvNxt.Add(seqnum.Size(avail)) newWnd := r.rcvNxt.Size(acc) curWnd := r.rcvNxt.Size(r.rcvAcc) diff --git a/pkg/tcpip/transport/tcp/tcp_test.go b/pkg/tcpip/transport/tcp/tcp_test.go index dd810f594..5b504d0d1 100644 --- a/pkg/tcpip/transport/tcp/tcp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_test.go @@ -5435,8 +5435,8 @@ func TestListenNoAcceptNonUnicastV4(t *testing.T) { // TestListenNoAcceptMulticastBroadcastV6 makes sure that TCP segments with a // non unicast IPv6 address are not accepted. func TestListenNoAcceptNonUnicastV6(t *testing.T) { - multicastAddr := tcpip.Address("\xff\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01") - otherMulticastAddr := tcpip.Address("\xff\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02") + multicastAddr := tcpip.Address("\xff\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01") + otherMulticastAddr := tcpip.Address("\xff\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02") tests := []struct { name string @@ -6182,7 +6182,9 @@ func TestReceiveBufferAutoTuning(t *testing.T) { rawEP := c.CreateConnectedWithOptions(header.TCPSynOptions{TS: true, WS: 4}) tsVal := uint32(rawEP.TSVal) - rawEP.SendPacketWithTS([]byte{1}, tsVal) + rawEP.NextSeqNum-- + rawEP.SendPacketWithTS(nil, tsVal) + rawEP.NextSeqNum++ pkt := rawEP.VerifyAndReturnACKWithTS(tsVal) curRcvWnd := int(header.TCP(header.IPv4(pkt).Payload()).WindowSize()) << c.WindowScale scaleRcvWnd := func(rcvWnd int) uint16 { |