github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/tcpip/transport/tcp/tcp_rack_test.go (about)

     1  // Copyright 2020 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package tcp_test
    16  
    17  import (
    18  	"bytes"
    19  	"fmt"
    20  	"testing"
    21  	"time"
    22  
    23  	"github.com/SagerNet/gvisor/pkg/tcpip"
    24  	"github.com/SagerNet/gvisor/pkg/tcpip/header"
    25  	"github.com/SagerNet/gvisor/pkg/tcpip/seqnum"
    26  	"github.com/SagerNet/gvisor/pkg/tcpip/stack"
    27  	"github.com/SagerNet/gvisor/pkg/tcpip/transport/tcp/testing/context"
    28  	"github.com/SagerNet/gvisor/pkg/test/testutil"
    29  )
    30  
    31  const (
    32  	maxPayload       = 10
    33  	tsOptionSize     = 12
    34  	maxTCPOptionSize = 40
    35  	mtu              = header.TCPMinimumSize + header.IPv4MinimumSize + maxTCPOptionSize + maxPayload
    36  	latency          = 5 * time.Millisecond
    37  )
    38  
    39  func setStackRACKPermitted(t *testing.T, c *context.Context) {
    40  	t.Helper()
    41  	opt := tcpip.TCPRACKLossDetection
    42  	if err := c.Stack().SetTransportProtocolOption(header.TCPProtocolNumber, &opt); err != nil {
    43  		t.Fatalf("c.s.SetTransportProtocolOption(%d, &%v(%v)): %s", header.TCPProtocolNumber, opt, opt, err)
    44  	}
    45  }
    46  
    47  // TestRACKUpdate tests the RACK related fields are updated when an ACK is
    48  // received on a SACK enabled connection.
    49  func TestRACKUpdate(t *testing.T) {
    50  	c := context.New(t, uint32(mtu))
    51  	defer c.Cleanup()
    52  
    53  	var xmitTime tcpip.MonotonicTime
    54  	probeDone := make(chan struct{})
    55  	c.Stack().AddTCPProbe(func(state stack.TCPEndpointState) {
    56  		// Validate that the endpoint Sender.RACKState is what we expect.
    57  		if state.Sender.RACKState.XmitTime.Before(xmitTime) {
    58  			t.Fatalf("RACK transmit time failed to update when an ACK is received")
    59  		}
    60  
    61  		gotSeq := state.Sender.RACKState.EndSequence
    62  		wantSeq := state.Sender.SndNxt
    63  		if !gotSeq.LessThanEq(wantSeq) || gotSeq.LessThan(wantSeq) {
    64  			t.Fatalf("RACK sequence number failed to update, got: %v, but want: %v", gotSeq, wantSeq)
    65  		}
    66  
    67  		if state.Sender.RACKState.RTT == 0 {
    68  			t.Fatalf("RACK RTT failed to update when an ACK is received, got RACKState.RTT == 0 want != 0")
    69  		}
    70  		close(probeDone)
    71  	})
    72  	setStackSACKPermitted(t, c, true)
    73  	setStackRACKPermitted(t, c)
    74  	createConnectedWithSACKAndTS(c)
    75  
    76  	data := make([]byte, maxPayload)
    77  	for i := range data {
    78  		data[i] = byte(i)
    79  	}
    80  
    81  	// Write the data.
    82  	xmitTime = c.Stack().Clock().NowMonotonic()
    83  	var r bytes.Reader
    84  	r.Reset(data)
    85  	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
    86  		t.Fatalf("Write failed: %s", err)
    87  	}
    88  
    89  	bytesRead := 0
    90  	c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
    91  	bytesRead += maxPayload
    92  	c.SendAck(seqnum.Value(context.TestInitialSequenceNumber).Add(1), bytesRead)
    93  
    94  	// Wait for the probe function to finish processing the ACK before the
    95  	// test completes.
    96  	<-probeDone
    97  }
    98  
    99  // TestRACKDetectReorder tests that RACK detects packet reordering.
   100  func TestRACKDetectReorder(t *testing.T) {
   101  	c := context.New(t, uint32(mtu))
   102  	defer c.Cleanup()
   103  
   104  	t.Skipf("Skipping this test as reorder detection does not consider DSACK.")
   105  
   106  	var n int
   107  	const ackNumToVerify = 2
   108  	probeDone := make(chan struct{})
   109  	c.Stack().AddTCPProbe(func(state stack.TCPEndpointState) {
   110  		gotSeq := state.Sender.RACKState.FACK
   111  		wantSeq := state.Sender.SndNxt
   112  		// FACK should be updated to the highest ending sequence number of the
   113  		// segment acknowledged most recently.
   114  		if !gotSeq.LessThanEq(wantSeq) || gotSeq.LessThan(wantSeq) {
   115  			t.Fatalf("RACK FACK failed to update, got: %v, but want: %v", gotSeq, wantSeq)
   116  		}
   117  
   118  		n++
   119  		if n < ackNumToVerify {
   120  			if state.Sender.RACKState.Reord {
   121  				t.Fatalf("RACK reorder detected when there is no reordering")
   122  			}
   123  			return
   124  		}
   125  
   126  		if state.Sender.RACKState.Reord == false {
   127  			t.Fatalf("RACK reorder detection failed")
   128  		}
   129  		close(probeDone)
   130  	})
   131  	setStackSACKPermitted(t, c, true)
   132  	setStackRACKPermitted(t, c)
   133  	createConnectedWithSACKAndTS(c)
   134  	data := make([]byte, ackNumToVerify*maxPayload)
   135  	for i := range data {
   136  		data[i] = byte(i)
   137  	}
   138  
   139  	// Write the data.
   140  	var r bytes.Reader
   141  	r.Reset(data)
   142  	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
   143  		t.Fatalf("Write failed: %s", err)
   144  	}
   145  
   146  	bytesRead := 0
   147  	for i := 0; i < ackNumToVerify; i++ {
   148  		c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
   149  		bytesRead += maxPayload
   150  	}
   151  
   152  	start := c.IRS.Add(maxPayload + 1)
   153  	end := start.Add(maxPayload)
   154  	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
   155  	c.SendAckWithSACK(seq, 0, []header.SACKBlock{{start, end}})
   156  	c.SendAck(seq, bytesRead)
   157  
   158  	// Wait for the probe function to finish processing the ACK before the
   159  	// test completes.
   160  	<-probeDone
   161  }
   162  
   163  func sendAndReceiveWithSACK(t *testing.T, c *context.Context, numPackets int, enableRACK bool) []byte {
   164  	setStackSACKPermitted(t, c, true)
   165  	if enableRACK {
   166  		setStackRACKPermitted(t, c)
   167  	}
   168  	createConnectedWithSACKAndTS(c)
   169  
   170  	data := make([]byte, numPackets*maxPayload)
   171  	for i := range data {
   172  		data[i] = byte(i)
   173  	}
   174  
   175  	// Write the data.
   176  	var r bytes.Reader
   177  	r.Reset(data)
   178  	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
   179  		t.Fatalf("Write failed: %s", err)
   180  	}
   181  
   182  	bytesRead := 0
   183  	for i := 0; i < numPackets; i++ {
   184  		c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
   185  		bytesRead += maxPayload
   186  		// This delay is added to increase RTT as low RTT can cause TLP
   187  		// before sending ACK.
   188  		time.Sleep(latency)
   189  	}
   190  
   191  	return data
   192  }
   193  
   194  const (
   195  	validDSACKDetected   = 1
   196  	failedToDetectDSACK  = 2
   197  	invalidDSACKDetected = 3
   198  )
   199  
   200  func addDSACKSeenCheckerProbe(t *testing.T, c *context.Context, numACK int, probeDone chan int) {
   201  	var n int
   202  	c.Stack().AddTCPProbe(func(state stack.TCPEndpointState) {
   203  		// Validate that RACK detects DSACK.
   204  		n++
   205  		if n < numACK {
   206  			if state.Sender.RACKState.DSACKSeen {
   207  				probeDone <- invalidDSACKDetected
   208  			}
   209  			return
   210  		}
   211  
   212  		if !state.Sender.RACKState.DSACKSeen {
   213  			probeDone <- failedToDetectDSACK
   214  			return
   215  		}
   216  		probeDone <- validDSACKDetected
   217  	})
   218  }
   219  
   220  // TestRACKTLPRecovery tests that RACK sends a tail loss probe (TLP) in the
   221  // case of a tail loss. This simulates a situation where the TLP is able to
   222  // insinuate the SACK holes and sender is able to retransmit the rest.
   223  func TestRACKTLPRecovery(t *testing.T) {
   224  	c := context.New(t, uint32(mtu))
   225  	defer c.Cleanup()
   226  
   227  	// Send 8 packets.
   228  	numPackets := 8
   229  	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
   230  
   231  	// Packets [6-8] are lost. Send cumulative ACK for [1-5].
   232  	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
   233  	bytesRead := 5 * maxPayload
   234  	c.SendAck(seq, bytesRead)
   235  
   236  	// PTO should fire and send #8 packet as a TLP.
   237  	c.ReceiveAndCheckPacketWithOptions(data, 7*maxPayload, maxPayload, tsOptionSize)
   238  	var info tcpip.TCPInfoOption
   239  	if err := c.EP.GetSockOpt(&info); err != nil {
   240  		t.Fatalf("GetSockOpt failed: %v", err)
   241  	}
   242  
   243  	// Send the SACK after RTT because RACK RFC states that if the ACK for a
   244  	// retransmission arrives before the smoothed RTT then the sender should not
   245  	// update RACK state as it could be a spurious inference.
   246  	time.Sleep(info.RTT)
   247  
   248  	// Okay, let the sender know we got #8 using a SACK block.
   249  	eighthPStart := c.IRS.Add(1 + seqnum.Size(7*maxPayload))
   250  	eighthPEnd := eighthPStart.Add(maxPayload)
   251  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{eighthPStart, eighthPEnd}})
   252  
   253  	// The sender should be entering RACK based loss-recovery and sending #6 and
   254  	// #7 one after another.
   255  	c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
   256  	bytesRead += maxPayload
   257  	c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
   258  	bytesRead += 2 * maxPayload
   259  	c.SendAck(seq, bytesRead)
   260  
   261  	metricPollFn := func() error {
   262  		tcpStats := c.Stack().Stats().TCP
   263  		stats := []struct {
   264  			stat *tcpip.StatCounter
   265  			name string
   266  			want uint64
   267  		}{
   268  			// One fast retransmit after the SACK.
   269  			{tcpStats.FastRetransmit, "stats.TCP.FastRetransmit", 1},
   270  			// Recovery should be SACK recovery.
   271  			{tcpStats.SACKRecovery, "stats.TCP.SACKRecovery", 1},
   272  			// Packets 6, 7 and 8 were retransmitted.
   273  			{tcpStats.Retransmits, "stats.TCP.Retransmits", 3},
   274  			// TLP recovery should have been detected.
   275  			{tcpStats.TLPRecovery, "stats.TCP.TLPRecovery", 1},
   276  			// No RTOs should have occurred.
   277  			{tcpStats.Timeouts, "stats.TCP.Timeouts", 0},
   278  		}
   279  		for _, s := range stats {
   280  			if got, want := s.stat.Value(), s.want; got != want {
   281  				return fmt.Errorf("got %s.Value() = %d, want = %d", s.name, got, want)
   282  			}
   283  		}
   284  		return nil
   285  	}
   286  	if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
   287  		t.Error(err)
   288  	}
   289  }
   290  
   291  // TestRACKTLPFallbackRTO tests that RACK sends a tail loss probe (TLP) in the
   292  // case of a tail loss. This simulates a situation where either the TLP or its
   293  // ACK is lost. The sender should retransmit when RTO fires.
   294  func TestRACKTLPFallbackRTO(t *testing.T) {
   295  	c := context.New(t, uint32(mtu))
   296  	defer c.Cleanup()
   297  
   298  	// Send 8 packets.
   299  	numPackets := 8
   300  	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
   301  
   302  	// Packets [6-8] are lost. Send cumulative ACK for [1-5].
   303  	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
   304  	bytesRead := 5 * maxPayload
   305  	c.SendAck(seq, bytesRead)
   306  
   307  	// PTO should fire and send #8 packet as a TLP.
   308  	c.ReceiveAndCheckPacketWithOptions(data, 7*maxPayload, maxPayload, tsOptionSize)
   309  
   310  	// Either the TLP or the ACK the receiver sent with SACK blocks was lost.
   311  
   312  	// Confirm that RTO fires and retransmits packet #6.
   313  	c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
   314  
   315  	metricPollFn := func() error {
   316  		tcpStats := c.Stack().Stats().TCP
   317  		stats := []struct {
   318  			stat *tcpip.StatCounter
   319  			name string
   320  			want uint64
   321  		}{
   322  			// No fast retransmits happened.
   323  			{tcpStats.FastRetransmit, "stats.TCP.FastRetransmit", 0},
   324  			// No SACK recovery happened.
   325  			{tcpStats.SACKRecovery, "stats.TCP.SACKRecovery", 0},
   326  			// TLP was unsuccessful.
   327  			{tcpStats.TLPRecovery, "stats.TCP.TLPRecovery", 0},
   328  			// RTO should have fired.
   329  			{tcpStats.Timeouts, "stats.TCP.Timeouts", 1},
   330  		}
   331  		for _, s := range stats {
   332  			if got, want := s.stat.Value(), s.want; got != want {
   333  				return fmt.Errorf("got %s.Value() = %d, want = %d", s.name, got, want)
   334  			}
   335  		}
   336  		return nil
   337  	}
   338  	if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
   339  		t.Error(err)
   340  	}
   341  }
   342  
   343  // TestNoTLPRecoveryOnDSACK tests the scenario where the sender speculates a
   344  // tail loss and sends a TLP. Everything is received and acked. The probe
   345  // segment is DSACKed. No fast recovery should be triggered in this case.
   346  func TestNoTLPRecoveryOnDSACK(t *testing.T) {
   347  	c := context.New(t, uint32(mtu))
   348  	defer c.Cleanup()
   349  
   350  	// Send 8 packets.
   351  	numPackets := 8
   352  	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
   353  
   354  	// Packets [1-5] are received first. [6-8] took a detour and will take a
   355  	// while to arrive. Ack [1-5].
   356  	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
   357  	bytesRead := 5 * maxPayload
   358  	c.SendAck(seq, bytesRead)
   359  
   360  	// The tail loss probe (#8 packet) is received.
   361  	c.ReceiveAndCheckPacketWithOptions(data, 7*maxPayload, maxPayload, tsOptionSize)
   362  
   363  	// Now that all 8 packets are received + duplicate 8th packet, send ack.
   364  	bytesRead += 3 * maxPayload
   365  	eighthPStart := c.IRS.Add(1 + seqnum.Size(7*maxPayload))
   366  	eighthPEnd := eighthPStart.Add(maxPayload)
   367  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{eighthPStart, eighthPEnd}})
   368  
   369  	// Wait for RTO and make sure that nothing else is received.
   370  	var info tcpip.TCPInfoOption
   371  	if err := c.EP.GetSockOpt(&info); err != nil {
   372  		t.Fatalf("GetSockOpt failed: %v", err)
   373  	}
   374  	if p := c.GetPacketWithTimeout(info.RTO); p != nil {
   375  		t.Errorf("received an unexpected packet: %v", p)
   376  	}
   377  
   378  	metricPollFn := func() error {
   379  		tcpStats := c.Stack().Stats().TCP
   380  		stats := []struct {
   381  			stat *tcpip.StatCounter
   382  			name string
   383  			want uint64
   384  		}{
   385  			// Make sure no recovery was entered.
   386  			{tcpStats.FastRetransmit, "stats.TCP.FastRetransmit", 0},
   387  			{tcpStats.SACKRecovery, "stats.TCP.SACKRecovery", 0},
   388  			{tcpStats.TLPRecovery, "stats.TCP.TLPRecovery", 0},
   389  			// RTO should not have fired.
   390  			{tcpStats.Timeouts, "stats.TCP.Timeouts", 0},
   391  			// Only #8 was retransmitted.
   392  			{tcpStats.Retransmits, "stats.TCP.Retransmits", 1},
   393  		}
   394  		for _, s := range stats {
   395  			if got, want := s.stat.Value(), s.want; got != want {
   396  				return fmt.Errorf("got %s.Value() = %d, want = %d", s.name, got, want)
   397  			}
   398  		}
   399  		return nil
   400  	}
   401  	if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
   402  		t.Error(err)
   403  	}
   404  }
   405  
   406  // TestNoTLPOnSACK tests the scenario where there is not exactly a tail loss
   407  // due to the presence of multiple SACK holes. In such a scenario, TLP should
   408  // not be sent.
   409  func TestNoTLPOnSACK(t *testing.T) {
   410  	c := context.New(t, uint32(mtu))
   411  	defer c.Cleanup()
   412  
   413  	// Send 8 packets.
   414  	numPackets := 8
   415  	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
   416  
   417  	// Packets [1-5] and #7 were received. #6 and #8 were dropped.
   418  	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
   419  	bytesRead := 5 * maxPayload
   420  	seventhStart := c.IRS.Add(1 + seqnum.Size(6*maxPayload))
   421  	seventhEnd := seventhStart.Add(maxPayload)
   422  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{seventhStart, seventhEnd}})
   423  
   424  	// The sender should retransmit #6. If the sender sends a TLP, then #8 will
   425  	// received and fail this test.
   426  	c.ReceiveAndCheckPacketWithOptions(data, 5*maxPayload, maxPayload, tsOptionSize)
   427  
   428  	metricPollFn := func() error {
   429  		tcpStats := c.Stack().Stats().TCP
   430  		stats := []struct {
   431  			stat *tcpip.StatCounter
   432  			name string
   433  			want uint64
   434  		}{
   435  			// #6 was retransmitted due to SACK recovery.
   436  			{tcpStats.FastRetransmit, "stats.TCP.FastRetransmit", 1},
   437  			{tcpStats.SACKRecovery, "stats.TCP.SACKRecovery", 1},
   438  			{tcpStats.TLPRecovery, "stats.TCP.TLPRecovery", 0},
   439  			// RTO should not have fired.
   440  			{tcpStats.Timeouts, "stats.TCP.Timeouts", 0},
   441  			// Only #6 was retransmitted.
   442  			{tcpStats.Retransmits, "stats.TCP.Retransmits", 1},
   443  		}
   444  		for _, s := range stats {
   445  			if got, want := s.stat.Value(), s.want; got != want {
   446  				return fmt.Errorf("got %s.Value() = %d, want = %d", s.name, got, want)
   447  			}
   448  		}
   449  		return nil
   450  	}
   451  	if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
   452  		t.Error(err)
   453  	}
   454  }
   455  
   456  // TestRACKOnePacketTailLoss tests the trivial case of a tail loss of only one
   457  // packet. The probe should itself repairs the loss instead of having to go
   458  // into any recovery.
   459  func TestRACKOnePacketTailLoss(t *testing.T) {
   460  	c := context.New(t, uint32(mtu))
   461  	defer c.Cleanup()
   462  
   463  	// Send 3 packets.
   464  	numPackets := 3
   465  	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
   466  
   467  	// Packets [1-2] are received. #3 is lost.
   468  	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
   469  	bytesRead := 2 * maxPayload
   470  	c.SendAck(seq, bytesRead)
   471  
   472  	// PTO should fire and send #3 packet as a TLP.
   473  	c.ReceiveAndCheckPacketWithOptions(data, 2*maxPayload, maxPayload, tsOptionSize)
   474  	bytesRead += maxPayload
   475  	c.SendAck(seq, bytesRead)
   476  
   477  	metricPollFn := func() error {
   478  		tcpStats := c.Stack().Stats().TCP
   479  		stats := []struct {
   480  			stat *tcpip.StatCounter
   481  			name string
   482  			want uint64
   483  		}{
   484  			// #3 was retransmitted as TLP.
   485  			{tcpStats.FastRetransmit, "stats.TCP.FastRetransmit", 0},
   486  			{tcpStats.SACKRecovery, "stats.TCP.SACKRecovery", 1},
   487  			{tcpStats.TLPRecovery, "stats.TCP.TLPRecovery", 0},
   488  			// RTO should not have fired.
   489  			{tcpStats.Timeouts, "stats.TCP.Timeouts", 0},
   490  			// Only #3 was retransmitted.
   491  			{tcpStats.Retransmits, "stats.TCP.Retransmits", 1},
   492  		}
   493  		for _, s := range stats {
   494  			if got, want := s.stat.Value(), s.want; got != want {
   495  				return fmt.Errorf("got %s.Value() = %d, want = %d", s.name, got, want)
   496  			}
   497  		}
   498  		return nil
   499  	}
   500  	if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
   501  		t.Error(err)
   502  	}
   503  }
   504  
   505  // TestRACKDetectDSACK tests that RACK detects DSACK with duplicate segments.
   506  // See: https://tools.ietf.org/html/rfc2883#section-4.1.1.
   507  func TestRACKDetectDSACK(t *testing.T) {
   508  	c := context.New(t, uint32(mtu))
   509  	defer c.Cleanup()
   510  
   511  	probeDone := make(chan int)
   512  	const ackNumToVerify = 2
   513  	addDSACKSeenCheckerProbe(t, c, ackNumToVerify, probeDone)
   514  
   515  	numPackets := 8
   516  	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
   517  
   518  	// Cumulative ACK for [1-5] packets and SACK #8 packet (to prevent TLP).
   519  	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
   520  	bytesRead := 5 * maxPayload
   521  	eighthPStart := c.IRS.Add(1 + seqnum.Size(7*maxPayload))
   522  	eighthPEnd := eighthPStart.Add(maxPayload)
   523  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{eighthPStart, eighthPEnd}})
   524  
   525  	// Expect retransmission of #6 packet after RTO expires.
   526  	c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
   527  
   528  	// Send DSACK block for #6 packet indicating both
   529  	// initial and retransmitted packet are received and
   530  	// packets [1-8] are received.
   531  	start := c.IRS.Add(1 + seqnum.Size(bytesRead))
   532  	end := start.Add(maxPayload)
   533  	bytesRead += 3 * maxPayload
   534  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}})
   535  
   536  	// Wait for the probe function to finish processing the
   537  	// ACK before the test completes.
   538  	err := <-probeDone
   539  	switch err {
   540  	case failedToDetectDSACK:
   541  		t.Fatalf("RACK DSACK detection failed")
   542  	case invalidDSACKDetected:
   543  		t.Fatalf("RACK DSACK detected when there is no duplicate SACK")
   544  	}
   545  }
   546  
   547  // TestRACKDetectDSACKWithOutOfOrder tests that RACK detects DSACK with out of
   548  // order segments.
   549  // See: https://tools.ietf.org/html/rfc2883#section-4.1.2.
   550  func TestRACKDetectDSACKWithOutOfOrder(t *testing.T) {
   551  	c := context.New(t, uint32(mtu))
   552  	defer c.Cleanup()
   553  
   554  	probeDone := make(chan int)
   555  	const ackNumToVerify = 2
   556  	addDSACKSeenCheckerProbe(t, c, ackNumToVerify, probeDone)
   557  
   558  	numPackets := 10
   559  	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
   560  
   561  	// Cumulative ACK for [1-5] packets and SACK for #7 packet (to prevent TLP).
   562  	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
   563  	bytesRead := 5 * maxPayload
   564  	seventhPStart := c.IRS.Add(1 + seqnum.Size(6*maxPayload))
   565  	seventhPEnd := seventhPStart.Add(maxPayload)
   566  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{seventhPStart, seventhPEnd}})
   567  
   568  	// Expect retransmission of #6 packet.
   569  	c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
   570  
   571  	// Send DSACK block for #6 packet indicating both
   572  	// initial and retransmitted packet are received and
   573  	// packets [1-7] are received.
   574  	start := c.IRS.Add(1 + seqnum.Size(bytesRead))
   575  	end := start.Add(maxPayload)
   576  	bytesRead += 2 * maxPayload
   577  	// Send DSACK block for #6 along with SACK for out of
   578  	// order #9 packet.
   579  	start1 := c.IRS.Add(1 + seqnum.Size(bytesRead) + maxPayload)
   580  	end1 := start1.Add(maxPayload)
   581  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}, {start1, end1}})
   582  
   583  	// Wait for the probe function to finish processing the
   584  	// ACK before the test completes.
   585  	err := <-probeDone
   586  	switch err {
   587  	case failedToDetectDSACK:
   588  		t.Fatalf("RACK DSACK detection failed")
   589  	case invalidDSACKDetected:
   590  		t.Fatalf("RACK DSACK detected when there is no duplicate SACK")
   591  	}
   592  }
   593  
   594  // TestRACKDetectDSACKWithOutOfOrderDup tests that DSACK is detected on a
   595  // duplicate of out of order packet.
   596  // See: https://tools.ietf.org/html/rfc2883#section-4.1.3
   597  func TestRACKDetectDSACKWithOutOfOrderDup(t *testing.T) {
   598  	c := context.New(t, uint32(mtu))
   599  	defer c.Cleanup()
   600  
   601  	probeDone := make(chan int)
   602  	const ackNumToVerify = 4
   603  	addDSACKSeenCheckerProbe(t, c, ackNumToVerify, probeDone)
   604  
   605  	numPackets := 10
   606  	sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
   607  
   608  	// ACK [1-5] packets.
   609  	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
   610  	bytesRead := 5 * maxPayload
   611  	c.SendAck(seq, bytesRead)
   612  
   613  	// Send SACK indicating #6 packet is missing and received #7 packet.
   614  	offset := seqnum.Size(bytesRead + maxPayload)
   615  	start := c.IRS.Add(1 + offset)
   616  	end := start.Add(maxPayload)
   617  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}})
   618  
   619  	// Send SACK with #6 packet is missing and received [7-8] packets.
   620  	end = start.Add(2 * maxPayload)
   621  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}})
   622  
   623  	// Consider #8 packet is duplicated on the network and send DSACK.
   624  	dsackStart := c.IRS.Add(1 + offset + maxPayload)
   625  	dsackEnd := dsackStart.Add(maxPayload)
   626  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{dsackStart, dsackEnd}, {start, end}})
   627  
   628  	// Wait for the probe function to finish processing the ACK before the
   629  	// test completes.
   630  	err := <-probeDone
   631  	switch err {
   632  	case failedToDetectDSACK:
   633  		t.Fatalf("RACK DSACK detection failed")
   634  	case invalidDSACKDetected:
   635  		t.Fatalf("RACK DSACK detected when there is no duplicate SACK")
   636  	}
   637  }
   638  
   639  // TestRACKDetectDSACKSingleDup tests DSACK for a single duplicate subsegment.
   640  // See: https://tools.ietf.org/html/rfc2883#section-4.2.1.
   641  func TestRACKDetectDSACKSingleDup(t *testing.T) {
   642  	c := context.New(t, uint32(mtu))
   643  	defer c.Cleanup()
   644  
   645  	probeDone := make(chan int)
   646  	const ackNumToVerify = 4
   647  	addDSACKSeenCheckerProbe(t, c, ackNumToVerify, probeDone)
   648  
   649  	numPackets := 4
   650  	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
   651  
   652  	// Send ACK for #1 packet.
   653  	bytesRead := maxPayload
   654  	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
   655  	c.SendAck(seq, bytesRead)
   656  
   657  	// Missing [2-3] packets and received #4 packet.
   658  	seq = seqnum.Value(context.TestInitialSequenceNumber).Add(1)
   659  	start := c.IRS.Add(1 + seqnum.Size(3*maxPayload))
   660  	end := start.Add(seqnum.Size(maxPayload))
   661  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}})
   662  
   663  	// Expect retransmission of #2 packet.
   664  	c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
   665  
   666  	// ACK for retransmitted #2 packet.
   667  	bytesRead += maxPayload
   668  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}})
   669  
   670  	// Simulate receving delayed subsegment of #2 packet and delayed #3 packet by
   671  	// sending DSACK block for the subsegment.
   672  	dsackStart := c.IRS.Add(1 + seqnum.Size(bytesRead))
   673  	dsackEnd := dsackStart.Add(seqnum.Size(maxPayload / 2))
   674  	c.SendAckWithSACK(seq, numPackets*maxPayload, []header.SACKBlock{{dsackStart, dsackEnd}})
   675  
   676  	// Wait for the probe function to finish processing the ACK before the
   677  	// test completes.
   678  	err := <-probeDone
   679  	switch err {
   680  	case failedToDetectDSACK:
   681  		t.Fatalf("RACK DSACK detection failed")
   682  	case invalidDSACKDetected:
   683  		t.Fatalf("RACK DSACK detected when there is no duplicate SACK")
   684  	}
   685  }
   686  
   687  // TestRACKDetectDSACKDupWithCumulativeACK tests DSACK for two non-contiguous
   688  // duplicate subsegments covered by the cumulative acknowledgement.
   689  // See: https://tools.ietf.org/html/rfc2883#section-4.2.2.
   690  func TestRACKDetectDSACKDupWithCumulativeACK(t *testing.T) {
   691  	c := context.New(t, uint32(mtu))
   692  	defer c.Cleanup()
   693  
   694  	probeDone := make(chan int)
   695  	const ackNumToVerify = 5
   696  	addDSACKSeenCheckerProbe(t, c, ackNumToVerify, probeDone)
   697  
   698  	numPackets := 6
   699  	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
   700  
   701  	// Send ACK for #1 packet.
   702  	bytesRead := maxPayload
   703  	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
   704  	c.SendAck(seq, bytesRead)
   705  
   706  	// Missing [2-5] packets and received #6 packet.
   707  	seq = seqnum.Value(context.TestInitialSequenceNumber).Add(1)
   708  	start := c.IRS.Add(1 + seqnum.Size(5*maxPayload))
   709  	end := start.Add(seqnum.Size(maxPayload))
   710  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}})
   711  
   712  	// Expect retransmission of #2 packet.
   713  	c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
   714  
   715  	// Received delayed #2 packet.
   716  	bytesRead += maxPayload
   717  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}})
   718  
   719  	// Received delayed #4 packet.
   720  	start1 := c.IRS.Add(1 + seqnum.Size(3*maxPayload))
   721  	end1 := start1.Add(seqnum.Size(maxPayload))
   722  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start1, end1}, {start, end}})
   723  
   724  	// Simulate receiving retransmitted subsegment for #2 packet and delayed #3
   725  	// packet by sending DSACK block for #2 packet.
   726  	dsackStart := c.IRS.Add(1 + seqnum.Size(maxPayload))
   727  	dsackEnd := dsackStart.Add(seqnum.Size(maxPayload / 2))
   728  	c.SendAckWithSACK(seq, 4*maxPayload, []header.SACKBlock{{dsackStart, dsackEnd}, {start, end}})
   729  
   730  	// Wait for the probe function to finish processing the ACK before the
   731  	// test completes.
   732  	err := <-probeDone
   733  	switch err {
   734  	case failedToDetectDSACK:
   735  		t.Fatalf("RACK DSACK detection failed")
   736  	case invalidDSACKDetected:
   737  		t.Fatalf("RACK DSACK detected when there is no duplicate SACK")
   738  	}
   739  }
   740  
   741  // TestRACKDetectDSACKDup tests two non-contiguous duplicate subsegments not
   742  // covered by the cumulative acknowledgement.
   743  // See: https://tools.ietf.org/html/rfc2883#section-4.2.3.
   744  func TestRACKDetectDSACKDup(t *testing.T) {
   745  	c := context.New(t, uint32(mtu))
   746  	defer c.Cleanup()
   747  
   748  	probeDone := make(chan int)
   749  	const ackNumToVerify = 5
   750  	addDSACKSeenCheckerProbe(t, c, ackNumToVerify, probeDone)
   751  
   752  	numPackets := 7
   753  	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
   754  
   755  	// Send ACK for #1 packet.
   756  	bytesRead := maxPayload
   757  	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
   758  	c.SendAck(seq, bytesRead)
   759  
   760  	// Missing [2-6] packets and SACK #7 packet.
   761  	seq = seqnum.Value(context.TestInitialSequenceNumber).Add(1)
   762  	start := c.IRS.Add(1 + seqnum.Size(6*maxPayload))
   763  	end := start.Add(seqnum.Size(maxPayload))
   764  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}})
   765  
   766  	// Received delayed #3 packet.
   767  	start1 := c.IRS.Add(1 + seqnum.Size(2*maxPayload))
   768  	end1 := start1.Add(seqnum.Size(maxPayload))
   769  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start1, end1}, {start, end}})
   770  
   771  	// Expect retransmission of #2 packet.
   772  	c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
   773  
   774  	// Consider #2 packet has been dropped and SACK #4 packet.
   775  	start2 := c.IRS.Add(1 + seqnum.Size(3*maxPayload))
   776  	end2 := start2.Add(seqnum.Size(maxPayload))
   777  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start2, end2}, {start1, end1}, {start, end}})
   778  
   779  	// Simulate receiving retransmitted subsegment for #3 packet and delayed #5
   780  	// packet by sending DSACK block for the subsegment.
   781  	dsackStart := c.IRS.Add(1 + seqnum.Size(2*maxPayload))
   782  	dsackEnd := dsackStart.Add(seqnum.Size(maxPayload / 2))
   783  	end1 = end1.Add(seqnum.Size(2 * maxPayload))
   784  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{dsackStart, dsackEnd}, {start1, end1}})
   785  
   786  	// Wait for the probe function to finish processing the ACK before the
   787  	// test completes.
   788  	err := <-probeDone
   789  	switch err {
   790  	case failedToDetectDSACK:
   791  		t.Fatalf("RACK DSACK detection failed")
   792  	case invalidDSACKDetected:
   793  		t.Fatalf("RACK DSACK detected when there is no duplicate SACK")
   794  	}
   795  }
   796  
   797  // TestRACKWithInvalidDSACKBlock tests that DSACK is not detected when DSACK
   798  // is not the first SACK block.
   799  func TestRACKWithInvalidDSACKBlock(t *testing.T) {
   800  	c := context.New(t, uint32(mtu))
   801  	defer c.Cleanup()
   802  
   803  	probeDone := make(chan struct{})
   804  	const ackNumToVerify = 2
   805  	var n int
   806  	c.Stack().AddTCPProbe(func(state stack.TCPEndpointState) {
   807  		// Validate that RACK does not detect DSACK when DSACK block is
   808  		// not the first SACK block.
   809  		n++
   810  		t.Helper()
   811  		if state.Sender.RACKState.DSACKSeen {
   812  			t.Fatalf("RACK DSACK detected when there is no duplicate SACK")
   813  		}
   814  
   815  		if n == ackNumToVerify {
   816  			close(probeDone)
   817  		}
   818  	})
   819  
   820  	numPackets := 10
   821  	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
   822  
   823  	// Cumulative ACK for [1-5] packets and SACK for #7 packet (to prevent TLP).
   824  	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
   825  	bytesRead := 5 * maxPayload
   826  	seventhPStart := c.IRS.Add(1 + seqnum.Size(6*maxPayload))
   827  	seventhPEnd := seventhPStart.Add(maxPayload)
   828  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{seventhPStart, seventhPEnd}})
   829  
   830  	// Expect retransmission of #6 packet.
   831  	c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
   832  
   833  	// Send DSACK block for #6 packet indicating both
   834  	// initial and retransmitted packet are received and
   835  	// packets [1-7] are received.
   836  	start := c.IRS.Add(1 + seqnum.Size(bytesRead))
   837  	end := start.Add(maxPayload)
   838  	bytesRead += 2 * maxPayload
   839  
   840  	// Send DSACK block as second block. The first block is a SACK for #9 packet.
   841  	start1 := c.IRS.Add(1 + seqnum.Size(bytesRead) + maxPayload)
   842  	end1 := start1.Add(maxPayload)
   843  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start1, end1}, {start, end}})
   844  
   845  	// Wait for the probe function to finish processing the
   846  	// ACK before the test completes.
   847  	<-probeDone
   848  }
   849  
   850  func addReorderWindowCheckerProbe(c *context.Context, numACK int, probeDone chan error) {
   851  	var n int
   852  	c.Stack().AddTCPProbe(func(state stack.TCPEndpointState) {
   853  		// Validate that RACK detects DSACK.
   854  		n++
   855  		if n < numACK {
   856  			return
   857  		}
   858  
   859  		if state.Sender.RACKState.ReoWnd == 0 || state.Sender.RACKState.ReoWnd > state.Sender.RTTState.SRTT {
   860  			probeDone <- fmt.Errorf("got RACKState.ReoWnd: %d, expected it to be greater than 0 and less than %d", state.Sender.RACKState.ReoWnd, state.Sender.RTTState.SRTT)
   861  			return
   862  		}
   863  
   864  		if state.Sender.RACKState.ReoWndIncr != 1 {
   865  			probeDone <- fmt.Errorf("got RACKState.ReoWndIncr: %v, want: 1", state.Sender.RACKState.ReoWndIncr)
   866  			return
   867  		}
   868  
   869  		if state.Sender.RACKState.ReoWndPersist > 0 {
   870  			probeDone <- fmt.Errorf("got RACKState.ReoWndPersist: %v, want: greater than 0", state.Sender.RACKState.ReoWndPersist)
   871  			return
   872  		}
   873  		probeDone <- nil
   874  	})
   875  }
   876  
   877  func TestRACKCheckReorderWindow(t *testing.T) {
   878  	c := context.New(t, uint32(mtu))
   879  	defer c.Cleanup()
   880  
   881  	probeDone := make(chan error)
   882  	const ackNumToVerify = 3
   883  	addReorderWindowCheckerProbe(c, ackNumToVerify, probeDone)
   884  
   885  	const numPackets = 7
   886  	sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
   887  
   888  	// Send ACK for #1 packet.
   889  	bytesRead := maxPayload
   890  	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
   891  	c.SendAck(seq, bytesRead)
   892  
   893  	// Missing [2-6] packets and SACK #7 packet.
   894  	start := c.IRS.Add(1 + seqnum.Size(6*maxPayload))
   895  	end := start.Add(seqnum.Size(maxPayload))
   896  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}})
   897  
   898  	// Received delayed packets [2-6] which indicates there is reordering
   899  	// in the connection.
   900  	bytesRead += 6 * maxPayload
   901  	c.SendAck(seq, bytesRead)
   902  
   903  	// Wait for the probe function to finish processing the ACK before the
   904  	// test completes.
   905  	if err := <-probeDone; err != nil {
   906  		t.Fatalf("unexpected values for RACK variables: %v", err)
   907  	}
   908  }
   909  
   910  func TestRACKWithDuplicateACK(t *testing.T) {
   911  	c := context.New(t, uint32(mtu))
   912  	defer c.Cleanup()
   913  
   914  	const numPackets = 4
   915  	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
   916  
   917  	// Send three duplicate ACKs to trigger fast recovery. The first
   918  	// segment is considered as lost and will be retransmitted after
   919  	// receiving the duplicate ACKs.
   920  	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
   921  	start := c.IRS.Add(1 + seqnum.Size(maxPayload))
   922  	end := start.Add(seqnum.Size(maxPayload))
   923  	for i := 0; i < 3; i++ {
   924  		c.SendAckWithSACK(seq, 0, []header.SACKBlock{{start, end}})
   925  		end = end.Add(seqnum.Size(maxPayload))
   926  	}
   927  
   928  	// Receive the retransmitted packet.
   929  	c.ReceiveAndCheckPacketWithOptions(data, 0, maxPayload, tsOptionSize)
   930  
   931  	metricPollFn := func() error {
   932  		tcpStats := c.Stack().Stats().TCP
   933  		stats := []struct {
   934  			stat *tcpip.StatCounter
   935  			name string
   936  			want uint64
   937  		}{
   938  			{tcpStats.FastRetransmit, "stats.TCP.FastRetransmit", 1},
   939  			{tcpStats.SACKRecovery, "stats.TCP.SACKRecovery", 1},
   940  			{tcpStats.FastRecovery, "stats.TCP.FastRecovery", 0},
   941  		}
   942  		for _, s := range stats {
   943  			if got, want := s.stat.Value(), s.want; got != want {
   944  				return fmt.Errorf("got %s.Value() = %d, want = %d", s.name, got, want)
   945  			}
   946  		}
   947  		return nil
   948  	}
   949  
   950  	if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
   951  		t.Error(err)
   952  	}
   953  }
   954  
   955  // TestRACKUpdateSackedOut tests the sacked out field is updated when a SACK
   956  // is received.
   957  func TestRACKUpdateSackedOut(t *testing.T) {
   958  	c := context.New(t, uint32(mtu))
   959  	defer c.Cleanup()
   960  
   961  	probeDone := make(chan struct{})
   962  	ackNum := 0
   963  	c.Stack().AddTCPProbe(func(state stack.TCPEndpointState) {
   964  		// Validate that the endpoint Sender.SackedOut is what we expect.
   965  		if state.Sender.SackedOut != 2 && ackNum == 0 {
   966  			t.Fatalf("SackedOut got updated to wrong value got: %v want: 2", state.Sender.SackedOut)
   967  		}
   968  
   969  		if state.Sender.SackedOut != 0 && ackNum == 1 {
   970  			t.Fatalf("SackedOut got updated to wrong value got: %v want: 0", state.Sender.SackedOut)
   971  		}
   972  		if ackNum > 0 {
   973  			close(probeDone)
   974  		}
   975  		ackNum++
   976  	})
   977  
   978  	sendAndReceiveWithSACK(t, c, 8, true /* enableRACK */)
   979  
   980  	// ACK for [3-5] packets.
   981  	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
   982  	start := c.IRS.Add(seqnum.Size(1 + 3*maxPayload))
   983  	bytesRead := 2 * maxPayload
   984  	end := start.Add(seqnum.Size(bytesRead))
   985  	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}})
   986  
   987  	bytesRead += 3 * maxPayload
   988  	c.SendAck(seq, bytesRead)
   989  
   990  	// Wait for the probe function to finish processing the ACK before the
   991  	// test completes.
   992  	<-probeDone
   993  }
   994  
   995  // TestRACKWithWindowFull tests that RACK honors the receive window size.
   996  func TestRACKWithWindowFull(t *testing.T) {
   997  	c := context.New(t, uint32(mtu))
   998  	defer c.Cleanup()
   999  
  1000  	setStackSACKPermitted(t, c, true)
  1001  	setStackRACKPermitted(t, c)
  1002  	createConnectedWithSACKAndTS(c)
  1003  
  1004  	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
  1005  	const numPkts = 10
  1006  	data := make([]byte, numPkts*maxPayload)
  1007  	for i := range data {
  1008  		data[i] = byte(i)
  1009  	}
  1010  
  1011  	// Write the data.
  1012  	var r bytes.Reader
  1013  	r.Reset(data)
  1014  	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
  1015  		t.Fatalf("Write failed: %s", err)
  1016  	}
  1017  
  1018  	bytesRead := 0
  1019  	for i := 0; i < numPkts; i++ {
  1020  		c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
  1021  		bytesRead += maxPayload
  1022  		if i == 0 {
  1023  			// Send ACK for the first packet to establish RTT.
  1024  			c.SendAck(seq, maxPayload)
  1025  		}
  1026  	}
  1027  
  1028  	// SACK for #10 packet.
  1029  	start := c.IRS.Add(seqnum.Size(1 + (numPkts-1)*maxPayload))
  1030  	end := start.Add(seqnum.Size(maxPayload))
  1031  	c.SendAckWithSACK(seq, 2*maxPayload, []header.SACKBlock{{start, end}})
  1032  
  1033  	var info tcpip.TCPInfoOption
  1034  	if err := c.EP.GetSockOpt(&info); err != nil {
  1035  		t.Fatalf("GetSockOpt failed: %v", err)
  1036  	}
  1037  	// Wait for RTT to trigger recovery.
  1038  	time.Sleep(info.RTT)
  1039  
  1040  	// Expect retransmission of #2 packet.
  1041  	c.ReceiveAndCheckPacketWithOptions(data, 2*maxPayload, maxPayload, tsOptionSize)
  1042  
  1043  	// Send ACK for #2 packet.
  1044  	c.SendAck(seq, 3*maxPayload)
  1045  
  1046  	// Expect retransmission of #3 packet.
  1047  	c.ReceiveAndCheckPacketWithOptions(data, 3*maxPayload, maxPayload, tsOptionSize)
  1048  
  1049  	// Send ACK with zero window size.
  1050  	c.SendPacket(nil, &context.Headers{
  1051  		SrcPort: context.TestPort,
  1052  		DstPort: c.Port,
  1053  		Flags:   header.TCPFlagAck,
  1054  		SeqNum:  seq,
  1055  		AckNum:  c.IRS.Add(1 + 4*maxPayload),
  1056  		RcvWnd:  0,
  1057  	})
  1058  
  1059  	// No packet should be received as the receive window size is zero.
  1060  	c.CheckNoPacket("unexpected packet received after userTimeout has expired")
  1061  }