diff options
-rw-r--r-- | test/packetimpact/tests/BUILD | 3 | ||||
-rw-r--r-- | test/packetimpact/tests/tcp_retransmits_test.go | 45 |
2 files changed, 32 insertions, 16 deletions
diff --git a/test/packetimpact/tests/BUILD b/test/packetimpact/tests/BUILD index 7414a947a..3e27f50dc 100644 --- a/test/packetimpact/tests/BUILD +++ b/test/packetimpact/tests/BUILD @@ -103,7 +103,10 @@ packetimpact_testbench( name = "tcp_retransmits", srcs = ["tcp_retransmits_test.go"], deps = [ + "//pkg/abi/linux", + "//pkg/binary", "//pkg/tcpip/header", + "//pkg/usermem", "//test/packetimpact/testbench", "@org_golang_x_sys//unix:go_default_library", ], diff --git a/test/packetimpact/tests/tcp_retransmits_test.go b/test/packetimpact/tests/tcp_retransmits_test.go index 27e9641b1..ba79fbf55 100644 --- a/test/packetimpact/tests/tcp_retransmits_test.go +++ b/test/packetimpact/tests/tcp_retransmits_test.go @@ -20,7 +20,10 @@ import ( "time" "golang.org/x/sys/unix" + "gvisor.dev/gvisor/pkg/abi/linux" + "gvisor.dev/gvisor/pkg/binary" "gvisor.dev/gvisor/pkg/tcpip/header" + "gvisor.dev/gvisor/pkg/usermem" "gvisor.dev/gvisor/test/packetimpact/testbench" ) @@ -28,6 +31,16 @@ func init() { testbench.Initialize(flag.CommandLine) } +func getRTO(t *testing.T, dut testbench.DUT, acceptFd int32) (rto time.Duration) { + info := linux.TCPInfo{} + infoBytes := dut.GetSockOpt(t, acceptFd, unix.SOL_TCP, unix.TCP_INFO, int32(linux.SizeOfTCPInfo)) + if got, want := len(infoBytes), linux.SizeOfTCPInfo; got != want { + t.Fatalf("unexpected size for TCP_INFO, got %d bytes want %d bytes", got, want) + } + binary.Unmarshal(infoBytes, usermem.ByteOrder, &info) + return time.Duration(info.RTO) * time.Microsecond +} + // TestRetransmits tests retransmits occur at exponentially increasing // time intervals. func TestRetransmits(t *testing.T) { @@ -55,29 +68,29 @@ func TestRetransmits(t *testing.T) { // we can skip sending this ACK. conn.Send(t, testbench.TCP{Flags: testbench.Uint8(header.TCPFlagAck)}) - startRTO := time.Second - current := startRTO - first := time.Now() + const timeoutCorrection = time.Second + const diffCorrection = time.Millisecond + rto := getRTO(t, dut, acceptFd) + timeout := rto + timeoutCorrection + + startTime := time.Now() dut.Send(t, acceptFd, sampleData, 0) seq := testbench.Uint32(uint32(*conn.RemoteSeqNum(t))) - if _, err := conn.ExpectData(t, &testbench.TCP{SeqNum: seq}, samplePayload, startRTO); err != nil { + if _, err := conn.ExpectData(t, &testbench.TCP{SeqNum: seq}, samplePayload, timeout); err != nil { t.Fatalf("expected payload was not received: %s", err) } + // Expect retransmits of the same segment. for i := 0; i < 5; i++ { - start := time.Now() - if _, err := conn.ExpectData(t, &testbench.TCP{SeqNum: seq}, samplePayload, 2*current); err != nil { - t.Fatalf("expected payload was not received: %s loop %d", err, i) - } - if i == 0 { - startRTO = time.Now().Sub(first) - current = 2 * startRTO - continue + if _, err := conn.ExpectData(t, &testbench.TCP{SeqNum: seq}, samplePayload, timeout); err != nil { + t.Fatalf("expected payload was not received within %d loop %d err %s", timeout, i, err) } - // Check if the probes came at exponentially increasing intervals. - if p := time.Since(start); p < current-startRTO { - t.Fatalf("retransmit came sooner interval %d probe %d", p, i) + + if diff := time.Since(startTime); diff+diffCorrection < rto { + t.Fatalf("retransmit came sooner got: %d want: >= %d probe %d", diff, rto, i) } - current *= 2 + startTime = time.Now() + rto = getRTO(t, dut, acceptFd) + timeout = rto + timeoutCorrection } } |