mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
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:
committed by
gVisor bot
parent
0e0bc35879
commit
3145fe1d1e
@@ -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",
|
||||
],
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user