summaryrefslogtreecommitdiffhomepage
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/tcpip/transport/tcp/snd.go18
-rw-r--r--pkg/tcpip/transport/tcp/tcp_rack_test.go11
2 files changed, 24 insertions, 5 deletions
diff --git a/pkg/tcpip/transport/tcp/snd.go b/pkg/tcpip/transport/tcp/snd.go
index 463a259b7..063a7086a 100644
--- a/pkg/tcpip/transport/tcp/snd.go
+++ b/pkg/tcpip/transport/tcp/snd.go
@@ -1320,7 +1320,9 @@ func (s *sender) handleRcvdSegment(rcvdSeg *segment) {
// unacknowledged and also never retransmitted sequence below
// RACK.fack, then the corresponding packet has been
// reordered and RACK.reord is set to TRUE.
- s.walkSACK(rcvdSeg)
+ if s.ep.tcpRecovery&tcpip.TCPRACKLossDetection != 0 {
+ s.walkSACK(rcvdSeg)
+ }
s.SetPipe()
}
@@ -1339,7 +1341,9 @@ func (s *sender) handleRcvdSegment(rcvdSeg *segment) {
}
// See if TLP based recovery was successful.
- s.detectTLPRecovery(ack, rcvdSeg)
+ if s.ep.tcpRecovery&tcpip.TCPRACKLossDetection != 0 {
+ s.detectTLPRecovery(ack, rcvdSeg)
+ }
// Stash away the current window size.
s.sndWnd = rcvdSeg.window
@@ -1421,7 +1425,7 @@ func (s *sender) handleRcvdSegment(rcvdSeg *segment) {
}
// Update the RACK fields if SACK is enabled.
- if s.ep.sackPermitted && !seg.acked {
+ if s.ep.sackPermitted && !seg.acked && s.ep.tcpRecovery&tcpip.TCPRACKLossDetection != 0 {
s.rc.update(seg, rcvdSeg)
s.rc.detectReorder(seg)
}
@@ -1455,7 +1459,9 @@ func (s *sender) handleRcvdSegment(rcvdSeg *segment) {
// Update RACK when we are exiting fast or RTO
// recovery as described in the RFC
// draft-ietf-tcpm-rack-08 Section-7.2 Step 4.
- s.rc.exitRecovery()
+ if s.ep.tcpRecovery&tcpip.TCPRACKLossDetection != 0 {
+ s.rc.exitRecovery()
+ }
}
}
@@ -1483,7 +1489,9 @@ func (s *sender) handleRcvdSegment(rcvdSeg *segment) {
// See: https://tools.ietf.org/html/draft-ietf-tcpm-rack-08#section-7.2
// * Upon receiving an ACK:
// * Step 4: Update RACK reordering window
- s.rc.updateRACKReorderWindow(rcvdSeg)
+ if s.ep.tcpRecovery&tcpip.TCPRACKLossDetection != 0 {
+ s.rc.updateRACKReorderWindow(rcvdSeg)
+ }
// Now that we've popped all acknowledged data from the retransmit
// queue, retransmit if needed.
diff --git a/pkg/tcpip/transport/tcp/tcp_rack_test.go b/pkg/tcpip/transport/tcp/tcp_rack_test.go
index a6a26b705..78db742a9 100644
--- a/pkg/tcpip/transport/tcp/tcp_rack_test.go
+++ b/pkg/tcpip/transport/tcp/tcp_rack_test.go
@@ -34,6 +34,14 @@ const (
mtu = header.TCPMinimumSize + header.IPv4MinimumSize + maxTCPOptionSize + maxPayload
)
+func setStackRACKPermitted(t *testing.T, c *context.Context) {
+ t.Helper()
+ opt := tcpip.TCPRecovery(tcpip.TCPRACKLossDetection)
+ if err := c.Stack().SetTransportProtocolOption(header.TCPProtocolNumber, &opt); err != nil {
+ t.Fatalf("c.s.SetTransportProtocolOption(%d, &%v(%v)): %s", header.TCPProtocolNumber, opt, opt, err)
+ }
+}
+
// TestRACKUpdate tests the RACK related fields are updated when an ACK is
// received on a SACK enabled connection.
func TestRACKUpdate(t *testing.T) {
@@ -60,6 +68,7 @@ func TestRACKUpdate(t *testing.T) {
close(probeDone)
})
setStackSACKPermitted(t, c, true)
+ setStackRACKPermitted(t, c)
createConnectedWithSACKAndTS(c)
data := make([]byte, maxPayload)
@@ -116,6 +125,7 @@ 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 {
@@ -148,6 +158,7 @@ func TestRACKDetectReorder(t *testing.T) {
func sendAndReceive(t *testing.T, c *context.Context, numPackets int) []byte {
setStackSACKPermitted(t, c, true)
+ setStackRACKPermitted(t, c)
createConnectedWithSACKAndTS(c)
data := make([]byte, numPackets*maxPayload)