summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorBhasker Hariharan <bhaskerh@google.com>2020-09-28 23:29:36 -0700
committergVisor bot <gvisor-bot@google.com>2020-09-28 23:31:43 -0700
commit028e045da93b7c1c26417e80e4b4e388b86a713d (patch)
tree9a32ac8b14ec75745902a7e9188781085c248931
parentba44298a390c69dcf33ae591b9ddc6b3514cc9b3 (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.go7
-rw-r--r--pkg/tcpip/transport/tcp/tcp_test.go8
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 {