@@ -21,17 +21,20 @@ import (
2121 "gvisor.dev/gvisor/pkg/tcpip"
2222 "gvisor.dev/gvisor/pkg/tcpip/buffer"
2323 "gvisor.dev/gvisor/pkg/tcpip/header"
24+ "gvisor.dev/gvisor/pkg/tcpip/seqnum"
2425 "gvisor.dev/gvisor/pkg/tcpip/stack"
2526 "gvisor.dev/gvisor/pkg/tcpip/transport/tcp/testing/context"
2627)
2728
29+ const (
30+ maxPayload = 10
31+ tsOptionSize = 12
32+ maxTCPOptionSize = 40
33+ )
34+
2835// TestRACKUpdate tests the RACK related fields are updated when an ACK is
2936// received on a SACK enabled connection.
3037func TestRACKUpdate (t * testing.T ) {
31- const maxPayload = 10
32- const tsOptionSize = 12
33- const maxTCPOptionSize = 40
34-
3538 c := context .New (t , uint32 (header .TCPMinimumSize + header .IPv4MinimumSize + maxTCPOptionSize + maxPayload ))
3639 defer c .Cleanup ()
3740
@@ -49,7 +52,7 @@ func TestRACKUpdate(t *testing.T) {
4952 }
5053
5154 if state .Sender .RACKState .RTT == 0 {
52- t .Fatalf ("RACK RTT failed to update when an ACK is received" )
55+ t .Fatalf ("RACK RTT failed to update when an ACK is received, got RACKState.RTT == 0 want != 0 " )
5356 }
5457 })
5558 setStackSACKPermitted (t , c , true )
@@ -69,6 +72,66 @@ func TestRACKUpdate(t *testing.T) {
6972 bytesRead := 0
7073 c .ReceiveAndCheckPacketWithOptions (data , bytesRead , maxPayload , tsOptionSize )
7174 bytesRead += maxPayload
72- c .SendAck (790 , bytesRead )
75+ c .SendAck (seqnum . Value ( context . TestInitialSequenceNumber ). Add ( 1 ) , bytesRead )
7376 time .Sleep (200 * time .Millisecond )
7477}
78+
79+ // TestRACKDetectReorder tests that RACK detects packet reordering.
80+ func TestRACKDetectReorder (t * testing.T ) {
81+ c := context .New (t , uint32 (header .TCPMinimumSize + header .IPv4MinimumSize + maxTCPOptionSize + maxPayload ))
82+ defer c .Cleanup ()
83+
84+ const ackNum = 2
85+
86+ var n int
87+ ch := make (chan struct {})
88+ c .Stack ().AddTCPProbe (func (state stack.TCPEndpointState ) {
89+ gotSeq := state .Sender .RACKState .FACK
90+ wantSeq := state .Sender .SndNxt
91+ // FACK should be updated to the highest ending sequence number of the
92+ // segment acknowledged most recently.
93+ if ! gotSeq .LessThanEq (wantSeq ) || gotSeq .LessThan (wantSeq ) {
94+ t .Fatalf ("RACK FACK failed to update, got: %v, but want: %v" , gotSeq , wantSeq )
95+ }
96+
97+ n ++
98+ if n < ackNum {
99+ if state .Sender .RACKState .Reord {
100+ t .Fatalf ("RACK reorder detected when there is no reordering" )
101+ }
102+ return
103+ }
104+
105+ if state .Sender .RACKState .Reord == false {
106+ t .Fatalf ("RACK reorder detection failed" )
107+ }
108+ close (ch )
109+ })
110+ setStackSACKPermitted (t , c , true )
111+ createConnectedWithSACKAndTS (c )
112+ data := buffer .NewView (ackNum * maxPayload )
113+ for i := range data {
114+ data [i ] = byte (i )
115+ }
116+
117+ // Write the data.
118+ if _ , _ , err := c .EP .Write (tcpip .SlicePayload (data ), tcpip.WriteOptions {}); err != nil {
119+ t .Fatalf ("Write failed: %s" , err )
120+ }
121+
122+ bytesRead := 0
123+ for i := 0 ; i < ackNum ; i ++ {
124+ c .ReceiveAndCheckPacketWithOptions (data , bytesRead , maxPayload , tsOptionSize )
125+ bytesRead += maxPayload
126+ }
127+
128+ start := c .IRS .Add (maxPayload + 1 )
129+ end := start .Add (maxPayload )
130+ seq := seqnum .Value (context .TestInitialSequenceNumber ).Add (1 )
131+ c .SendAckWithSACK (seq , 0 , []header.SACKBlock {{start , end }})
132+ c .SendAck (seq , bytesRead )
133+
134+ // Wait for the probe function to finish processing the ACK before the
135+ // test completes.
136+ <- ch
137+ }
0 commit comments