Use TCP_INFO to get RTO in tcp_retransmits_test

- TCP_INFO is used to get the RTO instead of calculating it manually.

PiperOrigin-RevId: 358032487
This commit is contained in:
Nayana Bidari
2021-02-17 14:25:29 -08:00
committed by gVisor bot
parent 0e0bc35879
commit 3145fe1d1e
2 changed files with 32 additions and 16 deletions
+3
View File
@@ -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",
],
+29 -16
View File
@@ -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 _, 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)
}
if i == 0 {
startRTO = time.Now().Sub(first)
current = 2 * startRTO
continue
if diff := time.Since(startTime); diff+diffCorrection < rto {
t.Fatalf("retransmit came sooner got: %d want: >= %d probe %d", diff, rto, i)
}
// 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)
}
current *= 2
startTime = time.Now()
rto = getRTO(t, dut, acceptFd)
timeout = rto + timeoutCorrection
}
}