summaryrefslogtreecommitdiffhomepage
path: root/test/packetimpact
diff options
context:
space:
mode:
Diffstat (limited to 'test/packetimpact')
-rw-r--r--test/packetimpact/testbench/BUILD2
-rw-r--r--test/packetimpact/testbench/dut.go33
-rw-r--r--test/packetimpact/testbench/layers.go62
-rw-r--r--test/packetimpact/testbench/layers_test.go2
-rw-r--r--test/packetimpact/tests/BUILD7
-rw-r--r--test/packetimpact/tests/icmpv6_param_problem_test.go7
-rw-r--r--test/packetimpact/tests/ipv6_unknown_options_action_test.go20
-rw-r--r--test/packetimpact/tests/tcp_connect_icmp_error_test.go19
-rw-r--r--test/packetimpact/tests/tcp_info_test.go18
-rw-r--r--test/packetimpact/tests/tcp_network_unreachable_test.go57
-rw-r--r--test/packetimpact/tests/tcp_rack_test.go16
-rw-r--r--test/packetimpact/tests/tcp_retransmits_test.go10
-rw-r--r--test/packetimpact/tests/tcp_synsent_reset_test.go19
-rw-r--r--test/packetimpact/tests/udp_icmp_error_propagation_test.go29
14 files changed, 143 insertions, 158 deletions
diff --git a/test/packetimpact/testbench/BUILD b/test/packetimpact/testbench/BUILD
index 616215dc3..d8059ab98 100644
--- a/test/packetimpact/testbench/BUILD
+++ b/test/packetimpact/testbench/BUILD
@@ -16,6 +16,8 @@ go_library(
],
visibility = ["//test/packetimpact:__subpackages__"],
deps = [
+ "//pkg/abi/linux",
+ "//pkg/binary",
"//pkg/hostarch",
"//pkg/tcpip",
"//pkg/tcpip/buffer",
diff --git a/test/packetimpact/testbench/dut.go b/test/packetimpact/testbench/dut.go
index eabdc8cb3..269e163bb 100644
--- a/test/packetimpact/testbench/dut.go
+++ b/test/packetimpact/testbench/dut.go
@@ -22,11 +22,13 @@ import (
"testing"
"time"
- pb "gvisor.dev/gvisor/test/packetimpact/proto/posix_server_go_proto"
-
"golang.org/x/sys/unix"
"google.golang.org/grpc"
"google.golang.org/grpc/keepalive"
+ "gvisor.dev/gvisor/pkg/abi/linux"
+ bin "gvisor.dev/gvisor/pkg/binary"
+ "gvisor.dev/gvisor/pkg/hostarch"
+ pb "gvisor.dev/gvisor/test/packetimpact/proto/posix_server_go_proto"
)
// DUT communicates with the DUT to force it to make POSIX calls.
@@ -428,6 +430,33 @@ func (dut *DUT) GetSockOptTimevalWithErrno(ctx context.Context, t *testing.T, so
return ret, timeval, errno
}
+// GetSockOptTCPInfo retreives TCPInfo for the given socket descriptor.
+func (dut *DUT) GetSockOptTCPInfo(t *testing.T, sockfd int32) linux.TCPInfo {
+ t.Helper()
+
+ ctx, cancel := context.WithTimeout(context.Background(), RPCTimeout)
+ defer cancel()
+ ret, info, err := dut.GetSockOptTCPInfoWithErrno(ctx, t, sockfd)
+ if ret != 0 || err != unix.Errno(0) {
+ t.Fatalf("failed to GetSockOptTCPInfo: %s", err)
+ }
+ return info
+}
+
+// GetSockOptTCPInfoWithErrno retreives TCPInfo with any errno.
+func (dut *DUT) GetSockOptTCPInfoWithErrno(ctx context.Context, t *testing.T, sockfd int32) (int32, linux.TCPInfo, error) {
+ t.Helper()
+
+ info := linux.TCPInfo{}
+ ret, infoBytes, errno := dut.GetSockOptWithErrno(ctx, t, sockfd, unix.SOL_TCP, unix.TCP_INFO, int32(linux.SizeOfTCPInfo))
+ if got, want := len(infoBytes), linux.SizeOfTCPInfo; got != want {
+ t.Fatalf("expected %T, got %d bytes want %d bytes", info, got, want)
+ }
+ bin.Unmarshal(infoBytes, hostarch.ByteOrder, &info)
+
+ return ret, info, errno
+}
+
// Listen calls listen on the DUT and causes a fatal test failure if it doesn't
// succeed. If more control over the timeout or error handling is needed, use
// ListenWithErrno.
diff --git a/test/packetimpact/testbench/layers.go b/test/packetimpact/testbench/layers.go
index 2311f7686..ef8b63db4 100644
--- a/test/packetimpact/testbench/layers.go
+++ b/test/packetimpact/testbench/layers.go
@@ -824,6 +824,7 @@ type ICMPv6 struct {
Type *header.ICMPv6Type
Code *header.ICMPv6Code
Checksum *uint16
+ Pointer *uint32 // Only in Parameter Problem.
Payload []byte
}
@@ -835,7 +836,7 @@ func (l *ICMPv6) String() string {
// ToBytes implements Layer.ToBytes.
func (l *ICMPv6) ToBytes() ([]byte, error) {
- b := make([]byte, header.ICMPv6HeaderSize+len(l.Payload))
+ b := make([]byte, header.ICMPv6MinimumSize+len(l.Payload))
h := header.ICMPv6(b)
if l.Type != nil {
h.SetType(*l.Type)
@@ -843,27 +844,30 @@ func (l *ICMPv6) ToBytes() ([]byte, error) {
if l.Code != nil {
h.SetCode(*l.Code)
}
- if n := copy(h.MessageBody(), l.Payload); n != len(l.Payload) {
+ if n := copy(h.Payload(), l.Payload); n != len(l.Payload) {
panic(fmt.Sprintf("copied %d bytes, expected to copy %d bytes", n, len(l.Payload)))
}
+ typ := h.Type()
+ switch typ {
+ case header.ICMPv6ParamProblem:
+ if l.Pointer != nil {
+ h.SetTypeSpecific(*l.Pointer)
+ }
+ }
if l.Checksum != nil {
h.SetChecksum(*l.Checksum)
} else {
// It is possible that the ICMPv6 header does not follow the IPv6 header
// immediately, there could be one or more extension headers in between.
- // We need to search forward to find the IPv6 header.
- for prev := l.Prev(); prev != nil; prev = prev.Prev() {
- if ipv6, ok := prev.(*IPv6); ok {
- payload, err := payload(l)
- if err != nil {
- return nil, err
- }
+ // We need to search backwards to find the IPv6 header.
+ for layer := l.Prev(); layer != nil; layer = layer.Prev() {
+ if ipv6, ok := layer.(*IPv6); ok {
h.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
- Header: h,
+ Header: h[:header.ICMPv6PayloadOffset],
Src: *ipv6.SrcAddr,
Dst: *ipv6.DstAddr,
- PayloadCsum: header.ChecksumVV(payload, 0 /* initial */),
- PayloadLen: payload.Size(),
+ PayloadCsum: header.Checksum(l.Payload, 0 /* initial */),
+ PayloadLen: len(l.Payload),
}))
break
}
@@ -884,20 +888,19 @@ func ICMPv6Code(v header.ICMPv6Code) *header.ICMPv6Code {
return &v
}
-// Byte is a helper routine that allocates a new byte value to store
-// v and returns a pointer to it.
-func Byte(v byte) *byte {
- return &v
-}
-
// parseICMPv6 parses the bytes assuming that they start with an ICMPv6 header.
func parseICMPv6(b []byte) (Layer, layerParser) {
h := header.ICMPv6(b)
+ msgType := h.Type()
icmpv6 := ICMPv6{
- Type: ICMPv6Type(h.Type()),
+ Type: ICMPv6Type(msgType),
Code: ICMPv6Code(h.Code()),
Checksum: Uint16(h.Checksum()),
- Payload: h.MessageBody(),
+ Payload: h.Payload(),
+ }
+ switch msgType {
+ case header.ICMPv6ParamProblem:
+ icmpv6.Pointer = Uint32(h.TypeSpecific())
}
return &icmpv6, nil
}
@@ -907,7 +910,7 @@ func (l *ICMPv6) match(other Layer) bool {
}
func (l *ICMPv6) length() int {
- return header.ICMPv6HeaderSize + len(l.Payload)
+ return header.ICMPv6MinimumSize + len(l.Payload)
}
// merge overrides the values in l with the values from other but only in fields
@@ -954,8 +957,8 @@ func (l *ICMPv4) ToBytes() ([]byte, error) {
if l.Code != nil {
h.SetCode(*l.Code)
}
- if copied := copy(h.Payload(), l.Payload); copied != len(l.Payload) {
- panic(fmt.Sprintf("wrong number of bytes copied into h.Payload(): got = %d, want = %d", len(h.Payload()), len(l.Payload)))
+ if n := copy(h.Payload(), l.Payload); n != len(l.Payload) {
+ panic(fmt.Sprintf("wrong number of bytes copied into h.Payload(): got = %d, want = %d", n, len(l.Payload)))
}
typ := h.Type()
switch typ {
@@ -977,16 +980,7 @@ func (l *ICMPv4) ToBytes() ([]byte, error) {
if l.Checksum != nil {
h.SetChecksum(*l.Checksum)
} else {
- // Compute the checksum based on the ICMPv4.Payload and also the subsequent
- // layers.
- payload, err := payload(l)
- if err != nil {
- return nil, err
- }
- var vv buffer.VectorisedView
- vv.AppendView(buffer.View(l.Payload))
- vv.Append(payload)
- h.SetChecksum(header.ICMPv4Checksum(h, header.ChecksumVV(vv, 0 /* initial */)))
+ h.SetChecksum(^header.Checksum(h, 0))
}
return h, nil
@@ -1019,7 +1013,7 @@ func (l *ICMPv4) match(other Layer) bool {
}
func (l *ICMPv4) length() int {
- return header.ICMPv4MinimumSize
+ return header.ICMPv4MinimumSize + len(l.Payload)
}
// merge overrides the values in l with the values from other but only in fields
diff --git a/test/packetimpact/testbench/layers_test.go b/test/packetimpact/testbench/layers_test.go
index 614a5de1e..bc96e0c88 100644
--- a/test/packetimpact/testbench/layers_test.go
+++ b/test/packetimpact/testbench/layers_test.go
@@ -596,7 +596,7 @@ func TestIPv6ExtHdrOptions(t *testing.T) {
Type: ICMPv6Type(header.ICMPv6ParamProblem),
Code: ICMPv6Code(header.ICMPv6ErroneousHeader),
Checksum: Uint16(0x5f98),
- Payload: []byte{0x00, 0x00, 0x00, 0x06},
+ Pointer: Uint32(6),
},
},
},
diff --git a/test/packetimpact/tests/BUILD b/test/packetimpact/tests/BUILD
index c4fe293e0..b1d280f98 100644
--- a/test/packetimpact/tests/BUILD
+++ b/test/packetimpact/tests/BUILD
@@ -104,8 +104,6 @@ packetimpact_testbench(
srcs = ["tcp_retransmits_test.go"],
deps = [
"//pkg/abi/linux",
- "//pkg/binary",
- "//pkg/hostarch",
"//pkg/tcpip/header",
"//test/packetimpact/testbench",
"@org_golang_x_sys//unix:go_default_library",
@@ -189,6 +187,7 @@ packetimpact_testbench(
name = "tcp_synsent_reset",
srcs = ["tcp_synsent_reset_test.go"],
deps = [
+ "//pkg/abi/linux",
"//pkg/tcpip/header",
"//test/packetimpact/testbench",
"@org_golang_x_sys//unix:go_default_library",
@@ -353,8 +352,6 @@ packetimpact_testbench(
srcs = ["tcp_rack_test.go"],
deps = [
"//pkg/abi/linux",
- "//pkg/binary",
- "//pkg/hostarch",
"//pkg/tcpip/header",
"//pkg/tcpip/seqnum",
"//test/packetimpact/testbench",
@@ -367,8 +364,6 @@ packetimpact_testbench(
srcs = ["tcp_info_test.go"],
deps = [
"//pkg/abi/linux",
- "//pkg/binary",
- "//pkg/hostarch",
"//pkg/tcpip/header",
"//test/packetimpact/testbench",
"@org_golang_x_sys//unix:go_default_library",
diff --git a/test/packetimpact/tests/icmpv6_param_problem_test.go b/test/packetimpact/tests/icmpv6_param_problem_test.go
index 1beccb6cf..fdabcf1ad 100644
--- a/test/packetimpact/tests/icmpv6_param_problem_test.go
+++ b/test/packetimpact/tests/icmpv6_param_problem_test.go
@@ -15,7 +15,6 @@
package icmpv6_param_problem_test
import (
- "encoding/binary"
"flag"
"testing"
"time"
@@ -56,13 +55,11 @@ func TestICMPv6ParamProblemTest(t *testing.T) {
t.Fatalf("can't convert %s to bytes: %s", ipv6Sent, err)
}
- // The problematic field is the NextHeader.
- b := make([]byte, 4)
- binary.BigEndian.PutUint32(b, header.IPv6NextHeaderOffset)
- expectedPayload = append(b, expectedPayload...)
expectedICMPv6 := testbench.ICMPv6{
Type: testbench.ICMPv6Type(header.ICMPv6ParamProblem),
Payload: expectedPayload,
+ // The problematic field is the NextHeader.
+ Pointer: testbench.Uint32(header.IPv6NextHeaderOffset),
}
paramProblem := testbench.Layers{
diff --git a/test/packetimpact/tests/ipv6_unknown_options_action_test.go b/test/packetimpact/tests/ipv6_unknown_options_action_test.go
index f999d13d2..d762c43a7 100644
--- a/test/packetimpact/tests/ipv6_unknown_options_action_test.go
+++ b/test/packetimpact/tests/ipv6_unknown_options_action_test.go
@@ -15,7 +15,6 @@
package ipv6_unknown_options_action_test
import (
- "encoding/binary"
"flag"
"net"
"testing"
@@ -154,23 +153,22 @@ func TestIPv6UnknownOptionAction(t *testing.T) {
outgoing := conn.CreateFrame(t, outgoingOverride, tt.mkExtHdr(optionTypeFromAction(tt.action)))
conn.SendFrame(t, outgoing)
ipv6Sent := outgoing[1:]
- invokingPacket, err := ipv6Sent.ToBytes()
+ icmpv6Payload, err := ipv6Sent.ToBytes()
if err != nil {
t.Fatalf("failed to serialize the outgoing packet: %s", err)
}
- icmpv6Payload := make([]byte, 4)
- // The pointer in the ICMPv6 parameter problem message should point to
- // the option type of the unknown option. In our test case, it is the
- // first option in the extension header whose option type is 2 bytes
- // after the IPv6 header (after NextHeader and ExtHdrLen).
- binary.BigEndian.PutUint32(icmpv6Payload, header.IPv6MinimumSize+2)
- icmpv6Payload = append(icmpv6Payload, invokingPacket...)
gotICMPv6, err := conn.ExpectFrame(t, testbench.Layers{
&testbench.Ether{},
&testbench.IPv6{},
&testbench.ICMPv6{
- Type: testbench.ICMPv6Type(header.ICMPv6ParamProblem),
- Code: testbench.ICMPv6Code(header.ICMPv6UnknownOption),
+ Type: testbench.ICMPv6Type(header.ICMPv6ParamProblem),
+ Code: testbench.ICMPv6Code(header.ICMPv6UnknownOption),
+ // The pointer in the ICMPv6 parameter problem message
+ // should point to the option type of the unknown option. In
+ // our test case, it is the first option in the extension
+ // header whose option type is 2 bytes after the IPv6 header
+ // (after NextHeader and ExtHdrLen).
+ Pointer: testbench.Uint32(header.IPv6MinimumSize + 2),
Payload: icmpv6Payload,
},
}, time.Second)
diff --git a/test/packetimpact/tests/tcp_connect_icmp_error_test.go b/test/packetimpact/tests/tcp_connect_icmp_error_test.go
index 79bfe9eb7..3b4c4cd63 100644
--- a/test/packetimpact/tests/tcp_connect_icmp_error_test.go
+++ b/test/packetimpact/tests/tcp_connect_icmp_error_test.go
@@ -33,17 +33,18 @@ func init() {
func sendICMPError(t *testing.T, conn *testbench.TCPIPv4, tcp *testbench.TCP) {
t.Helper()
- layers := conn.CreateFrame(t, nil)
- layers = layers[:len(layers)-1]
- ip, ok := tcp.Prev().(*testbench.IPv4)
- if !ok {
- t.Fatalf("expected %s to be IPv4", tcp.Prev())
+ icmpPayload := testbench.Layers{tcp.Prev(), tcp}
+ bytes, err := icmpPayload.ToBytes()
+ if err != nil {
+ t.Fatalf("got icmpPayload.ToBytes() = (_, %s), want = (_, nil)", err)
}
- icmpErr := &testbench.ICMPv4{
- Type: testbench.ICMPv4Type(header.ICMPv4DstUnreachable),
- Code: testbench.ICMPv4Code(header.ICMPv4HostUnreachable)}
- layers = append(layers, icmpErr, ip, tcp)
+ layers := conn.CreateFrame(t, nil)
+ layers[len(layers)-1] = &testbench.ICMPv4{
+ Type: testbench.ICMPv4Type(header.ICMPv4DstUnreachable),
+ Code: testbench.ICMPv4Code(header.ICMPv4HostUnreachable),
+ Payload: bytes,
+ }
conn.SendFrameStateless(t, layers)
}
diff --git a/test/packetimpact/tests/tcp_info_test.go b/test/packetimpact/tests/tcp_info_test.go
index 93f58ec49..b7514e846 100644
--- a/test/packetimpact/tests/tcp_info_test.go
+++ b/test/packetimpact/tests/tcp_info_test.go
@@ -21,8 +21,6 @@ import (
"golang.org/x/sys/unix"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/binary"
- "gvisor.dev/gvisor/pkg/hostarch"
"gvisor.dev/gvisor/pkg/tcpip/header"
"gvisor.dev/gvisor/test/packetimpact/testbench"
)
@@ -53,13 +51,10 @@ func TestTCPInfo(t *testing.T) {
}
conn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagAck)})
- 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("expected %T, got %d bytes want %d bytes", info, got, want)
+ info := dut.GetSockOptTCPInfo(t, acceptFD)
+ if got, want := uint32(info.State), linux.TCP_ESTABLISHED; got != want {
+ t.Fatalf("got %d want %d", got, want)
}
- binary.Unmarshal(infoBytes, hostarch.ByteOrder, &info)
-
rtt := time.Duration(info.RTT) * time.Microsecond
rttvar := time.Duration(info.RTTVar) * time.Microsecond
rto := time.Duration(info.RTO) * time.Microsecond
@@ -94,12 +89,7 @@ func TestTCPInfo(t *testing.T) {
t.Fatalf("expected a packet with payload %v: %s", samplePayload, err)
}
- 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("expected %T, got %d bytes want %d bytes", info, got, want)
- }
- binary.Unmarshal(infoBytes, hostarch.ByteOrder, &info)
+ info = dut.GetSockOptTCPInfo(t, acceptFD)
if info.CaState != linux.TCP_CA_Loss {
t.Errorf("expected the connection to be in loss recovery, got: %v want: %v", info.CaState, linux.TCP_CA_Loss)
}
diff --git a/test/packetimpact/tests/tcp_network_unreachable_test.go b/test/packetimpact/tests/tcp_network_unreachable_test.go
index 5168450ad..60a2dbf3d 100644
--- a/test/packetimpact/tests/tcp_network_unreachable_test.go
+++ b/test/packetimpact/tests/tcp_network_unreachable_test.go
@@ -50,30 +50,24 @@ func TestTCPSynSentUnreachable(t *testing.T) {
}
// Get the SYN.
- tcpLayers, err := conn.ExpectData(t, &testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagSyn)}, nil, time.Second)
+ tcp, err := conn.Expect(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagSyn)}, time.Second)
if err != nil {
t.Fatalf("expected SYN: %s", err)
}
// Send a host unreachable message.
- layers := conn.CreateFrame(t, nil)
- layers = layers[:len(layers)-1]
- const ipLayer = 1
- const tcpLayer = ipLayer + 1
- ip, ok := tcpLayers[ipLayer].(*testbench.IPv4)
- if !ok {
- t.Fatalf("expected %s to be IPv4", tcpLayers[ipLayer])
- }
- tcp, ok := tcpLayers[tcpLayer].(*testbench.TCP)
- if !ok {
- t.Fatalf("expected %s to be TCP", tcpLayers[tcpLayer])
- }
- var icmpv4 testbench.ICMPv4 = testbench.ICMPv4{
- Type: testbench.ICMPv4Type(header.ICMPv4DstUnreachable),
- Code: testbench.ICMPv4Code(header.ICMPv4HostUnreachable),
+ icmpPayload := testbench.Layers{tcp.Prev(), tcp}
+ bytes, err := icmpPayload.ToBytes()
+ if err != nil {
+ t.Fatalf("got icmpPayload.ToBytes() = (_, %s), want = (_, nil)", err)
}
- layers = append(layers, &icmpv4, ip, tcp)
+ layers := conn.CreateFrame(t, nil)
+ layers[len(layers)-1] = &testbench.ICMPv4{
+ Type: testbench.ICMPv4Type(header.ICMPv4DstUnreachable),
+ Code: testbench.ICMPv4Code(header.ICMPv4HostUnreachable),
+ Payload: bytes,
+ }
conn.SendFrameStateless(t, layers)
if err := getConnectError(t, &dut, clientFD); err != unix.EHOSTUNREACH {
@@ -104,31 +98,24 @@ func TestTCPSynSentUnreachable6(t *testing.T) {
}
// Get the SYN.
- tcpLayers, err := conn.ExpectData(t, &testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagSyn)}, nil, time.Second)
+ tcp, err := conn.Expect(t, &testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagSyn)}, time.Second)
if err != nil {
t.Fatalf("expected SYN: %s", err)
}
// Send a host unreachable message.
- layers := conn.CreateFrame(t, nil)
- layers = layers[:len(layers)-1]
- const ipLayer = 1
- const tcpLayer = ipLayer + 1
- ip, ok := tcpLayers[ipLayer].(*testbench.IPv6)
- if !ok {
- t.Fatalf("expected %s to be IPv6", tcpLayers[ipLayer])
- }
- tcp, ok := tcpLayers[tcpLayer].(*testbench.TCP)
- if !ok {
- t.Fatalf("expected %s to be TCP", tcpLayers[tcpLayer])
+ icmpPayload := testbench.Layers{tcp.Prev(), tcp}
+ bytes, err := icmpPayload.ToBytes()
+ if err != nil {
+ t.Fatalf("got icmpPayload.ToBytes() = (_, %s), want = (_, nil)", err)
}
- var icmpv6 testbench.ICMPv6 = testbench.ICMPv6{
- Type: testbench.ICMPv6Type(header.ICMPv6DstUnreachable),
- Code: testbench.ICMPv6Code(header.ICMPv6NetworkUnreachable),
- // Per RFC 4443 3.1, the payload contains 4 zeroed bytes.
- Payload: []byte{0, 0, 0, 0},
+
+ layers := conn.CreateFrame(t, nil)
+ layers[len(layers)-1] = &testbench.ICMPv6{
+ Type: testbench.ICMPv6Type(header.ICMPv6DstUnreachable),
+ Code: testbench.ICMPv6Code(header.ICMPv6NetworkUnreachable),
+ Payload: bytes,
}
- layers = append(layers, &icmpv6, ip, tcp)
conn.SendFrameStateless(t, layers)
if err := getConnectError(t, &dut, clientFD); err != unix.ENETUNREACH {
diff --git a/test/packetimpact/tests/tcp_rack_test.go b/test/packetimpact/tests/tcp_rack_test.go
index ff1431bbf..5a60bf712 100644
--- a/test/packetimpact/tests/tcp_rack_test.go
+++ b/test/packetimpact/tests/tcp_rack_test.go
@@ -21,8 +21,6 @@ import (
"golang.org/x/sys/unix"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/binary"
- "gvisor.dev/gvisor/pkg/hostarch"
"gvisor.dev/gvisor/pkg/tcpip/header"
"gvisor.dev/gvisor/pkg/tcpip/seqnum"
"gvisor.dev/gvisor/test/packetimpact/testbench"
@@ -69,12 +67,7 @@ func closeSACKConnection(t *testing.T, dut testbench.DUT, conn testbench.TCPIPv4
}
func getRTTAndRTO(t *testing.T, dut testbench.DUT, acceptFd int32) (rtt, 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("expected %T, got %d bytes want %d bytes", info, got, want)
- }
- binary.Unmarshal(infoBytes, hostarch.ByteOrder, &info)
+ info := dut.GetSockOptTCPInfo(t, acceptFd)
return time.Duration(info.RTT) * time.Microsecond, time.Duration(info.RTO) * time.Microsecond
}
@@ -402,12 +395,7 @@ func TestRACKWithLostRetransmission(t *testing.T) {
}
// Check the congestion control state.
- 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("expected %T, got %d bytes want %d bytes", info, got, want)
- }
- binary.Unmarshal(infoBytes, hostarch.ByteOrder, &info)
+ info := dut.GetSockOptTCPInfo(t, acceptFd)
if info.CaState != linux.TCP_CA_Recovery {
t.Fatalf("expected connection to be in fast recovery, want: %v got: %v", linux.TCP_CA_Recovery, info.CaState)
}
diff --git a/test/packetimpact/tests/tcp_retransmits_test.go b/test/packetimpact/tests/tcp_retransmits_test.go
index 1eafe20c3..d3fb789f4 100644
--- a/test/packetimpact/tests/tcp_retransmits_test.go
+++ b/test/packetimpact/tests/tcp_retransmits_test.go
@@ -21,9 +21,6 @@ import (
"time"
"golang.org/x/sys/unix"
- "gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/binary"
- "gvisor.dev/gvisor/pkg/hostarch"
"gvisor.dev/gvisor/pkg/tcpip/header"
"gvisor.dev/gvisor/test/packetimpact/testbench"
)
@@ -33,12 +30,7 @@ func init() {
}
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, hostarch.ByteOrder, &info)
+ info := dut.GetSockOptTCPInfo(t, acceptFd)
return time.Duration(info.RTO) * time.Microsecond
}
diff --git a/test/packetimpact/tests/tcp_synsent_reset_test.go b/test/packetimpact/tests/tcp_synsent_reset_test.go
index cccb0abc6..fe53e7061 100644
--- a/test/packetimpact/tests/tcp_synsent_reset_test.go
+++ b/test/packetimpact/tests/tcp_synsent_reset_test.go
@@ -20,6 +20,7 @@ import (
"time"
"golang.org/x/sys/unix"
+ "gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/tcpip/header"
"gvisor.dev/gvisor/test/packetimpact/testbench"
)
@@ -29,7 +30,7 @@ func init() {
}
// dutSynSentState sets up the dut connection in SYN-SENT state.
-func dutSynSentState(t *testing.T) (*testbench.DUT, *testbench.TCPIPv4, uint16, uint16) {
+func dutSynSentState(t *testing.T) (*testbench.DUT, *testbench.TCPIPv4, int32, uint16, uint16) {
t.Helper()
dut := testbench.NewDUT(t)
@@ -46,26 +47,29 @@ func dutSynSentState(t *testing.T) (*testbench.DUT, *testbench.TCPIPv4, uint16,
t.Fatalf("expected SYN\n")
}
- return &dut, &conn, port, clientPort
+ return &dut, &conn, clientFD, port, clientPort
}
// TestTCPSynSentReset tests RFC793, p67: SYN-SENT to CLOSED transition.
func TestTCPSynSentReset(t *testing.T) {
- _, conn, _, _ := dutSynSentState(t)
+ dut, conn, fd, _, _ := dutSynSentState(t)
defer conn.Close(t)
conn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagRst | header.TCPFlagAck)})
// Expect the connection to have closed.
- // TODO(gvisor.dev/issue/478): Check for TCP_INFO on the dut side.
conn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagAck)})
if _, err := conn.ExpectData(t, &testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagRst)}, nil, time.Second); err != nil {
t.Fatalf("expected a TCP RST")
}
+ info := dut.GetSockOptTCPInfo(t, fd)
+ if got, want := uint32(info.State), linux.TCP_CLOSE; got != want {
+ t.Fatalf("got %d want %d", got, want)
+ }
}
// TestTCPSynSentRcvdReset tests RFC793, p70, SYN-SENT to SYN-RCVD to CLOSED
// transitions.
func TestTCPSynSentRcvdReset(t *testing.T) {
- dut, c, remotePort, clientPort := dutSynSentState(t)
+ dut, c, fd, remotePort, clientPort := dutSynSentState(t)
defer c.Close(t)
conn := dut.Net.NewTCPIPv4(t, testbench.TCP{SrcPort: &remotePort, DstPort: &clientPort}, testbench.TCP{SrcPort: &clientPort, DstPort: &remotePort})
@@ -79,9 +83,12 @@ func TestTCPSynSentRcvdReset(t *testing.T) {
}
conn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagRst)})
// Expect the connection to have transitioned SYN-RCVD to CLOSED.
- // TODO(gvisor.dev/issue/478): Check for TCP_INFO on the dut side.
conn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagAck)})
if _, err := conn.ExpectData(t, &testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagRst)}, nil, time.Second); err != nil {
t.Fatalf("expected a TCP RST")
}
+ info := dut.GetSockOptTCPInfo(t, fd)
+ if got, want := uint32(info.State), linux.TCP_CLOSE; got != want {
+ t.Fatalf("got %d want %d", got, want)
+ }
}
diff --git a/test/packetimpact/tests/udp_icmp_error_propagation_test.go b/test/packetimpact/tests/udp_icmp_error_propagation_test.go
index 3159d5b89..087aeb66e 100644
--- a/test/packetimpact/tests/udp_icmp_error_propagation_test.go
+++ b/test/packetimpact/tests/udp_icmp_error_propagation_test.go
@@ -58,16 +58,20 @@ func (e icmpError) String() string {
return "Unknown ICMP error"
}
-func (e icmpError) ToICMPv4() *testbench.ICMPv4 {
+func (e icmpError) ToICMPv4(payload []byte) *testbench.ICMPv4 {
switch e {
case portUnreachable:
return &testbench.ICMPv4{
- Type: testbench.ICMPv4Type(header.ICMPv4DstUnreachable),
- Code: testbench.ICMPv4Code(header.ICMPv4PortUnreachable)}
+ Type: testbench.ICMPv4Type(header.ICMPv4DstUnreachable),
+ Code: testbench.ICMPv4Code(header.ICMPv4PortUnreachable),
+ Payload: payload,
+ }
case timeToLiveExceeded:
return &testbench.ICMPv4{
- Type: testbench.ICMPv4Type(header.ICMPv4TimeExceeded),
- Code: testbench.ICMPv4Code(header.ICMPv4TTLExceeded)}
+ Type: testbench.ICMPv4Type(header.ICMPv4TimeExceeded),
+ Code: testbench.ICMPv4Code(header.ICMPv4TTLExceeded),
+ Payload: payload,
+ }
}
return nil
}
@@ -101,8 +105,6 @@ func wantErrno(c connectionMode, icmpErr icmpError) unix.Errno {
func sendICMPError(t *testing.T, conn *testbench.UDPIPv4, icmpErr icmpError, udp *testbench.UDP) {
t.Helper()
- layers := conn.CreateFrame(t, nil)
- layers = layers[:len(layers)-1]
ip, ok := udp.Prev().(*testbench.IPv4)
if !ok {
t.Fatalf("expected %s to be IPv4", udp.Prev())
@@ -113,12 +115,15 @@ func sendICMPError(t *testing.T, conn *testbench.UDPIPv4, icmpErr icmpError, udp
// to 1.
ip.Checksum = nil
}
- // Note that the ICMP payload is valid in this case because the UDP
- // payload is empty. If the UDP payload were not empty, the packet
- // length during serialization may not be calculated correctly,
- // resulting in a mal-formed packet.
- layers = append(layers, icmpErr.ToICMPv4(), ip, udp)
+ icmpPayload := testbench.Layers{ip, udp}
+ bytes, err := icmpPayload.ToBytes()
+ if err != nil {
+ t.Fatalf("got icmpPayload.ToBytes() = (_, %s), want = (_, nil)", err)
+ }
+
+ layers := conn.CreateFrame(t, nil)
+ layers[len(layers)-1] = icmpErr.ToICMPv4(bytes)
conn.SendFrameStateless(t, layers)
}