summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/tcpip')
-rw-r--r--pkg/tcpip/link/fdbased/endpoint.go1
-rw-r--r--pkg/tcpip/link/fdbased/endpoint_test.go1
-rw-r--r--pkg/tcpip/link/fdbased/endpoint_unsafe.go1
-rw-r--r--pkg/tcpip/link/fdbased/mmap.go1
-rw-r--r--pkg/tcpip/link/fdbased/mmap_stub.go1
-rw-r--r--pkg/tcpip/link/fdbased/mmap_unsafe.go1
-rw-r--r--pkg/tcpip/link/fdbased/packet_dispatchers.go1
-rw-r--r--pkg/tcpip/link/rawfile/blockingpoll_noyield_unsafe.go1
-rw-r--r--pkg/tcpip/link/rawfile/blockingpoll_yield_unsafe.go1
-rw-r--r--pkg/tcpip/link/rawfile/errors.go1
-rw-r--r--pkg/tcpip/link/rawfile/errors_test.go1
-rw-r--r--pkg/tcpip/link/rawfile/rawfile_unsafe.go1
-rw-r--r--pkg/tcpip/link/sharedmem/rx.go1
-rw-r--r--pkg/tcpip/link/sharedmem/sharedmem.go1
-rw-r--r--pkg/tcpip/link/sharedmem/sharedmem_test.go1
-rw-r--r--pkg/tcpip/link/tun/tun_unsafe.go1
-rw-r--r--pkg/tcpip/sample/tun_tcp_connect/main.go1
-rw-r--r--pkg/tcpip/sample/tun_tcp_echo/main.go1
-rw-r--r--pkg/tcpip/socketops.go2
-rw-r--r--pkg/tcpip/tcpip.go4
-rw-r--r--pkg/tcpip/transport/raw/endpoint.go17
-rw-r--r--pkg/tcpip/transport/tcp/endpoint.go8
-rw-r--r--pkg/tcpip/transport/tcp/protocol.go3
-rw-r--r--pkg/tcpip/transport/tcp/snd.go7
-rw-r--r--pkg/tcpip/transport/tcp/tcp_noracedetector_test.go1
-rw-r--r--pkg/tcpip/transport/tcp/tcp_rack_test.go55
-rw-r--r--pkg/tcpip/transport/tcp/tcp_sack_test.go5
27 files changed, 103 insertions, 17 deletions
diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go
index 1b56d2b72..e8e716db0 100644
--- a/pkg/tcpip/link/fdbased/endpoint.go
+++ b/pkg/tcpip/link/fdbased/endpoint.go
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//go:build linux
// +build linux
// Package fdbased provides the implemention of data-link layer endpoints
diff --git a/pkg/tcpip/link/fdbased/endpoint_test.go b/pkg/tcpip/link/fdbased/endpoint_test.go
index 8aad338b6..eccd21579 100644
--- a/pkg/tcpip/link/fdbased/endpoint_test.go
+++ b/pkg/tcpip/link/fdbased/endpoint_test.go
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//go:build linux
// +build linux
package fdbased
diff --git a/pkg/tcpip/link/fdbased/endpoint_unsafe.go b/pkg/tcpip/link/fdbased/endpoint_unsafe.go
index df14eaad1..904393faa 100644
--- a/pkg/tcpip/link/fdbased/endpoint_unsafe.go
+++ b/pkg/tcpip/link/fdbased/endpoint_unsafe.go
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//go:build linux
// +build linux
package fdbased
diff --git a/pkg/tcpip/link/fdbased/mmap.go b/pkg/tcpip/link/fdbased/mmap.go
index 5d698a5e9..bfae34ab9 100644
--- a/pkg/tcpip/link/fdbased/mmap.go
+++ b/pkg/tcpip/link/fdbased/mmap.go
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//go:build (linux && amd64) || (linux && arm64)
// +build linux,amd64 linux,arm64
package fdbased
diff --git a/pkg/tcpip/link/fdbased/mmap_stub.go b/pkg/tcpip/link/fdbased/mmap_stub.go
index 67be52d67..9d8679502 100644
--- a/pkg/tcpip/link/fdbased/mmap_stub.go
+++ b/pkg/tcpip/link/fdbased/mmap_stub.go
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//go:build !linux || (!amd64 && !arm64)
// +build !linux !amd64,!arm64
package fdbased
diff --git a/pkg/tcpip/link/fdbased/mmap_unsafe.go b/pkg/tcpip/link/fdbased/mmap_unsafe.go
index 1293f68a2..58d5dfeef 100644
--- a/pkg/tcpip/link/fdbased/mmap_unsafe.go
+++ b/pkg/tcpip/link/fdbased/mmap_unsafe.go
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//go:build (linux && amd64) || (linux && arm64)
// +build linux,amd64 linux,arm64
package fdbased
diff --git a/pkg/tcpip/link/fdbased/packet_dispatchers.go b/pkg/tcpip/link/fdbased/packet_dispatchers.go
index 4b7ef3aac..ab2855a63 100644
--- a/pkg/tcpip/link/fdbased/packet_dispatchers.go
+++ b/pkg/tcpip/link/fdbased/packet_dispatchers.go
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//go:build linux
// +build linux
package fdbased
diff --git a/pkg/tcpip/link/rawfile/blockingpoll_noyield_unsafe.go b/pkg/tcpip/link/rawfile/blockingpoll_noyield_unsafe.go
index 2206fe0e6..c1438da21 100644
--- a/pkg/tcpip/link/rawfile/blockingpoll_noyield_unsafe.go
+++ b/pkg/tcpip/link/rawfile/blockingpoll_noyield_unsafe.go
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//go:build linux && !amd64 && !arm64
// +build linux,!amd64,!arm64
package rawfile
diff --git a/pkg/tcpip/link/rawfile/blockingpoll_yield_unsafe.go b/pkg/tcpip/link/rawfile/blockingpoll_yield_unsafe.go
index 5002245a1..da900c24b 100644
--- a/pkg/tcpip/link/rawfile/blockingpoll_yield_unsafe.go
+++ b/pkg/tcpip/link/rawfile/blockingpoll_yield_unsafe.go
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//go:build ((linux && amd64) || (linux && arm64)) && go1.12 && !go1.18
// +build linux,amd64 linux,arm64
// +build go1.12
// +build !go1.18
diff --git a/pkg/tcpip/link/rawfile/errors.go b/pkg/tcpip/link/rawfile/errors.go
index 9743e70ea..7e21a78d4 100644
--- a/pkg/tcpip/link/rawfile/errors.go
+++ b/pkg/tcpip/link/rawfile/errors.go
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//go:build linux
// +build linux
package rawfile
diff --git a/pkg/tcpip/link/rawfile/errors_test.go b/pkg/tcpip/link/rawfile/errors_test.go
index 8f4bd60da..1b88c309b 100644
--- a/pkg/tcpip/link/rawfile/errors_test.go
+++ b/pkg/tcpip/link/rawfile/errors_test.go
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//go:build linux
// +build linux
package rawfile
diff --git a/pkg/tcpip/link/rawfile/rawfile_unsafe.go b/pkg/tcpip/link/rawfile/rawfile_unsafe.go
index 43fe57830..53448a641 100644
--- a/pkg/tcpip/link/rawfile/rawfile_unsafe.go
+++ b/pkg/tcpip/link/rawfile/rawfile_unsafe.go
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//go:build linux
// +build linux
// Package rawfile contains utilities for using the netstack with raw host
diff --git a/pkg/tcpip/link/sharedmem/rx.go b/pkg/tcpip/link/sharedmem/rx.go
index 8e6f3e5e3..e882a128c 100644
--- a/pkg/tcpip/link/sharedmem/rx.go
+++ b/pkg/tcpip/link/sharedmem/rx.go
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//go:build linux
// +build linux
package sharedmem
diff --git a/pkg/tcpip/link/sharedmem/sharedmem.go b/pkg/tcpip/link/sharedmem/sharedmem.go
index df9a0b90a..30cf659b8 100644
--- a/pkg/tcpip/link/sharedmem/sharedmem.go
+++ b/pkg/tcpip/link/sharedmem/sharedmem.go
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//go:build linux
// +build linux
// Package sharedmem provides the implemention of data-link layer endpoints
diff --git a/pkg/tcpip/link/sharedmem/sharedmem_test.go b/pkg/tcpip/link/sharedmem/sharedmem_test.go
index 0f72d4e95..d6d953085 100644
--- a/pkg/tcpip/link/sharedmem/sharedmem_test.go
+++ b/pkg/tcpip/link/sharedmem/sharedmem_test.go
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//go:build linux
// +build linux
package sharedmem
diff --git a/pkg/tcpip/link/tun/tun_unsafe.go b/pkg/tcpip/link/tun/tun_unsafe.go
index 0591fbd63..db4338e79 100644
--- a/pkg/tcpip/link/tun/tun_unsafe.go
+++ b/pkg/tcpip/link/tun/tun_unsafe.go
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//go:build linux
// +build linux
// Package tun contains methods to open TAP and TUN devices.
diff --git a/pkg/tcpip/sample/tun_tcp_connect/main.go b/pkg/tcpip/sample/tun_tcp_connect/main.go
index b9a24ff56..009cab643 100644
--- a/pkg/tcpip/sample/tun_tcp_connect/main.go
+++ b/pkg/tcpip/sample/tun_tcp_connect/main.go
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//go:build linux
// +build linux
// This sample creates a stack with TCP and IPv4 protocols on top of a TUN
diff --git a/pkg/tcpip/sample/tun_tcp_echo/main.go b/pkg/tcpip/sample/tun_tcp_echo/main.go
index ef1bfc186..c10b19aa0 100644
--- a/pkg/tcpip/sample/tun_tcp_echo/main.go
+++ b/pkg/tcpip/sample/tun_tcp_echo/main.go
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//go:build linux
// +build linux
// This sample creates a stack with TCP and IPv4 protocols on top of a TUN
diff --git a/pkg/tcpip/socketops.go b/pkg/tcpip/socketops.go
index 042326a3a..5642c86f8 100644
--- a/pkg/tcpip/socketops.go
+++ b/pkg/tcpip/socketops.go
@@ -54,7 +54,7 @@ type SocketOptionsHandler interface {
// buffer size. It also returns the newly set value.
OnSetSendBufferSize(v int64) (newSz int64)
- // OnSetReceiveBufferSize is invoked to set the SO_RCVBUFSIZE.
+ // OnSetReceiveBufferSize is invoked by SO_RCVBUF and SO_RCVBUFFORCE.
OnSetReceiveBufferSize(v, oldSz int64) (newSz int64)
}
diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go
index 8f2658f64..55683b4fb 100644
--- a/pkg/tcpip/tcpip.go
+++ b/pkg/tcpip/tcpip.go
@@ -1845,6 +1845,10 @@ type TCPStats struct {
// FailedPortReservations is the number of times TCP failed to reserve
// a port.
FailedPortReservations *StatCounter
+
+ // SegmentsAckedWithDSACK is the number of segments acknowledged with
+ // DSACK.
+ SegmentsAckedWithDSACK *StatCounter
}
// UDPStats collects UDP-specific stats.
diff --git a/pkg/tcpip/transport/raw/endpoint.go b/pkg/tcpip/transport/raw/endpoint.go
index ab5da987a..b3d8951ff 100644
--- a/pkg/tcpip/transport/raw/endpoint.go
+++ b/pkg/tcpip/transport/raw/endpoint.go
@@ -455,8 +455,21 @@ func (e *endpoint) Bind(addr tcpip.FullAddress) tcpip.Error {
}
// GetLocalAddress implements tcpip.Endpoint.GetLocalAddress.
-func (*endpoint) GetLocalAddress() (tcpip.FullAddress, tcpip.Error) {
- return tcpip.FullAddress{}, &tcpip.ErrNotSupported{}
+func (e *endpoint) GetLocalAddress() (tcpip.FullAddress, tcpip.Error) {
+ e.mu.RLock()
+ defer e.mu.RUnlock()
+
+ addr := e.BindAddr
+ if e.connected {
+ addr = e.route.LocalAddress()
+ }
+
+ return tcpip.FullAddress{
+ NIC: e.RegisterNICID,
+ Addr: addr,
+ // Linux returns the protocol in the port field.
+ Port: uint16(e.TransProto),
+ }, nil
}
// GetRemoteAddress implements tcpip.Endpoint.GetRemoteAddress.
diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go
index 9945fdd6b..044123185 100644
--- a/pkg/tcpip/transport/tcp/endpoint.go
+++ b/pkg/tcpip/transport/tcp/endpoint.go
@@ -478,7 +478,7 @@ type endpoint struct {
// shutdownFlags represent the current shutdown state of the endpoint.
shutdownFlags tcpip.ShutdownFlags
- // tcpRecovery is the loss deteoction algorithm used by TCP.
+ // tcpRecovery is the loss recovery algorithm used by TCP.
tcpRecovery tcpip.TCPRecovery
// sack holds TCP SACK related information for this endpoint.
@@ -754,7 +754,7 @@ func (e *endpoint) ResumeWork() {
//
// Precondition: e.mu must be held to call this method.
func (e *endpoint) setEndpointState(state EndpointState) {
- oldstate := EndpointState(atomic.LoadUint32(&e.state))
+ oldstate := EndpointState(atomic.SwapUint32(&e.state, uint32(state)))
switch state {
case StateEstablished:
e.stack.Stats().TCP.CurrentEstablished.Increment()
@@ -771,7 +771,6 @@ func (e *endpoint) setEndpointState(state EndpointState) {
e.stack.Stats().TCP.CurrentEstablished.Decrement()
}
}
- atomic.StoreUint32(&e.state, uint32(state))
}
// EndpointState returns the current state of the endpoint.
@@ -870,8 +869,6 @@ func newEndpoint(s *stack.Stack, netProto tcpip.NetworkProtocolNumber, waiterQue
e.maxSynRetries = uint8(synRetries)
}
- s.TransportProtocolOption(ProtocolNumber, &e.tcpRecovery)
-
if p := s.GetTCPProbe(); p != nil {
e.probe = p
}
@@ -2923,6 +2920,7 @@ func (e *endpoint) maybeEnableSACKPermitted(synOpts *header.TCPSynOptions) {
}
if bool(v) && synOpts.SACKPermitted {
e.SACKPermitted = true
+ e.stack.TransportProtocolOption(ProtocolNumber, &e.tcpRecovery)
}
}
diff --git a/pkg/tcpip/transport/tcp/protocol.go b/pkg/tcpip/transport/tcp/protocol.go
index 2fc282e73..18b834243 100644
--- a/pkg/tcpip/transport/tcp/protocol.go
+++ b/pkg/tcpip/transport/tcp/protocol.go
@@ -478,8 +478,7 @@ func NewProtocol(s *stack.Stack) stack.TransportProtocol {
minRTO: MinRTO,
maxRTO: MaxRTO,
maxRetries: MaxRetries,
- // TODO(gvisor.dev/issue/5243): Set recovery to tcpip.TCPRACKLossDetection.
- recovery: 0,
+ recovery: tcpip.TCPRACKLossDetection,
}
p.dispatcher.init(s.Rand(), runtime.GOMAXPROCS(0))
return &p
diff --git a/pkg/tcpip/transport/tcp/snd.go b/pkg/tcpip/transport/tcp/snd.go
index 72d58dcff..92a66f17e 100644
--- a/pkg/tcpip/transport/tcp/snd.go
+++ b/pkg/tcpip/transport/tcp/snd.go
@@ -1154,6 +1154,13 @@ func (s *sender) walkSACK(rcvdSeg *segment) {
idx := 0
n := len(rcvdSeg.parsedOptions.SACKBlocks)
if checkDSACK(rcvdSeg) {
+ dsackBlock := rcvdSeg.parsedOptions.SACKBlocks[0]
+ numDSACK := uint64(dsackBlock.End-dsackBlock.Start) / uint64(s.MaxPayloadSize)
+ // numDSACK can be zero when DSACK is sent for subsegments.
+ if numDSACK < 1 {
+ numDSACK = 1
+ }
+ s.ep.stack.Stats().TCP.SegmentsAckedWithDSACK.IncrementBy(numDSACK)
s.rc.setDSACKSeen(true)
idx = 1
n--
diff --git a/pkg/tcpip/transport/tcp/tcp_noracedetector_test.go b/pkg/tcpip/transport/tcp/tcp_noracedetector_test.go
index ced3a9c58..84fb1c416 100644
--- a/pkg/tcpip/transport/tcp/tcp_noracedetector_test.go
+++ b/pkg/tcpip/transport/tcp/tcp_noracedetector_test.go
@@ -16,6 +16,7 @@
// iterations taking long enough that the retransmit timer can kick in causing
// the congestion window measurements to fail due to extra packets etc.
//
+//go:build !race
// +build !race
package tcp_test
diff --git a/pkg/tcpip/transport/tcp/tcp_rack_test.go b/pkg/tcpip/transport/tcp/tcp_rack_test.go
index d6cf786a1..89e9fb886 100644
--- a/pkg/tcpip/transport/tcp/tcp_rack_test.go
+++ b/pkg/tcpip/transport/tcp/tcp_rack_test.go
@@ -36,9 +36,9 @@ const (
latency = 5 * time.Millisecond
)
-func setStackRACKPermitted(t *testing.T, c *context.Context) {
+func setStackTCPRecovery(t *testing.T, c *context.Context, recovery int) {
t.Helper()
- opt := tcpip.TCPRACKLossDetection
+ opt := tcpip.TCPRecovery(recovery)
if err := c.Stack().SetTransportProtocolOption(header.TCPProtocolNumber, &opt); err != nil {
t.Fatalf("c.s.SetTransportProtocolOption(%d, &%v(%v)): %s", header.TCPProtocolNumber, opt, opt, err)
}
@@ -70,7 +70,6 @@ func TestRACKUpdate(t *testing.T) {
close(probeDone)
})
setStackSACKPermitted(t, c, true)
- setStackRACKPermitted(t, c)
createConnectedWithSACKAndTS(c)
data := make([]byte, maxPayload)
@@ -129,7 +128,6 @@ func TestRACKDetectReorder(t *testing.T) {
close(probeDone)
})
setStackSACKPermitted(t, c, true)
- setStackRACKPermitted(t, c)
createConnectedWithSACKAndTS(c)
data := make([]byte, ackNumToVerify*maxPayload)
for i := range data {
@@ -162,8 +160,8 @@ func TestRACKDetectReorder(t *testing.T) {
func sendAndReceiveWithSACK(t *testing.T, c *context.Context, numPackets int, enableRACK bool) []byte {
setStackSACKPermitted(t, c, true)
- if enableRACK {
- setStackRACKPermitted(t, c)
+ if !enableRACK {
+ setStackTCPRecovery(t, c, 0)
}
createConnectedWithSACKAndTS(c)
@@ -542,6 +540,28 @@ func TestRACKDetectDSACK(t *testing.T) {
case invalidDSACKDetected:
t.Fatalf("RACK DSACK detected when there is no duplicate SACK")
}
+
+ metricPollFn := func() error {
+ tcpStats := c.Stack().Stats().TCP
+ stats := []struct {
+ stat *tcpip.StatCounter
+ name string
+ want uint64
+ }{
+ // Check DSACK was received for one segment.
+ {tcpStats.SegmentsAckedWithDSACK, "stats.TCP.SegmentsAckedWithDSACK", 1},
+ }
+ for _, s := range stats {
+ if got, want := s.stat.Value(), s.want; got != want {
+ return fmt.Errorf("got %s.Value() = %d, want = %d", s.name, got, want)
+ }
+ }
+ return nil
+ }
+
+ if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
+ t.Error(err)
+ }
}
// TestRACKDetectDSACKWithOutOfOrder tests that RACK detects DSACK with out of
@@ -682,6 +702,28 @@ func TestRACKDetectDSACKSingleDup(t *testing.T) {
case invalidDSACKDetected:
t.Fatalf("RACK DSACK detected when there is no duplicate SACK")
}
+
+ metricPollFn := func() error {
+ tcpStats := c.Stack().Stats().TCP
+ stats := []struct {
+ stat *tcpip.StatCounter
+ name string
+ want uint64
+ }{
+ // Check DSACK was received for a subsegment.
+ {tcpStats.SegmentsAckedWithDSACK, "stats.TCP.SegmentsAckedWithDSACK", 1},
+ }
+ for _, s := range stats {
+ if got, want := s.stat.Value(), s.want; got != want {
+ return fmt.Errorf("got %s.Value() = %d, want = %d", s.name, got, want)
+ }
+ }
+ return nil
+ }
+
+ if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
+ t.Error(err)
+ }
}
// TestRACKDetectDSACKDupWithCumulativeACK tests DSACK for two non-contiguous
@@ -998,7 +1040,6 @@ func TestRACKWithWindowFull(t *testing.T) {
defer c.Cleanup()
setStackSACKPermitted(t, c, true)
- setStackRACKPermitted(t, c)
createConnectedWithSACKAndTS(c)
seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
diff --git a/pkg/tcpip/transport/tcp/tcp_sack_test.go b/pkg/tcpip/transport/tcp/tcp_sack_test.go
index 20c9761f2..83e0653b9 100644
--- a/pkg/tcpip/transport/tcp/tcp_sack_test.go
+++ b/pkg/tcpip/transport/tcp/tcp_sack_test.go
@@ -61,6 +61,7 @@ func TestSackPermittedConnect(t *testing.T) {
defer c.Cleanup()
setStackSACKPermitted(t, c, sackEnabled)
+ setStackTCPRecovery(t, c, 0)
rep := createConnectedWithSACKPermittedOption(c)
data := []byte{1, 2, 3}
@@ -105,6 +106,7 @@ func TestSackDisabledConnect(t *testing.T) {
defer c.Cleanup()
setStackSACKPermitted(t, c, sackEnabled)
+ setStackTCPRecovery(t, c, 0)
rep := c.CreateConnectedWithOptions(header.TCPSynOptions{})
@@ -166,6 +168,7 @@ func TestSackPermittedAccept(t *testing.T) {
}
}
setStackSACKPermitted(t, c, sackEnabled)
+ setStackTCPRecovery(t, c, 0)
rep := c.AcceptWithOptions(tc.wndScale, header.TCPSynOptions{MSS: defaultIPv4MSS, SACKPermitted: tc.sackPermitted})
// Now verify no SACK blocks are
@@ -239,6 +242,7 @@ func TestSackDisabledAccept(t *testing.T) {
}
setStackSACKPermitted(t, c, sackEnabled)
+ setStackTCPRecovery(t, c, 0)
rep := c.AcceptWithOptions(tc.wndScale, header.TCPSynOptions{MSS: defaultIPv4MSS})
@@ -386,6 +390,7 @@ func TestSACKRecovery(t *testing.T) {
log.Printf("state: %+v\n", s)
})
setStackSACKPermitted(t, c, true)
+ setStackTCPRecovery(t, c, 0)
createConnectedWithSACKAndTS(c)
const iterations = 3