diff options
Diffstat (limited to 'test')
100 files changed, 3173 insertions, 1948 deletions
diff --git a/test/benchmarks/base/BUILD b/test/benchmarks/base/BUILD index 697ab5837..a5a3cf2c1 100644 --- a/test/benchmarks/base/BUILD +++ b/test/benchmarks/base/BUILD @@ -17,7 +17,6 @@ go_library( benchmark_test( name = "startup_test", - size = "enormous", srcs = ["startup_test.go"], visibility = ["//:sandbox"], deps = [ @@ -29,7 +28,6 @@ benchmark_test( benchmark_test( name = "size_test", - size = "enormous", srcs = ["size_test.go"], visibility = ["//:sandbox"], deps = [ @@ -42,7 +40,6 @@ benchmark_test( benchmark_test( name = "sysbench_test", - size = "enormous", srcs = ["sysbench_test.go"], visibility = ["//:sandbox"], deps = [ diff --git a/test/benchmarks/database/BUILD b/test/benchmarks/database/BUILD index 0b1743603..fee2695ff 100644 --- a/test/benchmarks/database/BUILD +++ b/test/benchmarks/database/BUILD @@ -11,7 +11,6 @@ go_library( benchmark_test( name = "redis_test", - size = "enormous", srcs = ["redis_test.go"], library = ":database", visibility = ["//:sandbox"], diff --git a/test/benchmarks/fs/BUILD b/test/benchmarks/fs/BUILD index dc82e63b2..c2b981a07 100644 --- a/test/benchmarks/fs/BUILD +++ b/test/benchmarks/fs/BUILD @@ -4,7 +4,6 @@ package(licenses = ["notice"]) benchmark_test( name = "bazel_test", - size = "enormous", srcs = ["bazel_test.go"], visibility = ["//:sandbox"], deps = [ @@ -18,7 +17,6 @@ benchmark_test( benchmark_test( name = "fio_test", - size = "enormous", srcs = ["fio_test.go"], visibility = ["//:sandbox"], deps = [ diff --git a/test/benchmarks/media/BUILD b/test/benchmarks/media/BUILD index 380783f0b..ad2ef3a55 100644 --- a/test/benchmarks/media/BUILD +++ b/test/benchmarks/media/BUILD @@ -11,7 +11,6 @@ go_library( benchmark_test( name = "ffmpeg_test", - size = "enormous", srcs = ["ffmpeg_test.go"], library = ":media", visibility = ["//:sandbox"], diff --git a/test/benchmarks/ml/BUILD b/test/benchmarks/ml/BUILD index 3425b8dad..56a4d4f39 100644 --- a/test/benchmarks/ml/BUILD +++ b/test/benchmarks/ml/BUILD @@ -11,7 +11,6 @@ go_library( benchmark_test( name = "tensorflow_test", - size = "enormous", srcs = ["tensorflow_test.go"], library = ":ml", visibility = ["//:sandbox"], diff --git a/test/benchmarks/network/BUILD b/test/benchmarks/network/BUILD index 2741570f5..e047020bf 100644 --- a/test/benchmarks/network/BUILD +++ b/test/benchmarks/network/BUILD @@ -18,7 +18,6 @@ go_library( benchmark_test( name = "iperf_test", - size = "enormous", srcs = [ "iperf_test.go", ], @@ -34,7 +33,6 @@ benchmark_test( benchmark_test( name = "node_test", - size = "enormous", srcs = [ "node_test.go", ], @@ -49,7 +47,6 @@ benchmark_test( benchmark_test( name = "ruby_test", - size = "enormous", srcs = [ "ruby_test.go", ], @@ -64,7 +61,6 @@ benchmark_test( benchmark_test( name = "nginx_test", - size = "enormous", srcs = [ "nginx_test.go", ], @@ -79,7 +75,6 @@ benchmark_test( benchmark_test( name = "httpd_test", - size = "enormous", srcs = [ "httpd_test.go", ], diff --git a/test/e2e/BUILD b/test/e2e/BUILD index 29a84f184..1e9792b4f 100644 --- a/test/e2e/BUILD +++ b/test/e2e/BUILD @@ -8,13 +8,12 @@ go_test( srcs = [ "exec_test.go", "integration_test.go", - "regression_test.go", ], library = ":integration", tags = [ # Requires docker and runsc to be configured before the test runs. - "manual", "local", + "manual", ], visibility = ["//:sandbox"], deps = [ diff --git a/test/e2e/integration_test.go b/test/e2e/integration_test.go index 49cd74887..1accc3b3b 100644 --- a/test/e2e/integration_test.go +++ b/test/e2e/integration_test.go @@ -168,13 +168,6 @@ func TestCheckpointRestore(t *testing.T) { t.Skip("Pause/resume is not supported.") } - // TODO(gvisor.dev/issue/3373): Remove after implementing. - if usingVFS2, err := dockerutil.UsingVFS2(); usingVFS2 { - t.Skip("CheckpointRestore not implemented in VFS2.") - } else if err != nil { - t.Fatalf("failed to read config for runtime %s: %v", dockerutil.Runtime(), err) - } - ctx := context.Background() d := dockerutil.MakeContainer(ctx, t) defer d.CleanUp(ctx) @@ -399,15 +392,15 @@ func TestTmpFile(t *testing.T) { // TestTmpMount checks that mounts inside '/tmp' are not overridden. func TestTmpMount(t *testing.T) { - ctx := context.Background() dir, err := ioutil.TempDir(testutil.TmpDir(), "tmp-mount") if err != nil { t.Fatalf("TempDir(): %v", err) } - want := "123" + const want = "123" if err := ioutil.WriteFile(filepath.Join(dir, "file.txt"), []byte("123"), 0666); err != nil { t.Fatalf("WriteFile(): %v", err) } + ctx := context.Background() d := dockerutil.MakeContainer(ctx, t) defer d.CleanUp(ctx) @@ -430,6 +423,48 @@ func TestTmpMount(t *testing.T) { } } +// Test that it is allowed to mount a file on top of /dev files, e.g. +// /dev/random. +func TestMountOverDev(t *testing.T) { + if usingVFS2, err := dockerutil.UsingVFS2(); !usingVFS2 { + t.Skip("VFS1 doesn't allow /dev/random to be mounted.") + } else if err != nil { + t.Fatalf("Failed to read config for runtime %s: %v", dockerutil.Runtime(), err) + } + + random, err := ioutil.TempFile(testutil.TmpDir(), "random") + if err != nil { + t.Fatal("ioutil.TempFile() failed:", err) + } + const want = "123" + if _, err := random.WriteString(want); err != nil { + t.Fatalf("WriteString() to %q: %v", random.Name(), err) + } + + ctx := context.Background() + d := dockerutil.MakeContainer(ctx, t) + defer d.CleanUp(ctx) + + opts := dockerutil.RunOpts{ + Image: "basic/alpine", + Mounts: []mount.Mount{ + { + Type: mount.TypeBind, + Source: random.Name(), + Target: "/dev/random", + }, + }, + } + cmd := "dd count=1 bs=5 if=/dev/random 2> /dev/null" + got, err := d.Run(ctx, opts, "sh", "-c", cmd) + if err != nil { + t.Fatalf("docker run failed: %v", err) + } + if want != got { + t.Errorf("invalid file content, want: %q, got: %q", want, got) + } +} + // TestSyntheticDirs checks that submounts can be created inside a readonly // mount even if the target path does not exist. func TestSyntheticDirs(t *testing.T) { @@ -550,6 +585,30 @@ func runIntegrationTest(t *testing.T, capAdd []string, args ...string) { } } +// Test that UDS can be created using overlay when parent directory is in lower +// layer only (b/134090485). +// +// Prerequisite: the directory where the socket file is created must not have +// been open for write before bind(2) is called. +func TestBindOverlay(t *testing.T) { + ctx := context.Background() + d := dockerutil.MakeContainer(ctx, t) + defer d.CleanUp(ctx) + + // Run the container. + got, err := d.Run(ctx, dockerutil.RunOpts{ + Image: "basic/ubuntu", + }, "bash", "-c", "nc -q -1 -l -U /var/run/sock & p=$! && sleep 1 && echo foobar-asdf | nc -q 0 -U /var/run/sock && wait $p") + if err != nil { + t.Fatalf("docker run failed: %v", err) + } + + // Check the output contains what we want. + if want := "foobar-asdf"; !strings.Contains(got, want) { + t.Fatalf("docker run output is missing %q: %s", want, got) + } +} + func TestMain(m *testing.M) { dockerutil.EnsureSupportedDockerVersion() flag.Parse() diff --git a/test/e2e/regression_test.go b/test/e2e/regression_test.go deleted file mode 100644 index 84564cdaa..000000000 --- a/test/e2e/regression_test.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2019 The gVisor Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package integration - -import ( - "context" - "strings" - "testing" - - "gvisor.dev/gvisor/pkg/test/dockerutil" -) - -// Test that UDS can be created using overlay when parent directory is in lower -// layer only (b/134090485). -// -// Prerequisite: the directory where the socket file is created must not have -// been open for write before bind(2) is called. -func TestBindOverlay(t *testing.T) { - ctx := context.Background() - d := dockerutil.MakeContainer(ctx, t) - defer d.CleanUp(ctx) - - // Run the container. - got, err := d.Run(ctx, dockerutil.RunOpts{ - Image: "basic/ubuntu", - }, "bash", "-c", "nc -q -1 -l -U /var/run/sock & p=$! && sleep 1 && echo foobar-asdf | nc -q 0 -U /var/run/sock && wait $p") - if err != nil { - t.Fatalf("docker run failed: %v", err) - } - - // Check the output contains what we want. - if want := "foobar-asdf"; !strings.Contains(got, want) { - t.Fatalf("docker run output is missing %q: %s", want, got) - } -} diff --git a/test/fsstress/BUILD b/test/fsstress/BUILD index d262c8554..e74e7fff2 100644 --- a/test/fsstress/BUILD +++ b/test/fsstress/BUILD @@ -14,9 +14,7 @@ go_test( "manual", "local", ], - deps = [ - "//pkg/test/dockerutil", - ], + deps = ["//pkg/test/dockerutil"], ) go_library( diff --git a/test/fsstress/fsstress_test.go b/test/fsstress/fsstress_test.go index 300c21ceb..d53c8f90d 100644 --- a/test/fsstress/fsstress_test.go +++ b/test/fsstress/fsstress_test.go @@ -17,7 +17,9 @@ package fsstress import ( "context" + "flag" "math/rand" + "os" "strconv" "strings" "testing" @@ -30,33 +32,44 @@ func init() { rand.Seed(int64(time.Now().Nanosecond())) } -func fsstress(t *testing.T, dir string) { +func TestMain(m *testing.M) { + dockerutil.EnsureSupportedDockerVersion() + flag.Parse() + os.Exit(m.Run()) +} + +type config struct { + operations string + processes string + target string +} + +func fsstress(t *testing.T, conf config) { ctx := context.Background() d := dockerutil.MakeContainer(ctx, t) defer d.CleanUp(ctx) - const ( - operations = "10000" - processes = "100" - image = "basic/fsstress" - ) + const image = "basic/fsstress" seed := strconv.FormatUint(uint64(rand.Uint32()), 10) - args := []string{"-d", dir, "-n", operations, "-p", processes, "-s", seed, "-X"} - t.Logf("Repro: docker run --rm --runtime=runsc %s %s", image, strings.Join(args, "")) + args := []string{"-d", conf.target, "-n", conf.operations, "-p", conf.processes, "-s", seed, "-X"} + t.Logf("Repro: docker run --rm --runtime=%s gvisor.dev/images/%s %s", dockerutil.Runtime(), image, strings.Join(args, " ")) out, err := d.Run(ctx, dockerutil.RunOpts{Image: image}, args...) if err != nil { t.Fatalf("docker run failed: %v\noutput: %s", err, out) } - lines := strings.SplitN(out, "\n", 2) - if len(lines) > 1 || !strings.HasPrefix(out, "seed =") { + // This is to catch cases where fsstress spews out error messages during clean + // up but doesn't return error. + if len(out) > 0 { t.Fatalf("unexpected output: %s", out) } } -func TestFsstressGofer(t *testing.T) { - fsstress(t, "/test") -} - func TestFsstressTmpfs(t *testing.T) { - fsstress(t, "/tmp") + // This takes between 10s to run on my machine. Adjust as needed. + cfg := config{ + operations: "5000", + processes: "20", + target: "/tmp", + } + fsstress(t, cfg) } diff --git a/test/image/image_test.go b/test/image/image_test.go index 968e62f63..952264173 100644 --- a/test/image/image_test.go +++ b/test/image/image_test.go @@ -183,7 +183,10 @@ func TestMysql(t *testing.T) { // Start the container. if err := server.Spawn(ctx, dockerutil.RunOpts{ Image: "basic/mysql", - Env: []string{"MYSQL_ROOT_PASSWORD=foobar123"}, + Env: []string{ + "MYSQL_ROOT_PASSWORD=foobar123", + "MYSQL_ROOT_HOST=%", // Allow anyone to connect to the server. + }, }); err != nil { t.Fatalf("docker run failed: %v", err) } diff --git a/test/iptables/iptables_test.go b/test/iptables/iptables_test.go index d6c69a319..04d112134 100644 --- a/test/iptables/iptables_test.go +++ b/test/iptables/iptables_test.go @@ -456,3 +456,11 @@ func TestNATPreRECVORIGDSTADDR(t *testing.T) { func TestNATOutRECVORIGDSTADDR(t *testing.T) { singleTest(t, &NATOutRECVORIGDSTADDR{}) } + +func TestNATPostSNATUDP(t *testing.T) { + singleTest(t, &NATPostSNATUDP{}) +} + +func TestNATPostSNATTCP(t *testing.T) { + singleTest(t, &NATPostSNATTCP{}) +} diff --git a/test/iptables/iptables_util.go b/test/iptables/iptables_util.go index bba17b894..4590e169d 100644 --- a/test/iptables/iptables_util.go +++ b/test/iptables/iptables_util.go @@ -69,29 +69,41 @@ func tableRules(ipv6 bool, table string, argsList [][]string) error { return nil } -// listenUDP listens on a UDP port and returns the value of net.Conn.Read() for -// the first read on that port. +// listenUDP listens on a UDP port and returns nil if the first read from that +// port is successful. func listenUDP(ctx context.Context, port int, ipv6 bool) error { + _, err := listenUDPFrom(ctx, port, ipv6) + return err +} + +// listenUDPFrom listens on a UDP port and returns the sender's UDP address if +// the first read from that port is successful. +func listenUDPFrom(ctx context.Context, port int, ipv6 bool) (*net.UDPAddr, error) { localAddr := net.UDPAddr{ Port: port, } conn, err := net.ListenUDP(udpNetwork(ipv6), &localAddr) if err != nil { - return err + return nil, err } defer conn.Close() - ch := make(chan error) + type result struct { + remoteAddr *net.UDPAddr + err error + } + + ch := make(chan result) go func() { - _, err = conn.Read([]byte{0}) - ch <- err + _, remoteAddr, err := conn.ReadFromUDP([]byte{0}) + ch <- result{remoteAddr, err} }() select { - case err := <-ch: - return err + case res := <-ch: + return res.remoteAddr, res.err case <-ctx.Done(): - return ctx.Err() + return nil, fmt.Errorf("timed out reading from %s: %w", &localAddr, ctx.Err()) } } @@ -125,8 +137,16 @@ func sendUDPLoop(ctx context.Context, ip net.IP, port int, ipv6 bool) error { } } -// listenTCP listens for connections on a TCP port. +// listenTCP listens for connections on a TCP port, and returns nil if a +// connection is established. func listenTCP(ctx context.Context, port int, ipv6 bool) error { + _, err := listenTCPFrom(ctx, port, ipv6) + return err +} + +// listenTCP listens for connections on a TCP port, and returns the remote +// TCP address if a connection is established. +func listenTCPFrom(ctx context.Context, port int, ipv6 bool) (net.Addr, error) { localAddr := net.TCPAddr{ Port: port, } @@ -134,23 +154,32 @@ func listenTCP(ctx context.Context, port int, ipv6 bool) error { // Starts listening on port. lConn, err := net.ListenTCP(tcpNetwork(ipv6), &localAddr) if err != nil { - return err + return nil, err } defer lConn.Close() + type result struct { + remoteAddr net.Addr + err error + } + // Accept connections on port. - ch := make(chan error) + ch := make(chan result) go func() { conn, err := lConn.AcceptTCP() - ch <- err + var remoteAddr net.Addr + if err == nil { + remoteAddr = conn.RemoteAddr() + } + ch <- result{remoteAddr, err} conn.Close() }() select { - case err := <-ch: - return err + case res := <-ch: + return res.remoteAddr, res.err case <-ctx.Done(): - return fmt.Errorf("timed out waiting for a connection at %#v: %w", localAddr, ctx.Err()) + return nil, fmt.Errorf("timed out waiting for a connection at %s: %w", &localAddr, ctx.Err()) } } diff --git a/test/iptables/nat.go b/test/iptables/nat.go index 0776639a7..0f25b6a18 100644 --- a/test/iptables/nat.go +++ b/test/iptables/nat.go @@ -19,6 +19,7 @@ import ( "errors" "fmt" "net" + "strconv" "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/binary" @@ -48,6 +49,8 @@ func init() { RegisterTestCase(&NATOutOriginalDst{}) RegisterTestCase(&NATPreRECVORIGDSTADDR{}) RegisterTestCase(&NATOutRECVORIGDSTADDR{}) + RegisterTestCase(&NATPostSNATUDP{}) + RegisterTestCase(&NATPostSNATTCP{}) } // NATPreRedirectUDPPort tests that packets are redirected to different port. @@ -486,7 +489,12 @@ func (*NATLoopbackSkipsPrerouting) Name() string { // ContainerAction implements TestCase.ContainerAction. func (*NATLoopbackSkipsPrerouting) ContainerAction(ctx context.Context, ip net.IP, ipv6 bool) error { // Redirect anything sent to localhost to an unused port. - dest := []byte{127, 0, 0, 1} + var dest net.IP + if ipv6 { + dest = net.IPv6loopback + } else { + dest = net.IPv4(127, 0, 0, 1) + } if err := natTable(ipv6, "-A", "PREROUTING", "-p", "tcp", "-j", "REDIRECT", "--to-port", fmt.Sprintf("%d", dropPort)); err != nil { return err } @@ -915,3 +923,115 @@ func addrMatches6(got unix.RawSockaddrInet6, wantAddrs []net.IP, port uint16) er } return fmt.Errorf("got %+v, but wanted one of %+v (note: port numbers are in network byte order)", got, wantAddrs) } + +const ( + snatAddrV4 = "194.236.50.155" + snatAddrV6 = "2a0a::1" + snatPort = 43 +) + +// NATPostSNATUDP tests that the source port/IP in the packets are modified as expected. +type NATPostSNATUDP struct{ localCase } + +var _ TestCase = (*NATPostSNATUDP)(nil) + +// Name implements TestCase.Name. +func (*NATPostSNATUDP) Name() string { + return "NATPostSNATUDP" +} + +// ContainerAction implements TestCase.ContainerAction. +func (*NATPostSNATUDP) ContainerAction(ctx context.Context, ip net.IP, ipv6 bool) error { + var source string + if ipv6 { + source = fmt.Sprintf("[%s]:%d", snatAddrV6, snatPort) + } else { + source = fmt.Sprintf("%s:%d", snatAddrV4, snatPort) + } + + if err := natTable(ipv6, "-A", "POSTROUTING", "-p", "udp", "-j", "SNAT", "--to-source", source); err != nil { + return err + } + return sendUDPLoop(ctx, ip, acceptPort, ipv6) +} + +// LocalAction implements TestCase.LocalAction. +func (*NATPostSNATUDP) LocalAction(ctx context.Context, ip net.IP, ipv6 bool) error { + remote, err := listenUDPFrom(ctx, acceptPort, ipv6) + if err != nil { + return err + } + var snatAddr string + if ipv6 { + snatAddr = snatAddrV6 + } else { + snatAddr = snatAddrV4 + } + if got, want := remote.IP, net.ParseIP(snatAddr); !got.Equal(want) { + return fmt.Errorf("got remote address = %s, want = %s", got, want) + } + if got, want := remote.Port, snatPort; got != want { + return fmt.Errorf("got remote port = %d, want = %d", got, want) + } + return nil +} + +// NATPostSNATTCP tests that the source port/IP in the packets are modified as +// expected. +type NATPostSNATTCP struct{ localCase } + +var _ TestCase = (*NATPostSNATTCP)(nil) + +// Name implements TestCase.Name. +func (*NATPostSNATTCP) Name() string { + return "NATPostSNATTCP" +} + +// ContainerAction implements TestCase.ContainerAction. +func (*NATPostSNATTCP) ContainerAction(ctx context.Context, ip net.IP, ipv6 bool) error { + addrs, err := getInterfaceAddrs(ipv6) + if err != nil { + return err + } + var source string + for _, addr := range addrs { + if addr.To4() != nil { + if !ipv6 { + source = fmt.Sprintf("%s:%d", addr, snatPort) + } + } else if ipv6 && addr.IsGlobalUnicast() { + source = fmt.Sprintf("[%s]:%d", addr, snatPort) + } + } + if source == "" { + return fmt.Errorf("can't find any interface address to use") + } + + if err := natTable(ipv6, "-A", "POSTROUTING", "-p", "tcp", "-j", "SNAT", "--to-source", source); err != nil { + return err + } + return connectTCP(ctx, ip, acceptPort, ipv6) +} + +// LocalAction implements TestCase.LocalAction. +func (*NATPostSNATTCP) LocalAction(ctx context.Context, ip net.IP, ipv6 bool) error { + remote, err := listenTCPFrom(ctx, acceptPort, ipv6) + if err != nil { + return err + } + HostStr, portStr, err := net.SplitHostPort(remote.String()) + if err != nil { + return err + } + if got, want := HostStr, ip.String(); got != want { + return fmt.Errorf("got remote address = %s, want = %s", got, want) + } + port, err := strconv.ParseInt(portStr, 10, 0) + if err != nil { + return err + } + if got, want := int(port), snatPort; got != want { + return fmt.Errorf("got remote port = %d, want = %d", got, want) + } + return nil +} diff --git a/test/packetdrill/BUILD b/test/packetdrill/BUILD index 5d95516ee..de66cbe6d 100644 --- a/test/packetdrill/BUILD +++ b/test/packetdrill/BUILD @@ -41,6 +41,7 @@ packetdrill_test( test_suite( name = "all_tests", tags = [ + "local", "manual", "packetdrill", ], diff --git a/test/packetimpact/runner/defs.bzl b/test/packetimpact/runner/defs.bzl index 34e83ec49..634c15727 100644 --- a/test/packetimpact/runner/defs.bzl +++ b/test/packetimpact/runner/defs.bzl @@ -246,6 +246,12 @@ ALL_TESTS = [ expect_netstack_failure = True, ), PacketimpactTestInfo( + name = "tcp_listen_backlog", + ), + PacketimpactTestInfo( + name = "tcp_syncookie", + ), + PacketimpactTestInfo( name = "icmpv6_param_problem", ), PacketimpactTestInfo( diff --git a/test/packetimpact/runner/dut.go b/test/packetimpact/runner/dut.go index b271bd47e..4fb2f5c4b 100644 --- a/test/packetimpact/runner/dut.go +++ b/test/packetimpact/runner/dut.go @@ -369,30 +369,32 @@ func TestWithDUT(ctx context.Context, t *testing.T, mkDevice func(*dockerutil.Co "--dut_infos_json", string(dutInfosBytes), ) testbenchLogs, err := testbenchContainer.Exec(ctx, dockerutil.ExecOpts{}, testArgs...) - if (err != nil) != expectFailure { - var dutLogs string - for i, dut := range duts { - logs, err := dut.Logs(ctx) - if err != nil { - logs = fmt.Sprintf("failed to fetch DUT logs: %s", err) - } - dutLogs = fmt.Sprintf(`%s====== Begin of DUT-%d Logs ====== + var dutLogs string + for i, dut := range duts { + logs, err := dut.Logs(ctx) + if err != nil { + logs = fmt.Sprintf("failed to fetch DUT logs: %s", err) + } + dutLogs = fmt.Sprintf(`%s====== Begin of DUT-%d Logs ====== %s ====== End of DUT-%d Logs ====== `, dutLogs, i, logs, i) - } - - t.Errorf(`test error: %v, expect failure: %t - + } + testLogs := fmt.Sprintf(` %s====== Begin of Testbench Logs ====== %s -====== End of Testbench Logs ======`, - err, expectFailure, dutLogs, testbenchLogs) +====== End of Testbench Logs ======`, dutLogs, testbenchLogs) + if (err != nil) != expectFailure { + t.Errorf(`test error: %v, expect failure: %t +%s`, err, expectFailure, testLogs) + } else if expectFailure { + t.Logf(`test failed as expected: %v +%s`, err, testLogs) } } diff --git a/test/packetimpact/tests/BUILD b/test/packetimpact/tests/BUILD index 92103c1e9..e015c1f0e 100644 --- a/test/packetimpact/tests/BUILD +++ b/test/packetimpact/tests/BUILD @@ -385,6 +385,26 @@ packetimpact_testbench( ], ) +packetimpact_testbench( + name = "tcp_listen_backlog", + srcs = ["tcp_listen_backlog_test.go"], + deps = [ + "//pkg/tcpip/header", + "//test/packetimpact/testbench", + "@org_golang_x_sys//unix:go_default_library", + ], +) + +packetimpact_testbench( + name = "tcp_syncookie", + srcs = ["tcp_syncookie_test.go"], + deps = [ + "//pkg/tcpip/header", + "//test/packetimpact/testbench", + "@org_golang_x_sys//unix:go_default_library", + ], +) + validate_all_tests() [packetimpact_go_test( @@ -396,6 +416,7 @@ validate_all_tests() test_suite( name = "all_tests", tags = [ + "local", "manual", "packetimpact", ], diff --git a/test/packetimpact/tests/tcp_listen_backlog_test.go b/test/packetimpact/tests/tcp_listen_backlog_test.go new file mode 100644 index 000000000..26c812d0a --- /dev/null +++ b/test/packetimpact/tests/tcp_listen_backlog_test.go @@ -0,0 +1,86 @@ +// Copyright 2021 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tcp_listen_backlog_test + +import ( + "flag" + "testing" + "time" + + "golang.org/x/sys/unix" + "gvisor.dev/gvisor/pkg/tcpip/header" + "gvisor.dev/gvisor/test/packetimpact/testbench" +) + +func init() { + testbench.Initialize(flag.CommandLine) +} + +// TestTCPListenBacklog tests for a listening endpoint behavior: +// (1) reply to more SYNs than what is configured as listen backlog +// (2) ignore ACKs (that complete a handshake) when the accept queue is full +// (3) ignore incoming SYNs when the accept queue is full +func TestTCPListenBacklog(t *testing.T) { + dut := testbench.NewDUT(t) + + // Listening endpoint accepts one more connection than the listen backlog. + listenFd, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 0 /*backlog*/) + + var establishedConn testbench.TCPIPv4 + var incompleteConn testbench.TCPIPv4 + + // Test if the DUT listener replies to more SYNs than listen backlog+1 + for i, conn := range []*testbench.TCPIPv4{&establishedConn, &incompleteConn} { + *conn = dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + // Expect dut connection to have transitioned to SYN-RCVD state. + conn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagSyn)}) + if _, err := conn.ExpectData(t, &testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagSyn | header.TCPFlagAck)}, nil, time.Second); err != nil { + t.Fatalf("expected SYN-ACK for %d connection, %s", i, err) + } + } + defer establishedConn.Close(t) + defer incompleteConn.Close(t) + + // Send the ACK to complete handshake. + establishedConn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagAck)}) + dut.PollOne(t, listenFd, unix.POLLIN, time.Second) + + // Send the ACK to complete handshake, expect this to be ignored by the + // listener. + incompleteConn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagAck)}) + + // Drain the accept queue to enable poll for subsequent connections on the + // listener. + dut.Accept(t, listenFd) + + // The ACK for the incomplete connection should be ignored by the + // listening endpoint and the poll on listener should now time out. + if pfds := dut.Poll(t, []unix.PollFd{{Fd: listenFd, Events: unix.POLLIN}}, time.Second); len(pfds) != 0 { + t.Fatalf("got dut.Poll(...) = %#v", pfds) + } + + // Re-send the ACK to complete handshake and re-fill the accept-queue. + incompleteConn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagAck)}) + dut.PollOne(t, listenFd, unix.POLLIN, time.Second) + + // Now initiate a new connection when the accept queue is full. + connectingConn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + defer connectingConn.Close(t) + // Expect dut connection to drop the SYN and let the client stay in SYN_SENT state. + connectingConn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagSyn)}) + if got, err := connectingConn.ExpectData(t, &testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagSyn | header.TCPFlagAck)}, nil, time.Second); err == nil { + t.Fatalf("expected no SYN-ACK, but got %s", got) + } +} diff --git a/test/packetimpact/tests/tcp_syncookie_test.go b/test/packetimpact/tests/tcp_syncookie_test.go new file mode 100644 index 000000000..1c21c62ff --- /dev/null +++ b/test/packetimpact/tests/tcp_syncookie_test.go @@ -0,0 +1,70 @@ +// Copyright 2021 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tcp_syncookie_test + +import ( + "flag" + "testing" + "time" + + "golang.org/x/sys/unix" + "gvisor.dev/gvisor/pkg/tcpip/header" + "gvisor.dev/gvisor/test/packetimpact/testbench" +) + +func init() { + testbench.Initialize(flag.CommandLine) +} + +// TestSynCookie test if the DUT listener is replying back using syn cookies. +// The test does not complete the handshake by not sending the ACK to SYNACK. +// When syncookies are not used, this forces the listener to retransmit SYNACK. +// And when syncookies are being used, there is no such retransmit. +func TestTCPSynCookie(t *testing.T) { + dut := testbench.NewDUT(t) + + // Listening endpoint accepts one more connection than the listen backlog. + _, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1 /*backlog*/) + + var withoutSynCookieConn testbench.TCPIPv4 + var withSynCookieConn testbench.TCPIPv4 + + // Test if the DUT listener replies to more SYNs than listen backlog+1 + for _, conn := range []*testbench.TCPIPv4{&withoutSynCookieConn, &withSynCookieConn} { + *conn = dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + } + defer withoutSynCookieConn.Close(t) + defer withSynCookieConn.Close(t) + + checkSynAck := func(t *testing.T, conn *testbench.TCPIPv4, expectRetransmit bool) { + // Expect dut connection to have transitioned to SYN-RCVD state. + conn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagSyn)}) + if _, err := conn.ExpectData(t, &testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagSyn | header.TCPFlagAck)}, nil, time.Second); err != nil { + t.Fatalf("expected SYN-ACK, but got %s", err) + } + + // If the DUT listener is using syn cookies, it will not retransmit SYNACK + got, err := conn.ExpectData(t, &testbench.TCP{SeqNum: testbench.Uint32(uint32(*conn.RemoteSeqNum(t) - 1)), Flags: testbench.TCPFlags(header.TCPFlagSyn | header.TCPFlagAck)}, nil, 2*time.Second) + if expectRetransmit && err != nil { + t.Fatalf("expected retransmitted SYN-ACK, but got %s", err) + } + if !expectRetransmit && err == nil { + t.Fatalf("expected no retransmitted SYN-ACK, but got %s", got) + } + } + + t.Run("without syncookies", func(t *testing.T) { checkSynAck(t, &withoutSynCookieConn, true /*expectRetransmit*/) }) + t.Run("with syncookies", func(t *testing.T) { checkSynAck(t, &withSynCookieConn, false /*expectRetransmit*/) }) +} diff --git a/test/perf/BUILD b/test/perf/BUILD index ed899ac22..71982fc4d 100644 --- a/test/perf/BUILD +++ b/test/perf/BUILD @@ -35,7 +35,7 @@ syscall_test( ) syscall_test( - size = "enormous", + size = "large", debug = False, tags = ["nogotsan"], test = "//test/perf/linux:getdents_benchmark", @@ -48,7 +48,7 @@ syscall_test( ) syscall_test( - size = "enormous", + size = "large", debug = False, tags = ["nogotsan"], test = "//test/perf/linux:gettid_benchmark", @@ -106,7 +106,7 @@ syscall_test( ) syscall_test( - size = "enormous", + size = "large", debug = False, test = "//test/perf/linux:signal_benchmark", ) @@ -124,9 +124,10 @@ syscall_test( ) syscall_test( - size = "enormous", + size = "large", add_overlay = True, debug = False, + tags = ["nogotsan"], test = "//test/perf/linux:unlink_benchmark", ) diff --git a/test/perf/linux/getpid_benchmark.cc b/test/perf/linux/getpid_benchmark.cc index db74cb264..047a034bd 100644 --- a/test/perf/linux/getpid_benchmark.cc +++ b/test/perf/linux/getpid_benchmark.cc @@ -31,6 +31,24 @@ void BM_Getpid(benchmark::State& state) { BENCHMARK(BM_Getpid); +#ifdef __x86_64__ + +#define SYSNO_STR1(x) #x +#define SYSNO_STR(x) SYSNO_STR1(x) + +// BM_GetpidOpt uses the most often pattern of calling system calls: +// mov $SYS_XXX, %eax; syscall. +void BM_GetpidOpt(benchmark::State& state) { + for (auto s : state) { + __asm__("movl $" SYSNO_STR(SYS_getpid) ", %%eax\n" + "syscall\n" + : : : "rax", "rcx", "r11"); + } +} + +BENCHMARK(BM_GetpidOpt); +#endif // __x86_64__ + } // namespace } // namespace testing diff --git a/test/perf/linux/write_benchmark.cc b/test/perf/linux/write_benchmark.cc index 7b060c70e..d495f3ddc 100644 --- a/test/perf/linux/write_benchmark.cc +++ b/test/perf/linux/write_benchmark.cc @@ -46,6 +46,18 @@ void BM_Write(benchmark::State& state) { BENCHMARK(BM_Write)->Range(1, 1 << 26)->UseRealTime(); +void BM_Append(benchmark::State& state) { + auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + auto fd = ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_WRONLY | O_APPEND)); + + const char data = 'a'; + for (auto _ : state) { + TEST_CHECK(WriteFd(fd.get(), &data, 1) == 1); + } +} + +BENCHMARK(BM_Append); + } // namespace } // namespace testing diff --git a/test/runner/defs.bzl b/test/runner/defs.bzl index 829247657..2a0ef2cec 100644 --- a/test/runner/defs.bzl +++ b/test/runner/defs.bzl @@ -4,7 +4,7 @@ load("//tools:defs.bzl", "default_platform", "platforms") def _runner_test_impl(ctx): # Generate a runner binary. - runner = ctx.actions.declare_file("%s-runner" % ctx.label.name) + runner = ctx.actions.declare_file(ctx.label.name) runner_content = "\n".join([ "#!/bin/bash", "set -euf -x -o pipefail", @@ -85,18 +85,9 @@ def _syscall_test( # Add the full_platform and file access in a tag to make it easier to run # all the tests on a specific flavor. Use --test_tag_filters=ptrace,file_shared. + tags = list(tags) tags += [full_platform, "file_" + file_access] - # Hash this target into one of 15 buckets. This can be used to - # randomly split targets between different workflows. - hash15 = hash(native.package_name() + name) % 15 - tags.append("hash15:" + str(hash15)) - - # TODO(b/139838000): Tests using hostinet must be disabled on Guitar until - # we figure out how to request ipv4 sockets on Guitar machines. - if network == "host": - tags.append("noguitar") - # Disable off-host networking. tags.append("requires-net:loopback") tags.append("requires-net:ipv4") @@ -157,116 +148,82 @@ def syscall_test( if not tags: tags = [] - vfs2_tags = list(tags) - if vfs2: - # Add tag to easily run VFS2 tests with --test_tag_filters=vfs2 - vfs2_tags.append("vfs2") - if fuse: - vfs2_tags.append("fuse") - - else: - # Don't automatically run tests tests not yet passing. - vfs2_tags.append("manual") - vfs2_tags.append("noguitar") - vfs2_tags.append("notap") - - _syscall_test( - test = test, - platform = default_platform, - use_tmpfs = use_tmpfs, - add_uds_tree = add_uds_tree, - tags = platforms[default_platform] + vfs2_tags, - debug = debug, - vfs2 = True, - fuse = fuse, - **kwargs - ) - if fuse: - # Only generate *_vfs2_fuse target if fuse parameter is enabled. - return - - _syscall_test( - test = test, - platform = "native", - use_tmpfs = False, - add_uds_tree = add_uds_tree, - tags = list(tags), - debug = debug, - **kwargs - ) - - for (platform, platform_tags) in platforms.items(): + if vfs2 and not fuse: + # Generate a vfs1 plain test. Most testing will now be + # biased towards vfs2, with only a single vfs1 case. _syscall_test( test = test, - platform = platform, + platform = default_platform, use_tmpfs = use_tmpfs, add_uds_tree = add_uds_tree, - tags = platform_tags + tags, + tags = tags + platforms[default_platform], debug = debug, + vfs2 = False, **kwargs ) - if add_overlay: + if not fuse: + # Generate a native test if fuse is not required. _syscall_test( test = test, - platform = default_platform, - use_tmpfs = use_tmpfs, + platform = "native", + use_tmpfs = False, add_uds_tree = add_uds_tree, - tags = platforms[default_platform] + tags, + tags = tags, debug = debug, - overlay = True, **kwargs ) - # TODO(gvisor.dev/issue/4407): Remove tags to enable VFS2 overlay tests. - overlay_vfs2_tags = list(vfs2_tags) - overlay_vfs2_tags.append("manual") - overlay_vfs2_tags.append("noguitar") - overlay_vfs2_tags.append("notap") + for (platform, platform_tags) in platforms.items(): _syscall_test( test = test, - platform = default_platform, + platform = platform, use_tmpfs = use_tmpfs, add_uds_tree = add_uds_tree, - tags = platforms[default_platform] + overlay_vfs2_tags, + tags = platform_tags + tags, + fuse = fuse, + vfs2 = vfs2, debug = debug, - overlay = True, - vfs2 = True, **kwargs ) - if add_hostinet: + if add_overlay: _syscall_test( test = test, platform = default_platform, use_tmpfs = use_tmpfs, - network = "host", add_uds_tree = add_uds_tree, tags = platforms[default_platform] + tags, debug = debug, + fuse = fuse, + vfs2 = vfs2, + overlay = True, **kwargs ) - - if not use_tmpfs: - # Also test shared gofer access. + if add_hostinet: _syscall_test( test = test, platform = default_platform, use_tmpfs = use_tmpfs, + network = "host", add_uds_tree = add_uds_tree, tags = platforms[default_platform] + tags, debug = debug, - file_access = "shared", + fuse = fuse, + vfs2 = vfs2, **kwargs ) + if not use_tmpfs: + # Also test shared gofer access. _syscall_test( test = test, platform = default_platform, use_tmpfs = use_tmpfs, add_uds_tree = add_uds_tree, - tags = platforms[default_platform] + vfs2_tags, + tags = platforms[default_platform] + tags, debug = debug, file_access = "shared", - vfs2 = True, + fuse = fuse, + vfs2 = vfs2, **kwargs ) diff --git a/test/runner/runner.go b/test/runner/runner.go index a8a134fe2..d314a5036 100644 --- a/test/runner/runner.go +++ b/test/runner/runner.go @@ -252,6 +252,7 @@ func runRunsc(spec *specs.Spec) error { debugLogDir += "/" log.Infof("runsc logs: %s", debugLogDir) args = append(args, "-debug-log", debugLogDir) + args = append(args, "-coverage-report", debugLogDir) // Default -log sends messages to stderr which makes reading the test log // difficult. Instead, drop them when debug log is enabled given it's a diff --git a/test/runtimes/defs.bzl b/test/runtimes/defs.bzl index 702522d86..2550b61a3 100644 --- a/test/runtimes/defs.bzl +++ b/test/runtimes/defs.bzl @@ -75,7 +75,6 @@ def runtime_test(name, **kwargs): "local", "manual", ], - size = "enormous", **kwargs ) diff --git a/test/syscalls/BUILD b/test/syscalls/BUILD index ef299799e..affcae8fd 100644 --- a/test/syscalls/BUILD +++ b/test/syscalls/BUILD @@ -244,6 +244,10 @@ syscall_test( ) syscall_test( + test = "//test/syscalls/linux:verity_ioctl_test", +) + +syscall_test( test = "//test/syscalls/linux:iptables_test", ) @@ -318,6 +322,10 @@ syscall_test( ) syscall_test( + test = "//test/syscalls/linux:verity_mount_test", +) + +syscall_test( size = "medium", test = "//test/syscalls/linux:mremap_test", ) @@ -772,8 +780,7 @@ syscall_test( ) syscall_test( - # NOTE(b/116636318): Large sendmsg may stall a long time. - size = "enormous", + flaky = 1, # NOTE(b/116636318): Large sendmsg may stall a long time. shard_count = more_shards, test = "//test/syscalls/linux:socket_unix_dgram_local_test", ) @@ -791,8 +798,7 @@ syscall_test( ) syscall_test( - # NOTE(b/116636318): Large sendmsg may stall a long time. - size = "enormous", + flaky = 1, # NOTE(b/116636318): Large sendmsg may stall a long time. shard_count = more_shards, test = "//test/syscalls/linux:socket_unix_seqpacket_local_test", ) @@ -995,3 +1001,7 @@ syscall_test( syscall_test( test = "//test/syscalls/linux:processes_test", ) + +syscall_test( + test = "//test/syscalls/linux:cgroup_test", +) diff --git a/test/syscalls/linux/32bit.cc b/test/syscalls/linux/32bit.cc index 3c825477c..6080a59b7 100644 --- a/test/syscalls/linux/32bit.cc +++ b/test/syscalls/linux/32bit.cc @@ -22,15 +22,13 @@ #include "test/util/posix_error.h" #include "test/util/test_util.h" -#ifndef __x86_64__ -#error "This test is x86-64 specific." -#endif - namespace gvisor { namespace testing { namespace { +#ifdef __x86_64__ + constexpr char kInt3 = '\xcc'; constexpr char kInt80[2] = {'\xcd', '\x80'}; constexpr char kSyscall[2] = {'\x0f', '\x05'}; @@ -244,5 +242,7 @@ TEST(Call32Bit, Disallowed) { } // namespace +#endif + } // namespace testing } // namespace gvisor diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index 043ada583..55f3fc4ae 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -212,10 +212,7 @@ cc_binary( cc_binary( name = "32bit_test", testonly = 1, - srcs = select_arch( - amd64 = ["32bit.cc"], - arm64 = [], - ), + srcs = ["32bit.cc"], linkstatic = 1, deps = [ "@com_google_absl//absl/base:core_headers", @@ -1014,6 +1011,22 @@ cc_binary( ], ) +cc_binary( + name = "verity_ioctl_test", + testonly = 1, + srcs = ["verity_ioctl.cc"], + linkstatic = 1, + deps = [ + "//test/util:capability_util", + gtest, + "//test/util:fs_util", + "//test/util:mount_util", + "//test/util:temp_path", + "//test/util:test_main", + "//test/util:test_util", + ], +) + cc_library( name = "iptables_types", testonly = 1, @@ -1304,6 +1317,20 @@ cc_binary( ) cc_binary( + name = "verity_mount_test", + testonly = 1, + srcs = ["verity_mount.cc"], + linkstatic = 1, + deps = [ + gtest, + "//test/util:capability_util", + "//test/util:temp_path", + "//test/util:test_main", + "//test/util:test_util", + ], +) + +cc_binary( name = "mremap_test", testonly = 1, srcs = ["mremap.cc"], @@ -4205,3 +4232,24 @@ cc_binary( "//test/util:test_util", ], ) + +cc_binary( + name = "cgroup_test", + testonly = 1, + srcs = ["cgroup.cc"], + linkstatic = 1, + deps = [ + "//test/util:capability_util", + "//test/util:cgroup_util", + "//test/util:file_descriptor", + "//test/util:fs_util", + "@com_google_absl//absl/strings", + gtest, + "//test/util:posix_error", + "//test/util:temp_path", + "//test/util:test_main", + "//test/util:test_util", + "@com_google_absl//absl/container:flat_hash_map", + "@com_google_absl//absl/container:flat_hash_set", + ], +) diff --git a/test/syscalls/linux/accept_bind.cc b/test/syscalls/linux/accept_bind.cc index f65a14fb8..fe560cfc5 100644 --- a/test/syscalls/linux/accept_bind.cc +++ b/test/syscalls/linux/accept_bind.cc @@ -67,6 +67,42 @@ TEST_P(AllSocketPairTest, ListenDecreaseBacklog) { SyscallSucceeds()); } +TEST_P(AllSocketPairTest, ListenBacklogSizes) { + DisableSave ds; + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(), + sockets->first_addr_size()), + SyscallSucceeds()); + + int type; + socklen_t typelen = sizeof(type); + EXPECT_THAT( + getsockopt(sockets->first_fd(), SOL_SOCKET, SO_TYPE, &type, &typelen), + SyscallSucceeds()); + + std::array<int, 3> backlogs = {-1, 0, 1}; + for (auto& backlog : backlogs) { + ASSERT_THAT(listen(sockets->first_fd(), backlog), SyscallSucceeds()); + + int expected_accepts = backlog; + if (backlog < 0) { + expected_accepts = 1024; + } + for (int i = 0; i < expected_accepts; i++) { + SCOPED_TRACE(absl::StrCat("i=", i)); + // Connect to the listening socket. + const FileDescriptor client = + ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_UNIX, type, 0)); + ASSERT_THAT(connect(client.get(), sockets->first_addr(), + sockets->first_addr_size()), + SyscallSucceeds()); + const FileDescriptor accepted = ASSERT_NO_ERRNO_AND_VALUE( + Accept(sockets->first_fd(), nullptr, nullptr)); + } + } +} + TEST_P(AllSocketPairTest, ListenWithoutBind) { auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); ASSERT_THAT(listen(sockets->first_fd(), 0), SyscallFailsWithErrno(EINVAL)); @@ -285,8 +321,7 @@ TEST_P(AllSocketPairTest, AcceptValidAddrLen) { struct sockaddr_un addr = {}; socklen_t addr_len = sizeof(addr); ASSERT_THAT( - accepted = accept(sockets->first_fd(), - reinterpret_cast<struct sockaddr*>(&addr), &addr_len), + accepted = accept(sockets->first_fd(), AsSockAddr(&addr), &addr_len), SyscallSucceeds()); ASSERT_THAT(close(accepted), SyscallSucceeds()); } @@ -307,8 +342,7 @@ TEST_P(AllSocketPairTest, AcceptNegativeAddrLen) { // With a negative addr_len, accept returns EINVAL, struct sockaddr_un addr = {}; socklen_t addr_len = -1; - ASSERT_THAT(accept(sockets->first_fd(), - reinterpret_cast<struct sockaddr*>(&addr), &addr_len), + ASSERT_THAT(accept(sockets->first_fd(), AsSockAddr(&addr), &addr_len), SyscallFailsWithErrno(EINVAL)); } @@ -499,10 +533,9 @@ TEST_P(AllSocketPairTest, UnboundSenderAddr) { struct sockaddr_storage addr; socklen_t addr_len = sizeof(addr); - ASSERT_THAT( - RetryEINTR(recvfrom)(accepted_fd.get(), &i, sizeof(i), 0, - reinterpret_cast<sockaddr*>(&addr), &addr_len), - SyscallSucceedsWithValue(sizeof(i))); + ASSERT_THAT(RetryEINTR(recvfrom)(accepted_fd.get(), &i, sizeof(i), 0, + AsSockAddr(&addr), &addr_len), + SyscallSucceedsWithValue(sizeof(i))); EXPECT_EQ(addr_len, 0); } @@ -534,10 +567,9 @@ TEST_P(AllSocketPairTest, BoundSenderAddr) { struct sockaddr_storage addr; socklen_t addr_len = sizeof(addr); - ASSERT_THAT( - RetryEINTR(recvfrom)(accepted_fd.get(), &i, sizeof(i), 0, - reinterpret_cast<sockaddr*>(&addr), &addr_len), - SyscallSucceedsWithValue(sizeof(i))); + ASSERT_THAT(RetryEINTR(recvfrom)(accepted_fd.get(), &i, sizeof(i), 0, + AsSockAddr(&addr), &addr_len), + SyscallSucceedsWithValue(sizeof(i))); EXPECT_EQ(addr_len, sockets->second_addr_len()); EXPECT_EQ( memcmp(&addr, sockets->second_addr(), @@ -573,10 +605,9 @@ TEST_P(AllSocketPairTest, BindAfterConnectSenderAddr) { struct sockaddr_storage addr; socklen_t addr_len = sizeof(addr); - ASSERT_THAT( - RetryEINTR(recvfrom)(accepted_fd.get(), &i, sizeof(i), 0, - reinterpret_cast<sockaddr*>(&addr), &addr_len), - SyscallSucceedsWithValue(sizeof(i))); + ASSERT_THAT(RetryEINTR(recvfrom)(accepted_fd.get(), &i, sizeof(i), 0, + AsSockAddr(&addr), &addr_len), + SyscallSucceedsWithValue(sizeof(i))); EXPECT_EQ(addr_len, sockets->second_addr_len()); EXPECT_EQ( memcmp(&addr, sockets->second_addr(), @@ -612,10 +643,9 @@ TEST_P(AllSocketPairTest, BindAfterAcceptSenderAddr) { struct sockaddr_storage addr; socklen_t addr_len = sizeof(addr); - ASSERT_THAT( - RetryEINTR(recvfrom)(accepted_fd.get(), &i, sizeof(i), 0, - reinterpret_cast<sockaddr*>(&addr), &addr_len), - SyscallSucceedsWithValue(sizeof(i))); + ASSERT_THAT(RetryEINTR(recvfrom)(accepted_fd.get(), &i, sizeof(i), 0, + AsSockAddr(&addr), &addr_len), + SyscallSucceedsWithValue(sizeof(i))); EXPECT_EQ(addr_len, sockets->second_addr_len()); EXPECT_EQ( memcmp(&addr, sockets->second_addr(), diff --git a/test/syscalls/linux/alarm.cc b/test/syscalls/linux/alarm.cc index 940c97285..cd0704334 100644 --- a/test/syscalls/linux/alarm.cc +++ b/test/syscalls/linux/alarm.cc @@ -36,7 +36,7 @@ void do_nothing_handler(int sig, siginfo_t* siginfo, void* arg) {} // No random save as the test relies on alarm timing. Cooperative save tests // already cover the save between alarm and read. -TEST(AlarmTest, Interrupt_NoRandomSave) { +TEST(AlarmTest, Interrupt) { int pipe_fds[2]; ASSERT_THAT(pipe(pipe_fds), SyscallSucceeds()); @@ -71,7 +71,7 @@ void inc_alarms_handler(int sig, siginfo_t* siginfo, void* arg) { // No random save as the test relies on alarm timing. Cooperative save tests // already cover the save between alarm and read. -TEST(AlarmTest, Restart_NoRandomSave) { +TEST(AlarmTest, Restart) { alarms_received = 0; int pipe_fds[2]; @@ -114,7 +114,7 @@ TEST(AlarmTest, Restart_NoRandomSave) { // No random save as the test relies on alarm timing. Cooperative save tests // already cover the save between alarm and pause. -TEST(AlarmTest, SaSiginfo_NoRandomSave) { +TEST(AlarmTest, SaSiginfo) { // Use a signal handler that interrupts but does nothing rather than using the // default terminate action. struct sigaction sa; @@ -134,7 +134,7 @@ TEST(AlarmTest, SaSiginfo_NoRandomSave) { // No random save as the test relies on alarm timing. Cooperative save tests // already cover the save between alarm and pause. -TEST(AlarmTest, SaInterrupt_NoRandomSave) { +TEST(AlarmTest, SaInterrupt) { // Use a signal handler that interrupts but does nothing rather than using the // default terminate action. struct sigaction sa; diff --git a/test/syscalls/linux/cgroup.cc b/test/syscalls/linux/cgroup.cc new file mode 100644 index 000000000..a1006a978 --- /dev/null +++ b/test/syscalls/linux/cgroup.cc @@ -0,0 +1,421 @@ +// Copyright 2021 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// All tests in this file rely on being about to mount and unmount cgroupfs, +// which isn't expected to work, or be safe on a general linux system. + +#include <sys/mount.h> +#include <unistd.h> + +#include "gtest/gtest.h" +#include "absl/container/flat_hash_map.h" +#include "absl/container/flat_hash_set.h" +#include "absl/strings/str_split.h" +#include "test/util/capability_util.h" +#include "test/util/cgroup_util.h" +#include "test/util/temp_path.h" +#include "test/util/test_util.h" + +namespace gvisor { +namespace testing { +namespace { + +using ::testing::_; +using ::testing::Ge; +using ::testing::Gt; + +std::vector<std::string> known_controllers = {"cpu", "cpuset", "cpuacct", + "memory"}; + +bool CgroupsAvailable() { + return IsRunningOnGvisor() && !IsRunningWithVFS1() && + TEST_CHECK_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN)); +} + +TEST(Cgroup, MountSucceeds) { + SKIP_IF(!CgroupsAvailable()); + + Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir())); + Cgroup c = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("")); + EXPECT_NO_ERRNO(c.ContainsCallingProcess()); +} + +TEST(Cgroup, SeparateMounts) { + SKIP_IF(!CgroupsAvailable()); + + Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir())); + + for (const auto& ctl : known_controllers) { + Cgroup c = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs(ctl)); + EXPECT_NO_ERRNO(c.ContainsCallingProcess()); + } +} + +TEST(Cgroup, AllControllersImplicit) { + SKIP_IF(!CgroupsAvailable()); + + Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir())); + Cgroup c = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("")); + + absl::flat_hash_map<std::string, CgroupsEntry> cgroups_entries = + ASSERT_NO_ERRNO_AND_VALUE(ProcCgroupsEntries()); + for (const auto& ctl : known_controllers) { + EXPECT_TRUE(cgroups_entries.contains(ctl)) + << absl::StreamFormat("ctl=%s", ctl); + } + EXPECT_EQ(cgroups_entries.size(), known_controllers.size()); +} + +TEST(Cgroup, AllControllersExplicit) { + SKIP_IF(!CgroupsAvailable()); + + Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir())); + Cgroup c = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("all")); + + absl::flat_hash_map<std::string, CgroupsEntry> cgroups_entries = + ASSERT_NO_ERRNO_AND_VALUE(ProcCgroupsEntries()); + for (const auto& ctl : known_controllers) { + EXPECT_TRUE(cgroups_entries.contains(ctl)) + << absl::StreamFormat("ctl=%s", ctl); + } + EXPECT_EQ(cgroups_entries.size(), known_controllers.size()); +} + +TEST(Cgroup, ProcsAndTasks) { + SKIP_IF(!CgroupsAvailable()); + + Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir())); + Cgroup c = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("")); + absl::flat_hash_set<pid_t> pids = ASSERT_NO_ERRNO_AND_VALUE(c.Procs()); + absl::flat_hash_set<pid_t> tids = ASSERT_NO_ERRNO_AND_VALUE(c.Tasks()); + + EXPECT_GE(tids.size(), pids.size()) << "Found more processes than threads"; + + // Pids should be a strict subset of tids. + for (auto it = pids.begin(); it != pids.end(); ++it) { + EXPECT_TRUE(tids.contains(*it)) + << absl::StreamFormat("Have pid %d, but no such tid", *it); + } +} + +TEST(Cgroup, ControllersMustBeInUniqueHierarchy) { + SKIP_IF(!CgroupsAvailable()); + + Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir())); + // Hierarchy #1: all controllers. + Cgroup all = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("")); + // Hierarchy #2: memory. + // + // This should conflict since memory is already in hierarchy #1, and the two + // hierarchies have different sets of controllers, so this mount can't be a + // view into hierarchy #1. + EXPECT_THAT(m.MountCgroupfs("memory"), PosixErrorIs(EBUSY, _)) + << "Memory controller mounted on two hierarchies"; + EXPECT_THAT(m.MountCgroupfs("cpu"), PosixErrorIs(EBUSY, _)) + << "CPU controller mounted on two hierarchies"; +} + +TEST(Cgroup, UnmountFreesControllers) { + SKIP_IF(!CgroupsAvailable()); + Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir())); + Cgroup all = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("")); + // All controllers are now attached to all's hierarchy. Attempting new mount + // with any individual controller should fail. + EXPECT_THAT(m.MountCgroupfs("memory"), PosixErrorIs(EBUSY, _)) + << "Memory controller mounted on two hierarchies"; + + // Unmount the "all" hierarchy. This should enable any controller to be + // mounted on a new hierarchy again. + ASSERT_NO_ERRNO(m.Unmount(all)); + EXPECT_NO_ERRNO(m.MountCgroupfs("memory")); + EXPECT_NO_ERRNO(m.MountCgroupfs("cpu")); +} + +TEST(Cgroup, OnlyContainsControllerSpecificFiles) { + SKIP_IF(!CgroupsAvailable()); + Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir())); + Cgroup mem = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("memory")); + EXPECT_THAT(Exists(mem.Relpath("memory.usage_in_bytes")), + IsPosixErrorOkAndHolds(true)); + // CPU files shouldn't exist in memory cgroups. + EXPECT_THAT(Exists(mem.Relpath("cpu.cfs_period_us")), + IsPosixErrorOkAndHolds(false)); + EXPECT_THAT(Exists(mem.Relpath("cpu.cfs_quota_us")), + IsPosixErrorOkAndHolds(false)); + EXPECT_THAT(Exists(mem.Relpath("cpu.shares")), IsPosixErrorOkAndHolds(false)); + + Cgroup cpu = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("cpu")); + EXPECT_THAT(Exists(cpu.Relpath("cpu.cfs_period_us")), + IsPosixErrorOkAndHolds(true)); + EXPECT_THAT(Exists(cpu.Relpath("cpu.cfs_quota_us")), + IsPosixErrorOkAndHolds(true)); + EXPECT_THAT(Exists(cpu.Relpath("cpu.shares")), IsPosixErrorOkAndHolds(true)); + // Memory files shouldn't exist in cpu cgroups. + EXPECT_THAT(Exists(cpu.Relpath("memory.usage_in_bytes")), + IsPosixErrorOkAndHolds(false)); +} + +TEST(Cgroup, InvalidController) { + SKIP_IF(!CgroupsAvailable()); + + TempPath mountpoint = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); + std::string mopts = "this-controller-is-invalid"; + EXPECT_THAT( + mount("none", mountpoint.path().c_str(), "cgroup", 0, mopts.c_str()), + SyscallFailsWithErrno(EINVAL)); +} + +TEST(Cgroup, MoptAllMustBeExclusive) { + SKIP_IF(!CgroupsAvailable()); + + TempPath mountpoint = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); + std::string mopts = "all,cpu"; + EXPECT_THAT( + mount("none", mountpoint.path().c_str(), "cgroup", 0, mopts.c_str()), + SyscallFailsWithErrno(EINVAL)); +} + +TEST(MemoryCgroup, MemoryUsageInBytes) { + SKIP_IF(!CgroupsAvailable()); + + Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir())); + Cgroup c = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("memory")); + EXPECT_THAT(c.ReadIntegerControlFile("memory.usage_in_bytes"), + IsPosixErrorOkAndHolds(Gt(0))); +} + +TEST(CPUCgroup, ControlFilesHaveDefaultValues) { + SKIP_IF(!CgroupsAvailable()); + + Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir())); + Cgroup c = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("cpu")); + EXPECT_THAT(c.ReadIntegerControlFile("cpu.cfs_quota_us"), + IsPosixErrorOkAndHolds(-1)); + EXPECT_THAT(c.ReadIntegerControlFile("cpu.cfs_period_us"), + IsPosixErrorOkAndHolds(100000)); + EXPECT_THAT(c.ReadIntegerControlFile("cpu.shares"), + IsPosixErrorOkAndHolds(1024)); +} + +TEST(CPUAcctCgroup, CPUAcctUsage) { + SKIP_IF(!CgroupsAvailable()); + + Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir())); + Cgroup c = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("cpuacct")); + + const int64_t usage = + ASSERT_NO_ERRNO_AND_VALUE(c.ReadIntegerControlFile("cpuacct.usage")); + const int64_t usage_user = + ASSERT_NO_ERRNO_AND_VALUE(c.ReadIntegerControlFile("cpuacct.usage_user")); + const int64_t usage_sys = + ASSERT_NO_ERRNO_AND_VALUE(c.ReadIntegerControlFile("cpuacct.usage_sys")); + + EXPECT_GE(usage, 0); + EXPECT_GE(usage_user, 0); + EXPECT_GE(usage_sys, 0); + + EXPECT_GE(usage_user + usage_sys, usage); +} + +TEST(CPUAcctCgroup, CPUAcctStat) { + SKIP_IF(!CgroupsAvailable()); + + Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir())); + Cgroup c = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("cpuacct")); + + std::string stat = + ASSERT_NO_ERRNO_AND_VALUE(c.ReadControlFile("cpuacct.stat")); + + // We're expecting the contents of "cpuacct.stat" to look similar to this: + // + // user 377986 + // system 220662 + + std::vector<absl::string_view> lines = + absl::StrSplit(stat, '\n', absl::SkipEmpty()); + ASSERT_EQ(lines.size(), 2); + + std::vector<absl::string_view> user_tokens = + StrSplit(lines[0], absl::ByChar(' ')); + EXPECT_EQ(user_tokens[0], "user"); + EXPECT_THAT(Atoi<int64_t>(user_tokens[1]), IsPosixErrorOkAndHolds(Ge(0))); + + std::vector<absl::string_view> sys_tokens = + StrSplit(lines[1], absl::ByChar(' ')); + EXPECT_EQ(sys_tokens[0], "system"); + EXPECT_THAT(Atoi<int64_t>(sys_tokens[1]), IsPosixErrorOkAndHolds(Ge(0))); +} + +TEST(ProcCgroups, Empty) { + SKIP_IF(!CgroupsAvailable()); + + absl::flat_hash_map<std::string, CgroupsEntry> entries = + ASSERT_NO_ERRNO_AND_VALUE(ProcCgroupsEntries()); + // No cgroups mounted yet, we should have no entries. + EXPECT_TRUE(entries.empty()); +} + +TEST(ProcCgroups, ProcCgroupsEntries) { + SKIP_IF(!CgroupsAvailable()); + + Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir())); + + Cgroup mem = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("memory")); + absl::flat_hash_map<std::string, CgroupsEntry> entries = + ASSERT_NO_ERRNO_AND_VALUE(ProcCgroupsEntries()); + EXPECT_EQ(entries.size(), 1); + ASSERT_TRUE(entries.contains("memory")); + CgroupsEntry mem_e = entries["memory"]; + EXPECT_EQ(mem_e.subsys_name, "memory"); + EXPECT_GE(mem_e.hierarchy, 1); + // Expect a single root cgroup. + EXPECT_EQ(mem_e.num_cgroups, 1); + // Cgroups are currently always enabled when mounted. + EXPECT_TRUE(mem_e.enabled); + + // Add a second cgroup, and check for new entry. + + Cgroup cpu = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("cpu")); + entries = ASSERT_NO_ERRNO_AND_VALUE(ProcCgroupsEntries()); + EXPECT_EQ(entries.size(), 2); + EXPECT_TRUE(entries.contains("memory")); // Still have memory entry. + ASSERT_TRUE(entries.contains("cpu")); + CgroupsEntry cpu_e = entries["cpu"]; + EXPECT_EQ(cpu_e.subsys_name, "cpu"); + EXPECT_GE(cpu_e.hierarchy, 1); + EXPECT_EQ(cpu_e.num_cgroups, 1); + EXPECT_TRUE(cpu_e.enabled); + + // Separate hierarchies, since controllers were mounted separately. + EXPECT_NE(mem_e.hierarchy, cpu_e.hierarchy); +} + +TEST(ProcCgroups, UnmountRemovesEntries) { + SKIP_IF(!CgroupsAvailable()); + + Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir())); + Cgroup cg = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("cpu,memory")); + absl::flat_hash_map<std::string, CgroupsEntry> entries = + ASSERT_NO_ERRNO_AND_VALUE(ProcCgroupsEntries()); + EXPECT_EQ(entries.size(), 2); + + ASSERT_NO_ERRNO(m.Unmount(cg)); + + entries = ASSERT_NO_ERRNO_AND_VALUE(ProcCgroupsEntries()); + EXPECT_TRUE(entries.empty()); +} + +TEST(ProcPIDCgroup, Empty) { + SKIP_IF(!CgroupsAvailable()); + + absl::flat_hash_map<std::string, PIDCgroupEntry> entries = + ASSERT_NO_ERRNO_AND_VALUE(ProcPIDCgroupEntries(getpid())); + EXPECT_TRUE(entries.empty()); +} + +TEST(ProcPIDCgroup, Entries) { + SKIP_IF(!CgroupsAvailable()); + + Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir())); + Cgroup c = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("memory")); + + absl::flat_hash_map<std::string, PIDCgroupEntry> entries = + ASSERT_NO_ERRNO_AND_VALUE(ProcPIDCgroupEntries(getpid())); + EXPECT_EQ(entries.size(), 1); + PIDCgroupEntry mem_e = entries["memory"]; + EXPECT_GE(mem_e.hierarchy, 1); + EXPECT_EQ(mem_e.controllers, "memory"); + EXPECT_EQ(mem_e.path, "/"); + + Cgroup c1 = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("cpu")); + entries = ASSERT_NO_ERRNO_AND_VALUE(ProcPIDCgroupEntries(getpid())); + EXPECT_EQ(entries.size(), 2); + EXPECT_TRUE(entries.contains("memory")); // Still have memory entry. + PIDCgroupEntry cpu_e = entries["cpu"]; + EXPECT_GE(cpu_e.hierarchy, 1); + EXPECT_EQ(cpu_e.controllers, "cpu"); + EXPECT_EQ(cpu_e.path, "/"); + + // Separate hierarchies, since controllers were mounted separately. + EXPECT_NE(mem_e.hierarchy, cpu_e.hierarchy); +} + +TEST(ProcPIDCgroup, UnmountRemovesEntries) { + SKIP_IF(!CgroupsAvailable()); + + Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir())); + Cgroup all = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("")); + + absl::flat_hash_map<std::string, PIDCgroupEntry> entries = + ASSERT_NO_ERRNO_AND_VALUE(ProcPIDCgroupEntries(getpid())); + EXPECT_GT(entries.size(), 0); + + ASSERT_NO_ERRNO(m.Unmount(all)); + + entries = ASSERT_NO_ERRNO_AND_VALUE(ProcPIDCgroupEntries(getpid())); + EXPECT_TRUE(entries.empty()); +} + +TEST(ProcCgroup, PIDCgroupMatchesCgroups) { + SKIP_IF(!CgroupsAvailable()); + + Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir())); + Cgroup c = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("memory")); + Cgroup c1 = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("cpu")); + + absl::flat_hash_map<std::string, CgroupsEntry> cgroups_entries = + ASSERT_NO_ERRNO_AND_VALUE(ProcCgroupsEntries()); + absl::flat_hash_map<std::string, PIDCgroupEntry> pid_entries = + ASSERT_NO_ERRNO_AND_VALUE(ProcPIDCgroupEntries(getpid())); + + CgroupsEntry cgroup_mem = cgroups_entries["memory"]; + PIDCgroupEntry pid_mem = pid_entries["memory"]; + + EXPECT_EQ(cgroup_mem.hierarchy, pid_mem.hierarchy); + + CgroupsEntry cgroup_cpu = cgroups_entries["cpu"]; + PIDCgroupEntry pid_cpu = pid_entries["cpu"]; + + EXPECT_EQ(cgroup_cpu.hierarchy, pid_cpu.hierarchy); + EXPECT_NE(cgroup_mem.hierarchy, cgroup_cpu.hierarchy); + EXPECT_NE(pid_mem.hierarchy, pid_cpu.hierarchy); +} + +TEST(ProcCgroup, MultiControllerHierarchy) { + SKIP_IF(!CgroupsAvailable()); + + Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir())); + Cgroup c = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("memory,cpu")); + + absl::flat_hash_map<std::string, CgroupsEntry> cgroups_entries = + ASSERT_NO_ERRNO_AND_VALUE(ProcCgroupsEntries()); + + CgroupsEntry mem_e = cgroups_entries["memory"]; + CgroupsEntry cpu_e = cgroups_entries["cpu"]; + + // Both controllers should have the same hierarchy ID. + EXPECT_EQ(mem_e.hierarchy, cpu_e.hierarchy); + + absl::flat_hash_map<std::string, PIDCgroupEntry> pid_entries = + ASSERT_NO_ERRNO_AND_VALUE(ProcPIDCgroupEntries(getpid())); + + // Expecting an entry listing both controllers, that matches the previous + // hierarchy ID. Note that the controllers are listed in alphabetical order. + PIDCgroupEntry pid_e = pid_entries["cpu,memory"]; + EXPECT_EQ(pid_e.hierarchy, mem_e.hierarchy); +} + +} // namespace +} // namespace testing +} // namespace gvisor diff --git a/test/syscalls/linux/chmod.cc b/test/syscalls/linux/chmod.cc index 8233df0f8..4a5ea84d4 100644 --- a/test/syscalls/linux/chmod.cc +++ b/test/syscalls/linux/chmod.cc @@ -53,7 +53,7 @@ TEST(ChmodTest, ChmodDirSucceeds) { EXPECT_THAT(open(fileInDir.c_str(), O_RDONLY), SyscallFailsWithErrno(EACCES)); } -TEST(ChmodTest, FchmodFileSucceeds_NoRandomSave) { +TEST(ChmodTest, FchmodFileSucceeds) { // Drop capabilities that allow us to file directory permissions. ASSERT_NO_ERRNO(SetCapability(CAP_DAC_OVERRIDE, false)); @@ -70,7 +70,7 @@ TEST(ChmodTest, FchmodFileSucceeds_NoRandomSave) { EXPECT_THAT(open(file.path().c_str(), O_RDWR), SyscallFailsWithErrno(EACCES)); } -TEST(ChmodTest, FchmodDirSucceeds_NoRandomSave) { +TEST(ChmodTest, FchmodDirSucceeds) { // Drop capabilities that allow us to override file and directory permissions. ASSERT_NO_ERRNO(SetCapability(CAP_DAC_OVERRIDE, false)); ASSERT_NO_ERRNO(SetCapability(CAP_DAC_READ_SEARCH, false)); @@ -212,7 +212,7 @@ TEST(ChmodTest, FchmodatDir) { SyscallFailsWithErrno(EACCES)); } -TEST(ChmodTest, ChmodDowngradeWritability_NoRandomSave) { +TEST(ChmodTest, ChmodDowngradeWritability) { auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileMode(0666)); int fd; @@ -238,7 +238,7 @@ TEST(ChmodTest, ChmodFileToNoPermissionsSucceeds) { SyscallFailsWithErrno(EACCES)); } -TEST(ChmodTest, FchmodDowngradeWritability_NoRandomSave) { +TEST(ChmodTest, FchmodDowngradeWritability) { auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); int fd; @@ -252,7 +252,7 @@ TEST(ChmodTest, FchmodDowngradeWritability_NoRandomSave) { EXPECT_THAT(close(fd), SyscallSucceeds()); } -TEST(ChmodTest, FchmodFileToNoPermissionsSucceeds_NoRandomSave) { +TEST(ChmodTest, FchmodFileToNoPermissionsSucceeds) { // Drop capabilities that allow us to override file permissions. ASSERT_NO_ERRNO(SetCapability(CAP_DAC_OVERRIDE, false)); ASSERT_NO_ERRNO(SetCapability(CAP_DAC_READ_SEARCH, false)); diff --git a/test/syscalls/linux/dev.cc b/test/syscalls/linux/dev.cc index 1d0d584cd..32860aa21 100644 --- a/test/syscalls/linux/dev.cc +++ b/test/syscalls/linux/dev.cc @@ -117,7 +117,7 @@ TEST(DevTest, ReadDevNull) { } // Do not allow random save as it could lead to partial reads. -TEST(DevTest, ReadDevZero_NoRandomSave) { +TEST(DevTest, ReadDevZero) { const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/zero", O_RDONLY)); diff --git a/test/syscalls/linux/epoll.cc b/test/syscalls/linux/epoll.cc index 8a72ef10a..b180f633c 100644 --- a/test/syscalls/linux/epoll.cc +++ b/test/syscalls/linux/epoll.cc @@ -115,7 +115,7 @@ TEST(EpollTest, LastNonWritable) { } } -TEST(EpollTest, Timeout_NoRandomSave) { +TEST(EpollTest, Timeout) { auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD()); std::vector<FileDescriptor> eventfds; for (int i = 0; i < kFDsPerEpoll; i++) { @@ -290,7 +290,7 @@ TEST(EpollTest, Oneshot) { SyscallSucceedsWithValue(0)); } -TEST(EpollTest, EdgeTriggered_NoRandomSave) { +TEST(EpollTest, EdgeTriggered) { // Test edge-triggered entry: make it edge-triggered, first wait should // return it, second one should time out, make it writable again, third wait // should return it, fourth wait should timeout. diff --git a/test/syscalls/linux/eventfd.cc b/test/syscalls/linux/eventfd.cc index dc794415e..8202d35fa 100644 --- a/test/syscalls/linux/eventfd.cc +++ b/test/syscalls/linux/eventfd.cc @@ -175,7 +175,7 @@ TEST(EventfdTest, SpliceFromPipePartialSucceeds) { } // NotifyNonZero is inherently racy, so random save is disabled. -TEST(EventfdTest, NotifyNonZero_NoRandomSave) { +TEST(EventfdTest, NotifyNonZero) { // Waits will time out at 10 seconds. constexpr int kEpollTimeoutMs = 10000; // Create an eventfd descriptor. diff --git a/test/syscalls/linux/flock.cc b/test/syscalls/linux/flock.cc index b286e84fe..fd387aa45 100644 --- a/test/syscalls/linux/flock.cc +++ b/test/syscalls/linux/flock.cc @@ -205,7 +205,7 @@ TEST_F(FlockTest, TestSharedLockFailExclusiveHolderNonblocking) { void trivial_handler(int signum) {} -TEST_F(FlockTest, TestSharedLockFailExclusiveHolderBlocking_NoRandomSave) { +TEST_F(FlockTest, TestSharedLockFailExclusiveHolderBlocking) { const DisableSave ds; // Timing-related. // This test will verify that a shared lock is denied while @@ -262,7 +262,7 @@ TEST_F(FlockTest, TestExclusiveLockFailExclusiveHolderNonblocking) { ASSERT_THAT(flock(test_file_fd_.get(), LOCK_UN), SyscallSucceedsWithValue(0)); } -TEST_F(FlockTest, TestExclusiveLockFailExclusiveHolderBlocking_NoRandomSave) { +TEST_F(FlockTest, TestExclusiveLockFailExclusiveHolderBlocking) { const DisableSave ds; // Timing-related. // This test will verify that an exclusive lock is denied while @@ -499,7 +499,7 @@ TEST_F(FlockTest, TestDupFdFollowedByLock) { // NOTE: These blocking tests are not perfect. Unfortunately it's very hard to // determine if a thread was actually blocked in the kernel so we're forced // to use timing. -TEST_F(FlockTest, BlockingLockNoBlockingForSharedLocks_NoRandomSave) { +TEST_F(FlockTest, BlockingLockNoBlockingForSharedLocks) { // This test will verify that although LOCK_NB isn't specified // two different fds can obtain shared locks without blocking. ASSERT_THAT(flock(test_file_fd_.get(), LOCK_SH), SyscallSucceeds()); @@ -539,7 +539,7 @@ TEST_F(FlockTest, BlockingLockNoBlockingForSharedLocks_NoRandomSave) { EXPECT_THAT(flock(test_file_fd_.get(), LOCK_UN), SyscallSucceeds()); } -TEST_F(FlockTest, BlockingLockFirstSharedSecondExclusive_NoRandomSave) { +TEST_F(FlockTest, BlockingLockFirstSharedSecondExclusive) { // This test will verify that if someone holds a shared lock any attempt to // obtain an exclusive lock will result in blocking. ASSERT_THAT(flock(test_file_fd_.get(), LOCK_SH), SyscallSucceeds()); @@ -576,7 +576,7 @@ TEST_F(FlockTest, BlockingLockFirstSharedSecondExclusive_NoRandomSave) { EXPECT_THAT(flock(test_file_fd_.get(), LOCK_UN), SyscallSucceeds()); } -TEST_F(FlockTest, BlockingLockFirstExclusiveSecondShared_NoRandomSave) { +TEST_F(FlockTest, BlockingLockFirstExclusiveSecondShared) { // This test will verify that if someone holds an exclusive lock any attempt // to obtain a shared lock will result in blocking. ASSERT_THAT(flock(test_file_fd_.get(), LOCK_EX), SyscallSucceeds()); @@ -613,7 +613,7 @@ TEST_F(FlockTest, BlockingLockFirstExclusiveSecondShared_NoRandomSave) { EXPECT_THAT(flock(test_file_fd_.get(), LOCK_UN), SyscallSucceeds()); } -TEST_F(FlockTest, BlockingLockFirstExclusiveSecondExclusive_NoRandomSave) { +TEST_F(FlockTest, BlockingLockFirstExclusiveSecondExclusive) { // This test will verify that if someone holds an exclusive lock any attempt // to obtain another exclusive lock will result in blocking. ASSERT_THAT(flock(test_file_fd_.get(), LOCK_EX), SyscallSucceeds()); diff --git a/test/syscalls/linux/fpsig_fork.cc b/test/syscalls/linux/fpsig_fork.cc index c47567b4e..79b0596c4 100644 --- a/test/syscalls/linux/fpsig_fork.cc +++ b/test/syscalls/linux/fpsig_fork.cc @@ -44,6 +44,8 @@ namespace { #define SET_FP0(var) SET_FPREG(var, d0) #endif +#define DEFAULT_MXCSR 0x1f80 + int parent, child; void sigusr1(int s, siginfo_t* siginfo, void* _uc) { @@ -57,6 +59,12 @@ void sigusr1(int s, siginfo_t* siginfo, void* _uc) { uint64_t got; GET_FP0(got); TEST_CHECK_MSG(val == got, "Basic FP check failed in sigusr1()"); + +#ifdef __x86_64 + uint32_t mxcsr; + __asm__("STMXCSR %0" : "=m"(mxcsr)); + TEST_CHECK_MSG(mxcsr == DEFAULT_MXCSR, "Unexpected mxcsr"); +#endif } TEST(FPSigTest, Fork) { @@ -125,6 +133,55 @@ TEST(FPSigTest, Fork) { } } +#ifdef __x86_64__ +TEST(FPSigTest, ForkWithZeroMxcsr) { + parent = getpid(); + pid_t parent_tid = gettid(); + + struct sigaction sa = {}; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sigusr1; + ASSERT_THAT(sigaction(SIGUSR1, &sa, nullptr), SyscallSucceeds()); + + // The control bits of the MXCSR register are callee-saved (preserved across + // calls), while the status bits are caller-saved (not preserved). + uint32_t expected = 0, origin; + __asm__("STMXCSR %0" : "=m"(origin)); + __asm__("LDMXCSR %0" : : "m"(expected)); + + asm volatile( + "movl %[killnr], %%eax;" + "movl %[parent], %%edi;" + "movl %[tid], %%esi;" + "movl %[sig], %%edx;" + "syscall;" + : + : [killnr] "i"(__NR_tgkill), [parent] "rm"(parent), + [tid] "rm"(parent_tid), [sig] "i"(SIGUSR1) + : "rax", "rdi", "rsi", "rdx", + // Clobbered by syscall. + "rcx", "r11"); + + uint32_t got; + __asm__("STMXCSR %0" : "=m"(got)); + __asm__("LDMXCSR %0" : : "m"(origin)); + + if (getpid() == parent) { // Parent. + int status; + ASSERT_THAT(waitpid(child, &status, 0), SyscallSucceedsWithValue(child)); + EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0); + } + + // TEST_CHECK_MSG since this may run in the child. + TEST_CHECK_MSG(expected == got, "Bad mxcsr value"); + + if (getpid() != parent) { // Child. + _exit(0); + } +} +#endif + } // namespace } // namespace testing diff --git a/test/syscalls/linux/futex.cc b/test/syscalls/linux/futex.cc index 90b1f0508..859f92b75 100644 --- a/test/syscalls/linux/futex.cc +++ b/test/syscalls/linux/futex.cc @@ -220,7 +220,7 @@ TEST_P(PrivateAndSharedFutexTest, Wait_ZeroBitset) { SyscallFailsWithErrno(EINVAL)); } -TEST_P(PrivateAndSharedFutexTest, Wake1_NoRandomSave) { +TEST_P(PrivateAndSharedFutexTest, Wake1) { constexpr int kInitialValue = 1; std::atomic<int> a = ATOMIC_VAR_INIT(kInitialValue); @@ -240,7 +240,7 @@ TEST_P(PrivateAndSharedFutexTest, Wake1_NoRandomSave) { EXPECT_THAT(futex_wake(IsPrivate(), &a, 1), SyscallSucceedsWithValue(1)); } -TEST_P(PrivateAndSharedFutexTest, Wake0_NoRandomSave) { +TEST_P(PrivateAndSharedFutexTest, Wake0) { constexpr int kInitialValue = 1; std::atomic<int> a = ATOMIC_VAR_INIT(kInitialValue); @@ -261,7 +261,7 @@ TEST_P(PrivateAndSharedFutexTest, Wake0_NoRandomSave) { EXPECT_THAT(futex_wake(IsPrivate(), &a, 0), SyscallSucceedsWithValue(1)); } -TEST_P(PrivateAndSharedFutexTest, WakeAll_NoRandomSave) { +TEST_P(PrivateAndSharedFutexTest, WakeAll) { constexpr int kInitialValue = 1; std::atomic<int> a = ATOMIC_VAR_INIT(kInitialValue); @@ -282,7 +282,7 @@ TEST_P(PrivateAndSharedFutexTest, WakeAll_NoRandomSave) { SyscallSucceedsWithValue(kThreads)); } -TEST_P(PrivateAndSharedFutexTest, WakeSome_NoRandomSave) { +TEST_P(PrivateAndSharedFutexTest, WakeSome) { constexpr int kInitialValue = 1; std::atomic<int> a = ATOMIC_VAR_INIT(kInitialValue); @@ -331,7 +331,7 @@ TEST_P(PrivateAndSharedFutexTest, WakeSome_NoRandomSave) { EXPECT_EQ(timedout, kThreads - kWokenThreads); } -TEST_P(PrivateAndSharedFutexTest, WaitBitset_Wake_NoRandomSave) { +TEST_P(PrivateAndSharedFutexTest, WaitBitset_Wake) { constexpr int kInitialValue = 1; std::atomic<int> a = ATOMIC_VAR_INIT(kInitialValue); @@ -346,7 +346,7 @@ TEST_P(PrivateAndSharedFutexTest, WaitBitset_Wake_NoRandomSave) { EXPECT_THAT(futex_wake(IsPrivate(), &a, 1), SyscallSucceedsWithValue(1)); } -TEST_P(PrivateAndSharedFutexTest, Wait_WakeBitset_NoRandomSave) { +TEST_P(PrivateAndSharedFutexTest, Wait_WakeBitset) { constexpr int kInitialValue = 1; std::atomic<int> a = ATOMIC_VAR_INIT(kInitialValue); @@ -361,7 +361,7 @@ TEST_P(PrivateAndSharedFutexTest, Wait_WakeBitset_NoRandomSave) { SyscallSucceedsWithValue(1)); } -TEST_P(PrivateAndSharedFutexTest, WaitBitset_WakeBitsetMatch_NoRandomSave) { +TEST_P(PrivateAndSharedFutexTest, WaitBitset_WakeBitsetMatch) { constexpr int kInitialValue = 1; std::atomic<int> a = ATOMIC_VAR_INIT(kInitialValue); @@ -379,7 +379,7 @@ TEST_P(PrivateAndSharedFutexTest, WaitBitset_WakeBitsetMatch_NoRandomSave) { SyscallSucceedsWithValue(1)); } -TEST_P(PrivateAndSharedFutexTest, WaitBitset_WakeBitsetNoMatch_NoRandomSave) { +TEST_P(PrivateAndSharedFutexTest, WaitBitset_WakeBitsetNoMatch) { constexpr int kInitialValue = 1; std::atomic<int> a = ATOMIC_VAR_INIT(kInitialValue); @@ -401,7 +401,7 @@ TEST_P(PrivateAndSharedFutexTest, WaitBitset_WakeBitsetNoMatch_NoRandomSave) { SyscallSucceedsWithValue(0)); } -TEST_P(PrivateAndSharedFutexTest, WakeOpCondSuccess_NoRandomSave) { +TEST_P(PrivateAndSharedFutexTest, WakeOpCondSuccess) { constexpr int kInitialValue = 1; std::atomic<int> a = ATOMIC_VAR_INIT(kInitialValue); std::atomic<int> b = ATOMIC_VAR_INIT(kInitialValue); @@ -428,7 +428,7 @@ TEST_P(PrivateAndSharedFutexTest, WakeOpCondSuccess_NoRandomSave) { EXPECT_EQ(b, kInitialValue + 2); } -TEST_P(PrivateAndSharedFutexTest, WakeOpCondFailure_NoRandomSave) { +TEST_P(PrivateAndSharedFutexTest, WakeOpCondFailure) { constexpr int kInitialValue = 1; std::atomic<int> a = ATOMIC_VAR_INIT(kInitialValue); std::atomic<int> b = ATOMIC_VAR_INIT(kInitialValue); @@ -457,7 +457,7 @@ TEST_P(PrivateAndSharedFutexTest, WakeOpCondFailure_NoRandomSave) { EXPECT_EQ(b, kInitialValue + 2); } -TEST_P(PrivateAndSharedFutexTest, NoWakeInterprocessPrivateAnon_NoRandomSave) { +TEST_P(PrivateAndSharedFutexTest, NoWakeInterprocessPrivateAnon) { auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); auto const ptr = static_cast<std::atomic<int>*>(mapping.ptr()); @@ -484,7 +484,7 @@ TEST_P(PrivateAndSharedFutexTest, NoWakeInterprocessPrivateAnon_NoRandomSave) { << " status " << status; } -TEST_P(PrivateAndSharedFutexTest, WakeAfterCOWBreak_NoRandomSave) { +TEST_P(PrivateAndSharedFutexTest, WakeAfterCOWBreak) { // Use a futex on a non-stack mapping so we can be sure that the child process // below isn't the one that breaks copy-on-write. auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( @@ -520,7 +520,7 @@ TEST_P(PrivateAndSharedFutexTest, WakeAfterCOWBreak_NoRandomSave) { EXPECT_THAT(futex_wake(IsPrivate(), ptr, 1), SyscallSucceedsWithValue(1)); } -TEST_P(PrivateAndSharedFutexTest, WakeWrongKind_NoRandomSave) { +TEST_P(PrivateAndSharedFutexTest, WakeWrongKind) { constexpr int kInitialValue = 1; std::atomic<int> a = ATOMIC_VAR_INIT(kInitialValue); @@ -584,7 +584,7 @@ TEST(PrivateFutexTest, WakeOp0Xor) { EXPECT_EQ(a, 0b0110); } -TEST(SharedFutexTest, WakeInterprocessSharedAnon_NoRandomSave) { +TEST(SharedFutexTest, WakeInterprocessSharedAnon) { auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_SHARED)); auto const ptr = static_cast<std::atomic<int>*>(mapping.ptr()); @@ -615,7 +615,7 @@ TEST(SharedFutexTest, WakeInterprocessSharedAnon_NoRandomSave) { << " status " << status; } -TEST(SharedFutexTest, WakeInterprocessFile_NoRandomSave) { +TEST(SharedFutexTest, WakeInterprocessFile) { auto const file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); ASSERT_THAT(truncate(file.path().c_str(), kPageSize), SyscallSucceeds()); auto const fd = ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR)); @@ -661,7 +661,7 @@ TEST_P(PrivateAndSharedFutexTest, PIBasic) { EXPECT_THAT(futex_unlock_pi(IsPrivate(), &a), SyscallFailsWithErrno(EPERM)); } -TEST_P(PrivateAndSharedFutexTest, PIConcurrency_NoRandomSave) { +TEST_P(PrivateAndSharedFutexTest, PIConcurrency) { DisableSave ds; // Too many syscalls. std::atomic<int> a = ATOMIC_VAR_INIT(0); @@ -717,7 +717,7 @@ TEST_P(PrivateAndSharedFutexTest, PITryLock) { ASSERT_THAT(futex_unlock_pi(IsPrivate(), &a), SyscallSucceeds()); } -TEST_P(PrivateAndSharedFutexTest, PITryLockConcurrency_NoRandomSave) { +TEST_P(PrivateAndSharedFutexTest, PITryLockConcurrency) { DisableSave ds; // Too many syscalls. std::atomic<int> a = ATOMIC_VAR_INIT(0); diff --git a/test/syscalls/linux/inotify.cc b/test/syscalls/linux/inotify.cc index a88c89e20..f6b78989b 100644 --- a/test/syscalls/linux/inotify.cc +++ b/test/syscalls/linux/inotify.cc @@ -1156,7 +1156,7 @@ TEST(Inotify, ZeroLengthReadWriteDoesNotGenerateEvent) { EXPECT_TRUE(events.empty()); } -TEST(Inotify, ChmodGeneratesAttribEvent_NoRandomSave) { +TEST(Inotify, ChmodGeneratesAttribEvent) { const TempPath root = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); const TempPath file1 = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileIn(root.path())); @@ -1999,7 +1999,7 @@ TEST(Inotify, Exec) { // // We need to disable S/R because there are filesystems where we cannot re-open // fds to an unlinked file across S/R, e.g. gofer-backed filesytems. -TEST(Inotify, IncludeUnlinkedFile_NoRandomSave) { +TEST(Inotify, IncludeUnlinkedFile) { const DisableSave ds; const TempPath dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); @@ -2052,7 +2052,7 @@ TEST(Inotify, IncludeUnlinkedFile_NoRandomSave) { // // We need to disable S/R because there are filesystems where we cannot re-open // fds to an unlinked file across S/R, e.g. gofer-backed filesytems. -TEST(Inotify, ExcludeUnlink_NoRandomSave) { +TEST(Inotify, ExcludeUnlink) { const DisableSave ds; // TODO(gvisor.dev/issue/1624): This test fails on VFS1. SKIP_IF(IsRunningWithVFS1()); @@ -2093,7 +2093,7 @@ TEST(Inotify, ExcludeUnlink_NoRandomSave) { // We need to disable S/R because there are filesystems where we cannot re-open // fds to an unlinked file across S/R, e.g. gofer-backed filesytems. -TEST(Inotify, ExcludeUnlinkDirectory_NoRandomSave) { +TEST(Inotify, ExcludeUnlinkDirectory) { // TODO(gvisor.dev/issue/1624): This test fails on VFS1. Remove once VFS1 is // deleted. SKIP_IF(IsRunningWithVFS1()); @@ -2138,7 +2138,7 @@ TEST(Inotify, ExcludeUnlinkDirectory_NoRandomSave) { // // We need to disable S/R because there are filesystems where we cannot re-open // fds to an unlinked file across S/R, e.g. gofer-backed filesytems. -TEST(Inotify, ExcludeUnlinkMultipleChildren_NoRandomSave) { +TEST(Inotify, ExcludeUnlinkMultipleChildren) { // Inotify does not work properly with hard links in gofer and overlay fs. SKIP_IF(IsRunningOnGvisor() && !ASSERT_NO_ERRNO_AND_VALUE(IsTmpfs(GetAbsoluteTestTmpdir()))); @@ -2184,7 +2184,7 @@ TEST(Inotify, ExcludeUnlinkMultipleChildren_NoRandomSave) { // // We need to disable S/R because there are filesystems where we cannot re-open // fds to an unlinked file across S/R, e.g. gofer-backed filesytems. -TEST(Inotify, ExcludeUnlinkInodeEvents_NoRandomSave) { +TEST(Inotify, ExcludeUnlinkInodeEvents) { // TODO(gvisor.dev/issue/1624): Fails on VFS1. SKIP_IF(IsRunningWithVFS1()); @@ -2284,7 +2284,7 @@ TEST(Inotify, OneShot) { // This test helps verify that the lock order of filesystem and inotify locks // is respected when inotify instances and watch targets are concurrently being // destroyed. -TEST(InotifyTest, InotifyAndTargetDestructionDoNotDeadlock_NoRandomSave) { +TEST(InotifyTest, InotifyAndTargetDestructionDoNotDeadlock) { const DisableSave ds; // Too many syscalls. // A file descriptor protected by a mutex. This ensures that while a @@ -2350,7 +2350,7 @@ TEST(InotifyTest, InotifyAndTargetDestructionDoNotDeadlock_NoRandomSave) { // This test helps verify that the lock order of filesystem and inotify locks // is respected when adding/removing watches occurs concurrently with the // removal of their targets. -TEST(InotifyTest, AddRemoveUnlinkDoNotDeadlock_NoRandomSave) { +TEST(InotifyTest, AddRemoveUnlinkDoNotDeadlock) { const DisableSave ds; // Too many syscalls. // Set up inotify instances. @@ -2405,7 +2405,7 @@ TEST(InotifyTest, AddRemoveUnlinkDoNotDeadlock_NoRandomSave) { // This test helps verify that the lock order of filesystem and inotify locks // is respected when many inotify events and filesystem operations occur // simultaneously. -TEST(InotifyTest, NotifyNoDeadlock_NoRandomSave) { +TEST(InotifyTest, NotifyNoDeadlock) { const DisableSave ds; // Too many syscalls. const TempPath parent = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); diff --git a/test/syscalls/linux/itimer.cc b/test/syscalls/linux/itimer.cc index e397d5f57..ac113e6da 100644 --- a/test/syscalls/linux/itimer.cc +++ b/test/syscalls/linux/itimer.cc @@ -215,7 +215,7 @@ int TestSIGALRMToMainThread() { // Random save/restore is disabled as it introduces additional latency and // unpredictable distribution patterns. -TEST(ItimerTest, DeliversSIGALRMToMainThread_NoRandomSave) { +TEST(ItimerTest, DeliversSIGALRMToMainThread) { pid_t child; int execve_errno; auto kill = ASSERT_NO_ERRNO_AND_VALUE( @@ -266,7 +266,7 @@ int TestSIGPROFFairness(absl::Duration sleep) { // Random save/restore is disabled as it introduces additional latency and // unpredictable distribution patterns. -TEST(ItimerTest, DeliversSIGPROFToThreadsRoughlyFairlyActive_NoRandomSave) { +TEST(ItimerTest, DeliversSIGPROFToThreadsRoughlyFairlyActive) { // On the KVM and ptrace platforms, switches between sentry and application // context are sometimes extremely slow, causing the itimer to send SIGPROF to // a thread that either already has one pending or has had SIGPROF delivered, @@ -301,7 +301,7 @@ TEST(ItimerTest, DeliversSIGPROFToThreadsRoughlyFairlyActive_NoRandomSave) { // Random save/restore is disabled as it introduces additional latency and // unpredictable distribution patterns. -TEST(ItimerTest, DeliversSIGPROFToThreadsRoughlyFairlyIdle_NoRandomSave) { +TEST(ItimerTest, DeliversSIGPROFToThreadsRoughlyFairlyIdle) { // See comment in DeliversSIGPROFToThreadsRoughlyFairlyActive. const auto gvisor_platform = GvisorPlatform(); SKIP_IF(gvisor_platform == Platform::kKVM || diff --git a/test/syscalls/linux/open.cc b/test/syscalls/linux/open.cc index e65ffee8f..4697c404c 100644 --- a/test/syscalls/linux/open.cc +++ b/test/syscalls/linux/open.cc @@ -431,7 +431,7 @@ TEST_F(OpenTest, CanTruncateReadOnly) { // If we don't have read permission on the file, opening with // O_TRUNC should fail. -TEST_F(OpenTest, CanTruncateReadOnlyNoWritePermission_NoRandomSave) { +TEST_F(OpenTest, CanTruncateReadOnlyNoWritePermission) { // Drop capabilities that allow us to override file permissions. ASSERT_NO_ERRNO(SetCapability(CAP_DAC_OVERRIDE, false)); @@ -452,7 +452,7 @@ TEST_F(OpenTest, CanTruncateReadOnlyNoWritePermission_NoRandomSave) { // If we don't have read permission but have write permission, opening O_WRONLY // and O_TRUNC should succeed. -TEST_F(OpenTest, CanTruncateWriteOnlyNoReadPermission_NoRandomSave) { +TEST_F(OpenTest, CanTruncateWriteOnlyNoReadPermission) { const DisableSave ds; // Permissions are dropped. EXPECT_THAT(fchmod(test_file_fd_.get(), S_IWUSR | S_IWGRP), diff --git a/test/syscalls/linux/open_create.cc b/test/syscalls/linux/open_create.cc index 46f41de50..43d446926 100644 --- a/test/syscalls/linux/open_create.cc +++ b/test/syscalls/linux/open_create.cc @@ -52,7 +52,7 @@ TEST(CreateTest, CreateAtFile) { EXPECT_THAT(close(fd), SyscallSucceeds()); } -TEST(CreateTest, HonorsUmask_NoRandomSave) { +TEST(CreateTest, HonorsUmask) { const DisableSave ds; // file cannot be re-opened as writable. auto dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); TempUmask mask(0222); @@ -119,7 +119,7 @@ TEST(CreateTest, OpenCreateROThenRW) { EXPECT_THAT(WriteFd(fd2.get(), &c, 1), SyscallSucceedsWithValue(1)); } -TEST(CreateTest, ChmodReadToWriteBetweenOpens_NoRandomSave) { +TEST(CreateTest, ChmodReadToWriteBetweenOpens) { // Make sure we don't have CAP_DAC_OVERRIDE, since that allows the user to // override file read/write permissions. CAP_DAC_READ_SEARCH needs to be // cleared for the same reason. @@ -149,7 +149,7 @@ TEST(CreateTest, ChmodReadToWriteBetweenOpens_NoRandomSave) { EXPECT_EQ(c, 'x'); } -TEST(CreateTest, ChmodWriteToReadBetweenOpens_NoRandomSave) { +TEST(CreateTest, ChmodWriteToReadBetweenOpens) { // Make sure we don't have CAP_DAC_OVERRIDE, since that allows the user to // override file read/write permissions. ASSERT_NO_ERRNO(SetCapability(CAP_DAC_OVERRIDE, false)); @@ -177,7 +177,7 @@ TEST(CreateTest, ChmodWriteToReadBetweenOpens_NoRandomSave) { EXPECT_EQ(c, 'x'); } -TEST(CreateTest, CreateWithReadFlagNotAllowedByMode_NoRandomSave) { +TEST(CreateTest, CreateWithReadFlagNotAllowedByMode) { // The only time we can open a file with flags forbidden by its permissions // is when we are creating the file. We cannot re-open with the same flags, // so we cannot restore an fd obtained from such an operation. @@ -204,7 +204,7 @@ TEST(CreateTest, CreateWithReadFlagNotAllowedByMode_NoRandomSave) { EXPECT_EQ(c, 'x'); } -TEST(CreateTest, CreateWithWriteFlagNotAllowedByMode_NoRandomSave) { +TEST(CreateTest, CreateWithWriteFlagNotAllowedByMode) { // The only time we can open a file with flags forbidden by its permissions // is when we are creating the file. We cannot re-open with the same flags, // so we cannot restore an fd obtained from such an operation. diff --git a/test/syscalls/linux/packet_socket_raw.cc b/test/syscalls/linux/packet_socket_raw.cc index d25be0e30..72080a272 100644 --- a/test/syscalls/linux/packet_socket_raw.cc +++ b/test/syscalls/linux/packet_socket_raw.cc @@ -440,11 +440,7 @@ TEST_P(RawPacketTest, SetSocketRecvBuf) { ASSERT_THAT(getsockopt(s_, SOL_SOCKET, SO_RCVBUF, &val, &val_len), SyscallSucceeds()); - // Linux doubles the value set by SO_SNDBUF/SO_RCVBUF. - // TODO(gvisor.dev/issue/2926): Remove when Netstack matches linux behavior. - if (!IsRunningOnGvisor()) { - quarter_sz *= 2; - } + quarter_sz *= 2; ASSERT_EQ(quarter_sz, val); } diff --git a/test/syscalls/linux/partial_bad_buffer.cc b/test/syscalls/linux/partial_bad_buffer.cc index 13afa0eaf..223ddc0c8 100644 --- a/test/syscalls/linux/partial_bad_buffer.cc +++ b/test/syscalls/linux/partial_bad_buffer.cc @@ -320,7 +320,7 @@ PosixErrorOr<sockaddr_storage> InetLoopbackAddr(int family) { // EFAULT. It also verifies that passing a buffer which is made up of 2 // pages one valid and one guard page succeeds as long as the write is // for exactly the size of 1 page. -TEST_F(PartialBadBufferTest, SendMsgTCP_NoRandomSave) { +TEST_F(PartialBadBufferTest, SendMsgTCP) { // FIXME(b/171436815): Netstack save/restore is broken. const DisableSave ds; diff --git a/test/syscalls/linux/ping_socket.cc b/test/syscalls/linux/ping_socket.cc index 999c8ab6b..8b78e4b16 100644 --- a/test/syscalls/linux/ping_socket.cc +++ b/test/syscalls/linux/ping_socket.cc @@ -35,7 +35,7 @@ namespace { // // We disable both random/cooperative S/R for this test as it makes way too many // syscalls. -TEST(PingSocket, ICMPPortExhaustion_NoRandomSave) { +TEST(PingSocket, ICMPPortExhaustion) { DisableSave ds; { diff --git a/test/syscalls/linux/pipe.cc b/test/syscalls/linux/pipe.cc index 01ccbdcd2..96c454485 100644 --- a/test/syscalls/linux/pipe.cc +++ b/test/syscalls/linux/pipe.cc @@ -399,7 +399,7 @@ TEST_P(PipeTest, BlockPartialWriteClosed) { t.Join(); } -TEST_P(PipeTest, ReadFromClosedFd_NoRandomSave) { +TEST_P(PipeTest, ReadFromClosedFd) { SKIP_IF(!CreateBlocking()); absl::Notification notify; diff --git a/test/syscalls/linux/poll.cc b/test/syscalls/linux/poll.cc index 6f9a9498c..5ce7e8c8d 100644 --- a/test/syscalls/linux/poll.cc +++ b/test/syscalls/linux/poll.cc @@ -57,7 +57,7 @@ TEST_F(PollTest, ZeroTimeout) { // If random S/R interrupts the poll, SIGALRM may be delivered before poll // restarts, causing the poll to hang forever. -TEST_F(PollTest, NegativeTimeout_NoRandomSave) { +TEST_F(PollTest, NegativeTimeout) { // Negative timeout mean wait forever so set a timer. SetTimer(absl::Milliseconds(100)); EXPECT_THAT(poll(nullptr, 0, -1), SyscallFailsWithErrno(EINTR)); diff --git a/test/syscalls/linux/ppoll.cc b/test/syscalls/linux/ppoll.cc index 8245a11e8..7f7d69731 100644 --- a/test/syscalls/linux/ppoll.cc +++ b/test/syscalls/linux/ppoll.cc @@ -76,7 +76,7 @@ TEST_F(PpollTest, ZeroTimeout) { // If random S/R interrupts the ppoll, SIGALRM may be delivered before ppoll // restarts, causing the ppoll to hang forever. -TEST_F(PpollTest, NoTimeout_NoRandomSave) { +TEST_F(PpollTest, NoTimeout) { // When there's no timeout, ppoll may never return so set a timer. SetTimer(absl::Milliseconds(100)); // See that we get interrupted by the timer. diff --git a/test/syscalls/linux/pread64.cc b/test/syscalls/linux/pread64.cc index c74990ba1..0a09259a3 100644 --- a/test/syscalls/linux/pread64.cc +++ b/test/syscalls/linux/pread64.cc @@ -144,7 +144,7 @@ TEST_F(Pread64Test, Overflow) { SyscallFailsWithErrno(EINVAL)); } -TEST(Pread64TestNoTempFile, CantReadSocketPair_NoRandomSave) { +TEST(Pread64TestNoTempFile, CantReadSocketPair) { int sock_fds[2]; EXPECT_THAT(socketpair(AF_UNIX, SOCK_STREAM, 0, sock_fds), SyscallSucceeds()); diff --git a/test/syscalls/linux/proc.cc b/test/syscalls/linux/proc.cc index 493042dfc..6b055ea89 100644 --- a/test/syscalls/linux/proc.cc +++ b/test/syscalls/linux/proc.cc @@ -1629,7 +1629,7 @@ TEST(ProcPidStatusTest, StateRunning) { IsPosixErrorOkAndHolds(Contains(Pair("State", "R (running)")))); } -TEST(ProcPidStatusTest, StateSleeping_NoRandomSave) { +TEST(ProcPidStatusTest, StateSleeping) { // Starts a child process that blocks and checks that State is sleeping. auto res = WithSubprocess( [&](int pid) -> PosixError { diff --git a/test/syscalls/linux/proc_net.cc b/test/syscalls/linux/proc_net.cc index 20f1dc305..04fecc02e 100644 --- a/test/syscalls/linux/proc_net.cc +++ b/test/syscalls/linux/proc_net.cc @@ -189,7 +189,7 @@ PosixErrorOr<uint64_t> GetSNMPMetricFromProc(const std::string snmp, EINVAL, absl::StrCat("failed to find ", type, "/", item, " in:", snmp)); } -TEST(ProcNetSnmp, TcpReset_NoRandomSave) { +TEST(ProcNetSnmp, TcpReset) { // TODO(gvisor.dev/issue/866): epsocket metrics are not savable. DisableSave ds; @@ -231,7 +231,7 @@ TEST(ProcNetSnmp, TcpReset_NoRandomSave) { EXPECT_EQ(oldAttemptFails, newAttemptFails - 1); } -TEST(ProcNetSnmp, TcpEstab_NoRandomSave) { +TEST(ProcNetSnmp, TcpEstab) { // TODO(gvisor.dev/issue/866): epsocket metrics are not savable. DisableSave ds; @@ -263,9 +263,8 @@ TEST(ProcNetSnmp, TcpEstab_NoRandomSave) { // Get the port bound by the listening socket. socklen_t addrlen = sizeof(sin); - ASSERT_THAT( - getsockname(s_listen.get(), reinterpret_cast<sockaddr*>(&sin), &addrlen), - SyscallSucceeds()); + ASSERT_THAT(getsockname(s_listen.get(), AsSockAddr(&sin), &addrlen), + SyscallSucceeds()); FileDescriptor s_connect = ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_INET, SOCK_STREAM, 0)); @@ -326,7 +325,7 @@ TEST(ProcNetSnmp, TcpEstab_NoRandomSave) { EXPECT_EQ(oldEstabResets, newEstabResets - 2); } -TEST(ProcNetSnmp, UdpNoPorts_NoRandomSave) { +TEST(ProcNetSnmp, UdpNoPorts) { // TODO(gvisor.dev/issue/866): epsocket metrics are not savable. DisableSave ds; @@ -360,7 +359,7 @@ TEST(ProcNetSnmp, UdpNoPorts_NoRandomSave) { EXPECT_EQ(oldNoPorts, newNoPorts - 1); } -TEST(ProcNetSnmp, UdpIn_NoRandomSave) { +TEST(ProcNetSnmp, UdpIn) { // TODO(gvisor.dev/issue/866): epsocket metrics are not savable. const DisableSave ds; @@ -384,9 +383,8 @@ TEST(ProcNetSnmp, UdpIn_NoRandomSave) { SyscallSucceeds()); // Get the port bound by the server socket. socklen_t addrlen = sizeof(sin); - ASSERT_THAT( - getsockname(server.get(), reinterpret_cast<sockaddr*>(&sin), &addrlen), - SyscallSucceeds()); + ASSERT_THAT(getsockname(server.get(), AsSockAddr(&sin), &addrlen), + SyscallSucceeds()); FileDescriptor client = ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_INET, SOCK_DGRAM, 0)); @@ -421,14 +419,14 @@ TEST(ProcNetSnmp, CheckNetStat) { int name_count = 0; int value_count = 0; std::vector<absl::string_view> lines = absl::StrSplit(contents, '\n'); - for (long unsigned int i = 0; i + 1 < lines.size(); i += 2) { + for (size_t i = 0; i + 1 < lines.size(); i += 2) { std::vector<absl::string_view> names = absl::StrSplit(lines[i], absl::ByAnyChar("\t ")); std::vector<absl::string_view> values = absl::StrSplit(lines[i + 1], absl::ByAnyChar("\t ")); EXPECT_EQ(names.size(), values.size()) << " mismatch in lines '" << lines[i] << "' and '" << lines[i + 1] << "'"; - for (long unsigned int j = 0; j < names.size() && j < values.size(); ++j) { + for (size_t j = 0; j < names.size() && j < values.size(); ++j) { if (names[j] == "TCPOrigDataSent" || names[j] == "TCPSynRetrans" || names[j] == "TCPDSACKRecv" || names[j] == "TCPDSACKOfoRecv") { ++name_count; @@ -458,14 +456,14 @@ TEST(ProcNetSnmp, CheckSnmp) { int name_count = 0; int value_count = 0; std::vector<absl::string_view> lines = absl::StrSplit(contents, '\n'); - for (long unsigned int i = 0; i + 1 < lines.size(); i += 2) { + for (size_t i = 0; i + 1 < lines.size(); i += 2) { std::vector<absl::string_view> names = absl::StrSplit(lines[i], absl::ByAnyChar("\t ")); std::vector<absl::string_view> values = absl::StrSplit(lines[i + 1], absl::ByAnyChar("\t ")); EXPECT_EQ(names.size(), values.size()) << " mismatch in lines '" << lines[i] << "' and '" << lines[i + 1] << "'"; - for (long unsigned int j = 0; j < names.size() && j < values.size(); ++j) { + for (size_t j = 0; j < names.size() && j < values.size(); ++j) { if (names[j] == "RetransSegs") { ++name_count; int64_t val; diff --git a/test/syscalls/linux/proc_net_unix.cc b/test/syscalls/linux/proc_net_unix.cc index d61d94309..f7ff65aad 100644 --- a/test/syscalls/linux/proc_net_unix.cc +++ b/test/syscalls/linux/proc_net_unix.cc @@ -182,7 +182,7 @@ PosixErrorOr<std::vector<UnixEntry>> ProcNetUnixEntries() { // Returns true on match, and sets 'match' to point to the matching entry. bool FindBy(std::vector<UnixEntry> entries, UnixEntry* match, std::function<bool(const UnixEntry&)> predicate) { - for (long unsigned int i = 0; i < entries.size(); ++i) { + for (size_t i = 0; i < entries.size(); ++i) { if (predicate(entries[i])) { *match = entries[i]; return true; @@ -201,15 +201,8 @@ TEST(ProcNetUnix, Exists) { const std::string content = ASSERT_NO_ERRNO_AND_VALUE(GetContents("/proc/net/unix")); const std::string header_line = StrCat(kProcNetUnixHeader, "\n"); - if (IsRunningOnGvisor()) { - // Should be just the header since we don't have any unix domain sockets - // yet. - EXPECT_EQ(content, header_line); - } else { - // However, on a general linux machine, we could have abitrary sockets on - // the system, so just check the header. - EXPECT_THAT(content, ::testing::StartsWith(header_line)); - } + // We could have abitrary sockets on the system, so just check the header. + EXPECT_THAT(content, ::testing::StartsWith(header_line)); } TEST(ProcNetUnix, FilesystemBindAcceptConnect) { @@ -223,9 +216,6 @@ TEST(ProcNetUnix, FilesystemBindAcceptConnect) { std::vector<UnixEntry> entries = ASSERT_NO_ERRNO_AND_VALUE(ProcNetUnixEntries()); - if (IsRunningOnGvisor()) { - EXPECT_EQ(entries.size(), 2); - } // The server-side socket's path is listed in the socket entry... UnixEntry s1; @@ -247,9 +237,6 @@ TEST(ProcNetUnix, AbstractBindAcceptConnect) { std::vector<UnixEntry> entries = ASSERT_NO_ERRNO_AND_VALUE(ProcNetUnixEntries()); - if (IsRunningOnGvisor()) { - EXPECT_EQ(entries.size(), 2); - } // The server-side socket's path is listed in the socket entry... UnixEntry s1; @@ -261,20 +248,12 @@ TEST(ProcNetUnix, AbstractBindAcceptConnect) { } TEST(ProcNetUnix, SocketPair) { - // Under gvisor, ensure a socketpair() syscall creates exactly 2 new - // entries. We have no way to verify this under Linux, as we have no control - // over socket creation on a general Linux machine. - SKIP_IF(!IsRunningOnGvisor()); - - std::vector<UnixEntry> entries = - ASSERT_NO_ERRNO_AND_VALUE(ProcNetUnixEntries()); - ASSERT_EQ(entries.size(), 0); - auto sockets = ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_STREAM).Create()); - entries = ASSERT_NO_ERRNO_AND_VALUE(ProcNetUnixEntries()); - EXPECT_EQ(entries.size(), 2); + std::vector<UnixEntry> entries = + ASSERT_NO_ERRNO_AND_VALUE(ProcNetUnixEntries()); + EXPECT_GE(entries.size(), 2); } TEST(ProcNetUnix, StreamSocketStateUnconnectedOnBind) { @@ -368,25 +347,12 @@ TEST(ProcNetUnix, DgramSocketStateDisconnectingOnBind) { auto sockets = ASSERT_NO_ERRNO_AND_VALUE( AbstractUnboundUnixDomainSocketPair(SOCK_DGRAM).Create()); - std::vector<UnixEntry> entries = - ASSERT_NO_ERRNO_AND_VALUE(ProcNetUnixEntries()); - - // On gVisor, the only two UDS on the system are the ones we just created and - // we rely on this to locate the test socket entries in the remainder of the - // test. On a generic Linux system, we have no easy way to locate the - // corresponding entries, as they don't have an address yet. - if (IsRunningOnGvisor()) { - ASSERT_EQ(entries.size(), 2); - for (const auto& e : entries) { - ASSERT_EQ(e.state, SS_DISCONNECTING); - } - } - ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(), sockets->first_addr_size()), SyscallSucceeds()); - entries = ASSERT_NO_ERRNO_AND_VALUE(ProcNetUnixEntries()); + std::vector<UnixEntry> entries = + ASSERT_NO_ERRNO_AND_VALUE(ProcNetUnixEntries()); const std::string address = ExtractPath(sockets->first_addr()); UnixEntry bind_entry; ASSERT_TRUE(FindByPath(entries, &bind_entry, address)); @@ -397,25 +363,12 @@ TEST(ProcNetUnix, DgramSocketStateConnectingOnConnect) { auto sockets = ASSERT_NO_ERRNO_AND_VALUE( AbstractUnboundUnixDomainSocketPair(SOCK_DGRAM).Create()); - std::vector<UnixEntry> entries = - ASSERT_NO_ERRNO_AND_VALUE(ProcNetUnixEntries()); - - // On gVisor, the only two UDS on the system are the ones we just created and - // we rely on this to locate the test socket entries in the remainder of the - // test. On a generic Linux system, we have no easy way to locate the - // corresponding entries, as they don't have an address yet. - if (IsRunningOnGvisor()) { - ASSERT_EQ(entries.size(), 2); - for (const auto& e : entries) { - ASSERT_EQ(e.state, SS_DISCONNECTING); - } - } - ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(), sockets->first_addr_size()), SyscallSucceeds()); - entries = ASSERT_NO_ERRNO_AND_VALUE(ProcNetUnixEntries()); + std::vector<UnixEntry> entries = + ASSERT_NO_ERRNO_AND_VALUE(ProcNetUnixEntries()); const std::string address = ExtractPath(sockets->first_addr()); UnixEntry bind_entry; ASSERT_TRUE(FindByPath(entries, &bind_entry, address)); @@ -423,22 +376,6 @@ TEST(ProcNetUnix, DgramSocketStateConnectingOnConnect) { ASSERT_THAT(connect(sockets->second_fd(), sockets->first_addr(), sockets->first_addr_size()), SyscallSucceeds()); - - entries = ASSERT_NO_ERRNO_AND_VALUE(ProcNetUnixEntries()); - - // Once again, we have no easy way to identify the connecting socket as it has - // no listed address. We can only identify the entry as the "non-bind socket - // entry" on gVisor, where we're guaranteed to have only the two entries we - // create during this test. - if (IsRunningOnGvisor()) { - ASSERT_EQ(entries.size(), 2); - UnixEntry connect_entry; - ASSERT_TRUE( - FindBy(entries, &connect_entry, [bind_entry](const UnixEntry& e) { - return e.inode != bind_entry.inode; - })); - EXPECT_EQ(connect_entry.state, SS_CONNECTING); - } } } // namespace diff --git a/test/syscalls/linux/proc_pid_uid_gid_map.cc b/test/syscalls/linux/proc_pid_uid_gid_map.cc index af052a63c..c030592c8 100644 --- a/test/syscalls/linux/proc_pid_uid_gid_map.cc +++ b/test/syscalls/linux/proc_pid_uid_gid_map.cc @@ -203,8 +203,9 @@ TEST_P(ProcSelfUidGidMapTest, IdentityMapOwnID) { EXPECT_THAT( InNewUserNamespaceWithMapFD([&](int fd) { DenySelfSetgroups(); - TEST_PCHECK(static_cast<long unsigned int>( - write(fd, line.c_str(), line.size())) == line.size()); + size_t n; + TEST_PCHECK((n = write(fd, line.c_str(), line.size())) != -1); + TEST_CHECK(n == line.size()); }), IsPosixErrorOkAndHolds(0)); } @@ -221,8 +222,9 @@ TEST_P(ProcSelfUidGidMapTest, TrailingNewlineAndNULIgnored) { DenySelfSetgroups(); // The write should return the full size of the write, even though // characters after the NUL were ignored. - TEST_PCHECK(static_cast<long unsigned int>( - write(fd, line.c_str(), line.size())) == line.size()); + size_t n; + TEST_PCHECK((n = write(fd, line.c_str(), line.size())) != -1); + TEST_CHECK(n == line.size()); }), IsPosixErrorOkAndHolds(0)); } diff --git a/test/syscalls/linux/pselect.cc b/test/syscalls/linux/pselect.cc index 4e43c4d7f..e490a987d 100644 --- a/test/syscalls/linux/pselect.cc +++ b/test/syscalls/linux/pselect.cc @@ -88,7 +88,7 @@ TEST_F(PselectTest, ZeroTimeout) { // If random S/R interrupts the pselect, SIGALRM may be delivered before pselect // restarts, causing the pselect to hang forever. -TEST_F(PselectTest, NoTimeout_NoRandomSave) { +TEST_F(PselectTest, NoTimeout) { // When there's no timeout, pselect may never return so set a timer. SetTimer(absl::Milliseconds(100)); // See that we get interrupted by the timer. diff --git a/test/syscalls/linux/ptrace.cc b/test/syscalls/linux/ptrace.cc index d1d7c6f84..2d9fec371 100644 --- a/test/syscalls/linux/ptrace.cc +++ b/test/syscalls/linux/ptrace.cc @@ -1708,8 +1708,7 @@ INSTANTIATE_TEST_SUITE_P(TraceExec, PtraceExecveTest, ::testing::Bool()); // This test has expectations on when syscall-enter/exit-stops occur that are // violated if saving occurs, since saving interrupts all syscalls, causing // premature syscall-exit. -TEST(PtraceTest, - ExitWhenParentIsNotTracer_Syscall_TraceVfork_TraceVforkDone_NoRandomSave) { +TEST(PtraceTest, ExitWhenParentIsNotTracer_Syscall_TraceVfork_TraceVforkDone) { constexpr int kExitTraceeExitCode = 99; pid_t const child_pid = fork(); @@ -2006,7 +2005,7 @@ TEST(PtraceTest, Sysemu_PokeUser) { } // This test also cares about syscall-exit-stop. -TEST(PtraceTest, ERESTART_NoRandomSave) { +TEST(PtraceTest, ERESTART) { constexpr int kSigno = SIGUSR1; pid_t const child_pid = fork(); diff --git a/test/syscalls/linux/raw_socket.cc b/test/syscalls/linux/raw_socket.cc index 32924466f..69616b400 100644 --- a/test/syscalls/linux/raw_socket.cc +++ b/test/syscalls/linux/raw_socket.cc @@ -514,10 +514,7 @@ TEST_P(RawSocketTest, SetSocketRecvBuf) { SyscallSucceeds()); // Linux doubles the value set by SO_SNDBUF/SO_RCVBUF. - // TODO(gvisor.dev/issue/2926): Remove when Netstack matches linux behavior. - if (!IsRunningOnGvisor()) { - quarter_sz *= 2; - } + quarter_sz *= 2; ASSERT_EQ(quarter_sz, val); } @@ -713,12 +710,7 @@ TEST_P(RawSocketTest, RecvBufLimits) { } // Now set the limit to min * 2. - int new_rcv_buf_sz = min * 4; - if (!IsRunningOnGvisor()) { - // Linux doubles the value specified so just set to min. - new_rcv_buf_sz = min * 2; - } - + int new_rcv_buf_sz = min * 2; ASSERT_THAT(setsockopt(s_, SOL_SOCKET, SO_RCVBUF, &new_rcv_buf_sz, sizeof(new_rcv_buf_sz)), SyscallSucceeds()); diff --git a/test/syscalls/linux/read.cc b/test/syscalls/linux/read.cc index 087262535..7056342d7 100644 --- a/test/syscalls/linux/read.cc +++ b/test/syscalls/linux/read.cc @@ -97,7 +97,7 @@ TEST_F(ReadTest, DevNullReturnsEof) { const int kReadSize = 128 * 1024; // Do not allow random save as it could lead to partial reads. -TEST_F(ReadTest, CanReadFullyFromDevZero_NoRandomSave) { +TEST_F(ReadTest, CanReadFullyFromDevZero) { int fd; ASSERT_THAT(fd = open("/dev/zero", O_RDONLY), SyscallSucceeds()); diff --git a/test/syscalls/linux/readv.cc b/test/syscalls/linux/readv.cc index 86808d255..a50d98d21 100644 --- a/test/syscalls/linux/readv.cc +++ b/test/syscalls/linux/readv.cc @@ -267,7 +267,7 @@ TEST_F(ReadvTest, ReadvWithOpath) { // This test depends on the maximum extent of a single readv() syscall, so // we can't tolerate interruption from saving. -TEST(ReadvTestNoFixture, TruncatedAtMax_NoRandomSave) { +TEST(ReadvTestNoFixture, TruncatedAtMax) { // Ensure that we won't be interrupted by ITIMER_PROF. This is particularly // important in environments where automated profiling tools may start // ITIMER_PROF automatically. diff --git a/test/syscalls/linux/select.cc b/test/syscalls/linux/select.cc index be2364fb8..d74096ded 100644 --- a/test/syscalls/linux/select.cc +++ b/test/syscalls/linux/select.cc @@ -98,7 +98,7 @@ TEST_F(SelectTest, ZeroTimeout) { // If random S/R interrupts the select, SIGALRM may be delivered before select // restarts, causing the select to hang forever. -TEST_F(SelectTest, NoTimeout_NoRandomSave) { +TEST_F(SelectTest, NoTimeout) { // When there's no timeout, select may never return so set a timer. SetTimer(absl::Milliseconds(100)); // See that we get interrupted by the timer. @@ -118,7 +118,7 @@ TEST_F(SelectTest, InvalidTimeoutNegative) { // // If random S/R interrupts the select, SIGALRM may be delivered before select // restarts, causing the select to hang forever. -TEST_F(SelectTest, InterruptedBySignal_NoRandomSave) { +TEST_F(SelectTest, InterruptedBySignal) { absl::Duration duration(absl::Seconds(5)); struct timeval timeout = absl::ToTimeval(duration); SetTimer(absl::Milliseconds(100)); diff --git a/test/syscalls/linux/semaphore.cc b/test/syscalls/linux/semaphore.cc index 28f51a3bf..207377efb 100644 --- a/test/syscalls/linux/semaphore.cc +++ b/test/syscalls/linux/semaphore.cc @@ -234,14 +234,6 @@ TEST(SemaphoreTest, SemTimedOpBlock) { AutoSem sem(semget(IPC_PRIVATE, 1, 0600 | IPC_CREAT)); ASSERT_THAT(sem.get(), SyscallSucceeds()); - ScopedThread th([&sem] { - absl::SleepFor(absl::Milliseconds(100)); - - struct sembuf buf = {}; - buf.sem_op = 1; - ASSERT_THAT(RetryEINTR(semop)(sem.get(), &buf, 1), SyscallSucceeds()); - }); - struct sembuf buf = {}; buf.sem_op = -1; struct timespec timeout = {}; @@ -295,7 +287,7 @@ TEST(SemaphoreTest, SemOpSimple) { // Tests that semaphore can be removed while there are waiters. // NoRandomSave: Test relies on timing that random save throws off. -TEST(SemaphoreTest, SemOpRemoveWithWaiter_NoRandomSave) { +TEST(SemaphoreTest, SemOpRemoveWithWaiter) { AutoSem sem(semget(IPC_PRIVATE, 2, 0600 | IPC_CREAT)); ASSERT_THAT(sem.get(), SyscallSucceeds()); @@ -716,7 +708,7 @@ TEST(SemaphoreTest, SemopGetzcntOnSetRemoval) { EXPECT_THAT(semctl(semid, 0, GETZCNT), SyscallFailsWithErrno(EINVAL)); } -TEST(SemaphoreTest, SemopGetzcntOnSignal_NoRandomSave) { +TEST(SemaphoreTest, SemopGetzcntOnSignal) { AutoSem sem(semget(IPC_PRIVATE, 1, 0600 | IPC_CREAT)); ASSERT_THAT(sem.get(), SyscallSucceeds()); ASSERT_THAT(semctl(sem.get(), 0, SETVAL, 1), SyscallSucceeds()); @@ -821,7 +813,7 @@ TEST(SemaphoreTest, SemopGetncntOnSetRemoval) { EXPECT_THAT(semctl(semid, 0, GETNCNT), SyscallFailsWithErrno(EINVAL)); } -TEST(SemaphoreTest, SemopGetncntOnSignal_NoRandomSave) { +TEST(SemaphoreTest, SemopGetncntOnSignal) { AutoSem sem(semget(IPC_PRIVATE, 1, 0600 | IPC_CREAT)); ASSERT_THAT(sem.get(), SyscallSucceeds()); ASSERT_EQ(semctl(sem.get(), 0, GETNCNT), 0); diff --git a/test/syscalls/linux/sendfile.cc b/test/syscalls/linux/sendfile.cc index 93b3a94f1..bea4ee71c 100644 --- a/test/syscalls/linux/sendfile.cc +++ b/test/syscalls/linux/sendfile.cc @@ -654,7 +654,7 @@ TEST(SendFileTest, SendFileToPipe) { SyscallSucceedsWithValue(kDataSize)); } -TEST(SendFileTest, SendFileToSelf_NoRandomSave) { +TEST(SendFileTest, SendFileToSelf) { int rawfd; ASSERT_THAT(rawfd = memfd_create("memfd", 0), SyscallSucceeds()); const FileDescriptor fd(rawfd); @@ -675,7 +675,7 @@ TEST(SendFileTest, SendFileToSelf_NoRandomSave) { static volatile int signaled = 0; void SigUsr1Handler(int sig, siginfo_t* info, void* context) { signaled = 1; } -TEST(SendFileTest, ToEventFDDoesNotSpin_NoRandomSave) { +TEST(SendFileTest, ToEventFDDoesNotSpin) { FileDescriptor efd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, 0)); // Write the maximum value of an eventfd to a file. diff --git a/test/syscalls/linux/sigtimedwait.cc b/test/syscalls/linux/sigtimedwait.cc index 4f8afff15..21651a697 100644 --- a/test/syscalls/linux/sigtimedwait.cc +++ b/test/syscalls/linux/sigtimedwait.cc @@ -52,7 +52,7 @@ TEST(SigtimedwaitTest, InvalidTimeout) { // No random save as the test relies on alarm timing. Cooperative save tests // already cover the save between alarm and wait. -TEST(SigtimedwaitTest, AlarmReturnsAlarm_NoRandomSave) { +TEST(SigtimedwaitTest, AlarmReturnsAlarm) { struct itimerval itv = {}; itv.it_value.tv_sec = kAlarmSecs; const auto itimer_cleanup = @@ -69,7 +69,7 @@ TEST(SigtimedwaitTest, AlarmReturnsAlarm_NoRandomSave) { // No random save as the test relies on alarm timing. Cooperative save tests // already cover the save between alarm and wait. -TEST(SigtimedwaitTest, NullTimeoutReturnsEINTR_NoRandomSave) { +TEST(SigtimedwaitTest, NullTimeoutReturnsEINTR) { struct sigaction sa; sa.sa_sigaction = NoopHandler; sigfillset(&sa.sa_mask); diff --git a/test/syscalls/linux/socket.cc b/test/syscalls/linux/socket.cc index b616c2c87..7b966484d 100644 --- a/test/syscalls/linux/socket.cc +++ b/test/syscalls/linux/socket.cc @@ -47,7 +47,7 @@ TEST(SocketTest, ProtocolUnix) { {AF_UNIX, SOCK_SEQPACKET, PF_UNIX}, {AF_UNIX, SOCK_DGRAM, PF_UNIX}, }; - for (long unsigned int i = 0; i < ABSL_ARRAYSIZE(tests); i++) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(tests); i++) { ASSERT_NO_ERRNO_AND_VALUE( Socket(tests[i].domain, tests[i].type, tests[i].protocol)); } @@ -60,7 +60,7 @@ TEST(SocketTest, ProtocolInet) { {AF_INET, SOCK_DGRAM, IPPROTO_UDP}, {AF_INET, SOCK_STREAM, IPPROTO_TCP}, }; - for (long unsigned int i = 0; i < ABSL_ARRAYSIZE(tests); i++) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(tests); i++) { ASSERT_NO_ERRNO_AND_VALUE( Socket(tests[i].domain, tests[i].type, tests[i].protocol)); } @@ -111,7 +111,7 @@ TEST(SocketTest, UnixSocketStatFS) { EXPECT_EQ(st.f_namelen, NAME_MAX); } -TEST(SocketTest, UnixSCMRightsOnlyPassedOnce_NoRandomSave) { +TEST(SocketTest, UnixSCMRightsOnlyPassedOnce) { const DisableSave ds; int sockets[2]; diff --git a/test/syscalls/linux/socket_bind_to_device_distribution.cc b/test/syscalls/linux/socket_bind_to_device_distribution.cc index f8a0a80f2..3b108cbd3 100644 --- a/test/syscalls/linux/socket_bind_to_device_distribution.cc +++ b/test/syscalls/linux/socket_bind_to_device_distribution.cc @@ -141,9 +141,8 @@ TEST_P(BindToDeviceDistributionTest, Tcp) { endpoint.bind_to_device.c_str(), endpoint.bind_to_device.size() + 1), SyscallSucceeds()); - ASSERT_THAT( - bind(fd, reinterpret_cast<sockaddr*>(&listen_addr), listener.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(fd, AsSockAddr(&listen_addr), listener.addr_len), + SyscallSucceeds()); ASSERT_THAT(listen(fd, 40), SyscallSucceeds()); // On the first bind we need to determine which port was bound. @@ -154,8 +153,7 @@ TEST_P(BindToDeviceDistributionTest, Tcp) { // Get the port bound by the listening socket. socklen_t addrlen = listener.addr_len; ASSERT_THAT( - getsockname(listener_fds[0].get(), - reinterpret_cast<sockaddr*>(&listen_addr), &addrlen), + getsockname(listener_fds[0].get(), AsSockAddr(&listen_addr), &addrlen), SyscallSucceeds()); uint16_t const port = ASSERT_NO_ERRNO_AND_VALUE(AddrPort(listener.family(), listen_addr)); @@ -168,7 +166,7 @@ TEST_P(BindToDeviceDistributionTest, Tcp) { std::vector<std::unique_ptr<ScopedThread>> listen_threads( listener_fds.size()); - for (long unsigned int i = 0; i < listener_fds.size(); i++) { + for (size_t i = 0; i < listener_fds.size(); i++) { listen_threads[i] = absl::make_unique<ScopedThread>( [&listener_fds, &accept_counts, &connects_received, i, kConnectAttempts]() { @@ -207,10 +205,9 @@ TEST_P(BindToDeviceDistributionTest, Tcp) { for (int32_t i = 0; i < kConnectAttempts; i++) { const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE( Socket(connector.family(), SOCK_STREAM, IPPROTO_TCP)); - ASSERT_THAT( - RetryEINTR(connect)(fd.get(), reinterpret_cast<sockaddr*>(&conn_addr), - connector.addr_len), - SyscallSucceeds()); + ASSERT_THAT(RetryEINTR(connect)(fd.get(), AsSockAddr(&conn_addr), + connector.addr_len), + SyscallSucceeds()); EXPECT_THAT(RetryEINTR(send)(fd.get(), &i, sizeof(i), 0), SyscallSucceedsWithValue(sizeof(i))); @@ -221,7 +218,7 @@ TEST_P(BindToDeviceDistributionTest, Tcp) { listen_thread->Join(); } // Check that connections are distributed correctly among listening sockets. - for (long unsigned int i = 0; i < accept_counts.size(); i++) { + for (size_t i = 0; i < accept_counts.size(); i++) { EXPECT_THAT( accept_counts[i], EquivalentWithin(static_cast<int>(kConnectAttempts * @@ -267,9 +264,8 @@ TEST_P(BindToDeviceDistributionTest, Udp) { endpoint.bind_to_device.c_str(), endpoint.bind_to_device.size() + 1), SyscallSucceeds()); - ASSERT_THAT( - bind(fd, reinterpret_cast<sockaddr*>(&listen_addr), listener.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(fd, AsSockAddr(&listen_addr), listener.addr_len), + SyscallSucceeds()); // On the first bind we need to determine which port was bound. if (listener_fds.size() > 1) { @@ -279,8 +275,7 @@ TEST_P(BindToDeviceDistributionTest, Udp) { // Get the port bound by the listening socket. socklen_t addrlen = listener.addr_len; ASSERT_THAT( - getsockname(listener_fds[0].get(), - reinterpret_cast<sockaddr*>(&listen_addr), &addrlen), + getsockname(listener_fds[0].get(), AsSockAddr(&listen_addr), &addrlen), SyscallSucceeds()); uint16_t const port = ASSERT_NO_ERRNO_AND_VALUE(AddrPort(listener.family(), listen_addr)); @@ -294,7 +289,7 @@ TEST_P(BindToDeviceDistributionTest, Udp) { std::vector<std::unique_ptr<ScopedThread>> receiver_threads( listener_fds.size()); - for (long unsigned int i = 0; i < listener_fds.size(); i++) { + for (size_t i = 0; i < listener_fds.size(); i++) { receiver_threads[i] = absl::make_unique<ScopedThread>( [&listener_fds, &packets_per_socket, &packets_received, i]() { do { @@ -302,9 +297,9 @@ TEST_P(BindToDeviceDistributionTest, Udp) { socklen_t addrlen = sizeof(addr); int data; - auto ret = RetryEINTR(recvfrom)( - listener_fds[i].get(), &data, sizeof(data), 0, - reinterpret_cast<struct sockaddr*>(&addr), &addrlen); + auto ret = + RetryEINTR(recvfrom)(listener_fds[i].get(), &data, sizeof(data), + 0, AsSockAddr(&addr), &addrlen); if (packets_received < kConnectAttempts) { ASSERT_THAT(ret, SyscallSucceedsWithValue(sizeof(data))); @@ -322,10 +317,10 @@ TEST_P(BindToDeviceDistributionTest, Udp) { // A response is required to synchronize with the main thread, // otherwise the main thread can send more than can fit into receive // queues. - EXPECT_THAT(RetryEINTR(sendto)( - listener_fds[i].get(), &data, sizeof(data), 0, - reinterpret_cast<sockaddr*>(&addr), addrlen), - SyscallSucceedsWithValue(sizeof(data))); + EXPECT_THAT( + RetryEINTR(sendto)(listener_fds[i].get(), &data, sizeof(data), + 0, AsSockAddr(&addr), addrlen), + SyscallSucceedsWithValue(sizeof(data))); } while (packets_received < kConnectAttempts); // Shutdown all sockets to wake up other threads. @@ -339,8 +334,7 @@ TEST_P(BindToDeviceDistributionTest, Udp) { FileDescriptor const fd = ASSERT_NO_ERRNO_AND_VALUE(Socket(connector.family(), SOCK_DGRAM, 0)); EXPECT_THAT(RetryEINTR(sendto)(fd.get(), &i, sizeof(i), 0, - reinterpret_cast<sockaddr*>(&conn_addr), - connector.addr_len), + AsSockAddr(&conn_addr), connector.addr_len), SyscallSucceedsWithValue(sizeof(i))); int data; EXPECT_THAT(RetryEINTR(recv)(fd.get(), &data, sizeof(data), 0), @@ -352,7 +346,7 @@ TEST_P(BindToDeviceDistributionTest, Udp) { receiver_thread->Join(); } // Check that packets are distributed correctly among listening sockets. - for (long unsigned int i = 0; i < packets_per_socket.size(); i++) { + for (size_t i = 0; i < packets_per_socket.size(); i++) { EXPECT_THAT( packets_per_socket[i], EquivalentWithin(static_cast<int>(kConnectAttempts * diff --git a/test/syscalls/linux/socket_inet_loopback.cc b/test/syscalls/linux/socket_inet_loopback.cc index 597b5bcb1..9a6b089f6 100644 --- a/test/syscalls/linux/socket_inet_loopback.cc +++ b/test/syscalls/linux/socket_inet_loopback.cc @@ -190,8 +190,7 @@ TEST_P(DualStackSocketTest, AddressOperations) { if (sockname) { sockaddr_storage sock_addr; socklen_t addrlen = sizeof(sock_addr); - ASSERT_THAT(getsockname(fd.get(), reinterpret_cast<sockaddr*>(&sock_addr), - &addrlen), + ASSERT_THAT(getsockname(fd.get(), AsSockAddr(&sock_addr), &addrlen), SyscallSucceeds()); ASSERT_EQ(addrlen, sizeof(struct sockaddr_in6)); @@ -200,24 +199,23 @@ TEST_P(DualStackSocketTest, AddressOperations) { if (operation == Operation::SendTo) { EXPECT_EQ(sock_addr_in6->sin6_family, AF_INET6); EXPECT_TRUE(IN6_IS_ADDR_UNSPECIFIED(sock_addr_in6->sin6_addr.s6_addr32)) - << OperationToString(operation) << " getsocknam=" - << GetAddrStr(reinterpret_cast<sockaddr*>(&sock_addr)); + << OperationToString(operation) + << " getsocknam=" << GetAddrStr(AsSockAddr(&sock_addr)); EXPECT_NE(sock_addr_in6->sin6_port, 0); } else if (IN6_IS_ADDR_V4MAPPED( reinterpret_cast<const sockaddr_in6*>(addr_in) ->sin6_addr.s6_addr32)) { EXPECT_TRUE(IN6_IS_ADDR_V4MAPPED(sock_addr_in6->sin6_addr.s6_addr32)) - << OperationToString(operation) << " getsocknam=" - << GetAddrStr(reinterpret_cast<sockaddr*>(&sock_addr)); + << OperationToString(operation) + << " getsocknam=" << GetAddrStr(AsSockAddr(&sock_addr)); } } if (peername) { sockaddr_storage peer_addr; socklen_t addrlen = sizeof(peer_addr); - ASSERT_THAT(getpeername(fd.get(), reinterpret_cast<sockaddr*>(&peer_addr), - &addrlen), + ASSERT_THAT(getpeername(fd.get(), AsSockAddr(&peer_addr), &addrlen), SyscallSucceeds()); ASSERT_EQ(addrlen, sizeof(struct sockaddr_in6)); @@ -227,8 +225,8 @@ TEST_P(DualStackSocketTest, AddressOperations) { EXPECT_TRUE(IN6_IS_ADDR_V4MAPPED( reinterpret_cast<const sockaddr_in6*>(&peer_addr) ->sin6_addr.s6_addr32)) - << OperationToString(operation) << " getpeername=" - << GetAddrStr(reinterpret_cast<sockaddr*>(&peer_addr)); + << OperationToString(operation) + << " getpeername=" << GetAddrStr(AsSockAddr(&peer_addr)); } } } @@ -265,16 +263,15 @@ void tcpSimpleConnectTest(TestAddress const& listener, Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP)); sockaddr_storage listen_addr = listener.addr; if (!unbound) { - ASSERT_THAT(bind(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), - listener.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(listen_fd.get(), AsSockAddr(&listen_addr), listener.addr_len), + SyscallSucceeds()); } ASSERT_THAT(listen(listen_fd.get(), SOMAXCONN), SyscallSucceeds()); // Get the port bound by the listening socket. socklen_t addrlen = listener.addr_len; - ASSERT_THAT(getsockname(listen_fd.get(), - reinterpret_cast<sockaddr*>(&listen_addr), &addrlen), + ASSERT_THAT(getsockname(listen_fd.get(), AsSockAddr(&listen_addr), &addrlen), SyscallSucceeds()); uint16_t const port = ASSERT_NO_ERRNO_AND_VALUE(AddrPort(listener.family(), listen_addr)); @@ -284,8 +281,7 @@ void tcpSimpleConnectTest(TestAddress const& listener, Socket(connector.family(), SOCK_STREAM, IPPROTO_TCP)); sockaddr_storage conn_addr = connector.addr; ASSERT_NO_ERRNO(SetAddrPort(connector.family(), &conn_addr, port)); - ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(), - reinterpret_cast<sockaddr*>(&conn_addr), + ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(), AsSockAddr(&conn_addr), connector.addr_len), SyscallSucceeds()); @@ -331,9 +327,9 @@ TEST_P(SocketInetLoopbackTest, TCPListenShutdownListen) { FileDescriptor listen_fd = ASSERT_NO_ERRNO_AND_VALUE( Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP)); sockaddr_storage listen_addr = listener.addr; - ASSERT_THAT(bind(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), - listener.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(listen_fd.get(), AsSockAddr(&listen_addr), listener.addr_len), + SyscallSucceeds()); ASSERT_THAT(listen(listen_fd.get(), kBacklog), SyscallSucceeds()); ASSERT_THAT(shutdown(listen_fd.get(), SHUT_RD), SyscallSucceeds()); @@ -341,8 +337,7 @@ TEST_P(SocketInetLoopbackTest, TCPListenShutdownListen) { // Get the port bound by the listening socket. socklen_t addrlen = listener.addr_len; - ASSERT_THAT(getsockname(listen_fd.get(), - reinterpret_cast<sockaddr*>(&listen_addr), &addrlen), + ASSERT_THAT(getsockname(listen_fd.get(), AsSockAddr(&listen_addr), &addrlen), SyscallSucceeds()); const uint16_t port = ASSERT_NO_ERRNO_AND_VALUE(AddrPort(listener.family(), listen_addr)); @@ -357,8 +352,7 @@ TEST_P(SocketInetLoopbackTest, TCPListenShutdownListen) { for (int i = 0; i < kBacklog; i++) { auto client = ASSERT_NO_ERRNO_AND_VALUE( Socket(connector.family(), SOCK_STREAM, IPPROTO_TCP)); - ASSERT_THAT(RetryEINTR(connect)(client.get(), - reinterpret_cast<sockaddr*>(&conn_addr), + ASSERT_THAT(RetryEINTR(connect)(client.get(), AsSockAddr(&conn_addr), connector.addr_len), SyscallSucceeds()); } @@ -380,15 +374,14 @@ TEST_P(SocketInetLoopbackTest, TCPListenShutdown) { FileDescriptor listen_fd = ASSERT_NO_ERRNO_AND_VALUE( Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP)); sockaddr_storage listen_addr = listener.addr; - ASSERT_THAT(bind(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), - listener.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(listen_fd.get(), AsSockAddr(&listen_addr), listener.addr_len), + SyscallSucceeds()); ASSERT_THAT(listen(listen_fd.get(), kBacklog), SyscallSucceeds()); // Get the port bound by the listening socket. socklen_t addrlen = listener.addr_len; - ASSERT_THAT(getsockname(listen_fd.get(), - reinterpret_cast<sockaddr*>(&listen_addr), &addrlen), + ASSERT_THAT(getsockname(listen_fd.get(), AsSockAddr(&listen_addr), &addrlen), SyscallSucceeds()); uint16_t const port = ASSERT_NO_ERRNO_AND_VALUE(AddrPort(listener.family(), listen_addr)); @@ -402,8 +395,7 @@ TEST_P(SocketInetLoopbackTest, TCPListenShutdown) { for (int i = 0; i < kFDs; i++) { auto client = ASSERT_NO_ERRNO_AND_VALUE( Socket(connector.family(), SOCK_STREAM, IPPROTO_TCP)); - ASSERT_THAT(RetryEINTR(connect)(client.get(), - reinterpret_cast<sockaddr*>(&conn_addr), + ASSERT_THAT(RetryEINTR(connect)(client.get(), AsSockAddr(&conn_addr), connector.addr_len), SyscallSucceeds()); ASSERT_THAT(accept(listen_fd.get(), nullptr, nullptr), SyscallSucceeds()); @@ -420,8 +412,7 @@ TEST_P(SocketInetLoopbackTest, TCPListenShutdown) { FileDescriptor new_listen_fd = ASSERT_NO_ERRNO_AND_VALUE( Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP)); ASSERT_THAT( - bind(new_listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), - listener.addr_len), + bind(new_listen_fd.get(), AsSockAddr(&listen_addr), listener.addr_len), SyscallFailsWithErrno(EADDRINUSE)); // Check that subsequent connection attempts receive a RST. @@ -431,8 +422,7 @@ TEST_P(SocketInetLoopbackTest, TCPListenShutdown) { for (int i = 0; i < kFDs; i++) { auto client = ASSERT_NO_ERRNO_AND_VALUE( Socket(connector.family(), SOCK_STREAM, IPPROTO_TCP)); - ASSERT_THAT(RetryEINTR(connect)(client.get(), - reinterpret_cast<sockaddr*>(&conn_addr), + ASSERT_THAT(RetryEINTR(connect)(client.get(), AsSockAddr(&conn_addr), connector.addr_len), SyscallFailsWithErrno(ECONNREFUSED)); } @@ -452,15 +442,14 @@ TEST_P(SocketInetLoopbackTest, TCPListenClose) { FileDescriptor listen_fd = ASSERT_NO_ERRNO_AND_VALUE( Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP)); sockaddr_storage listen_addr = listener.addr; - ASSERT_THAT(bind(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), - listener.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(listen_fd.get(), AsSockAddr(&listen_addr), listener.addr_len), + SyscallSucceeds()); ASSERT_THAT(listen(listen_fd.get(), kBacklog), SyscallSucceeds()); // Get the port bound by the listening socket. socklen_t addrlen = listener.addr_len; - ASSERT_THAT(getsockname(listen_fd.get(), - reinterpret_cast<sockaddr*>(&listen_addr), &addrlen), + ASSERT_THAT(getsockname(listen_fd.get(), AsSockAddr(&listen_addr), &addrlen), SyscallSucceeds()); uint16_t const port = ASSERT_NO_ERRNO_AND_VALUE(AddrPort(listener.family(), listen_addr)); @@ -471,8 +460,7 @@ TEST_P(SocketInetLoopbackTest, TCPListenClose) { for (int i = 0; i < kFDs; i++) { auto client = ASSERT_NO_ERRNO_AND_VALUE( Socket(connector.family(), SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP)); - int ret = connect(client.get(), reinterpret_cast<sockaddr*>(&conn_addr), - connector.addr_len); + int ret = connect(client.get(), AsSockAddr(&conn_addr), connector.addr_len); if (ret != 0) { EXPECT_THAT(ret, SyscallFailsWithErrno(EINPROGRESS)); } @@ -484,93 +472,160 @@ TEST_P(SocketInetLoopbackTest, TCPListenClose) { } } -void TestListenWhileConnect(const TestParam& param, - void (*stopListen)(FileDescriptor&)) { +void TestHangupDuringConnect(const TestParam& param, + void (*hangup)(FileDescriptor&)) { TestAddress const& listener = param.listener; TestAddress const& connector = param.connector; - constexpr int kBacklog = 2; - // Linux completes one more connection than the listen backlog argument. - // To ensure that there is at least one client connection that stays in - // connecting state, keep 2 more client connections than the listen backlog. - // gVisor differs in this behavior though, gvisor.dev/issue/3153. - constexpr int kClients = kBacklog + 2; + for (int i = 0; i < 100; i++) { + // Create the listening socket. + FileDescriptor listen_fd = ASSERT_NO_ERRNO_AND_VALUE( + Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP)); + sockaddr_storage listen_addr = listener.addr; + ASSERT_THAT(bind(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), + listener.addr_len), + SyscallSucceeds()); + ASSERT_THAT(listen(listen_fd.get(), 0), SyscallSucceeds()); + + // Get the port bound by the listening socket. + socklen_t addrlen = listener.addr_len; + ASSERT_THAT( + getsockname(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), + &addrlen), + SyscallSucceeds()); + uint16_t const port = + ASSERT_NO_ERRNO_AND_VALUE(AddrPort(listener.family(), listen_addr)); + + sockaddr_storage conn_addr = connector.addr; + ASSERT_NO_ERRNO(SetAddrPort(connector.family(), &conn_addr, port)); + + // Connect asynchronously and immediately hang up the listener. + FileDescriptor client = ASSERT_NO_ERRNO_AND_VALUE( + Socket(connector.family(), SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP)); + int ret = connect(client.get(), reinterpret_cast<sockaddr*>(&conn_addr), + connector.addr_len); + if (ret != 0) { + EXPECT_THAT(ret, SyscallFailsWithErrno(EINPROGRESS)); + } + + hangup(listen_fd); + + // Wait for the connection to close. + struct pollfd pfd = { + .fd = client.get(), + }; + constexpr int kTimeout = 10000; + int n = poll(&pfd, 1, kTimeout); + ASSERT_GE(n, 0) << strerror(errno); + ASSERT_EQ(n, 1); + ASSERT_EQ(pfd.revents, POLLHUP | POLLERR); + ASSERT_EQ(close(client.release()), 0) << strerror(errno); + } +} + +TEST_P(SocketInetLoopbackTest, TCPListenCloseDuringConnect) { + TestHangupDuringConnect(GetParam(), [](FileDescriptor& f) { + ASSERT_THAT(close(f.release()), SyscallSucceeds()); + }); +} + +TEST_P(SocketInetLoopbackTest, TCPListenShutdownDuringConnect) { + TestHangupDuringConnect(GetParam(), [](FileDescriptor& f) { + ASSERT_THAT(shutdown(f.get(), SHUT_RD), SyscallSucceeds()); + }); +} + +void TestListenHangupConnectingRead(const TestParam& param, + void (*hangup)(FileDescriptor&)) { + TestAddress const& listener = param.listener; + TestAddress const& connector = param.connector; // Create the listening socket. FileDescriptor listen_fd = ASSERT_NO_ERRNO_AND_VALUE( Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP)); sockaddr_storage listen_addr = listener.addr; - ASSERT_THAT(bind(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), - listener.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(listen_fd.get(), AsSockAddr(&listen_addr), listener.addr_len), + SyscallSucceeds()); + // This test is only interested in deterministically getting a socket in + // connecting state. For that, we use a listen backlog of zero which would + // mean there is exactly one connection that gets established and is enqueued + // to the accept queue. We poll on the listener to ensure that is enqueued. + // After that the subsequent client connect will stay in connecting state as + // the accept queue is full. + constexpr int kBacklog = 0; ASSERT_THAT(listen(listen_fd.get(), kBacklog), SyscallSucceeds()); // Get the port bound by the listening socket. socklen_t addrlen = listener.addr_len; - ASSERT_THAT(getsockname(listen_fd.get(), - reinterpret_cast<sockaddr*>(&listen_addr), &addrlen), + ASSERT_THAT(getsockname(listen_fd.get(), AsSockAddr(&listen_addr), &addrlen), SyscallSucceeds()); uint16_t const port = ASSERT_NO_ERRNO_AND_VALUE(AddrPort(listener.family(), listen_addr)); sockaddr_storage conn_addr = connector.addr; ASSERT_NO_ERRNO(SetAddrPort(connector.family(), &conn_addr, port)); - std::vector<FileDescriptor> clients; - for (int i = 0; i < kClients; i++) { - FileDescriptor client = ASSERT_NO_ERRNO_AND_VALUE( - Socket(connector.family(), SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP)); - int ret = connect(client.get(), reinterpret_cast<sockaddr*>(&conn_addr), - connector.addr_len); - if (ret != 0) { - EXPECT_THAT(ret, SyscallFailsWithErrno(EINPROGRESS)); - clients.push_back(std::move(client)); - } + FileDescriptor established_client = ASSERT_NO_ERRNO_AND_VALUE( + Socket(connector.family(), SOCK_STREAM, IPPROTO_TCP)); + ASSERT_THAT(connect(established_client.get(), AsSockAddr(&conn_addr), + connector.addr_len), + SyscallSucceeds()); + + // Ensure that the accept queue has the completed connection. + constexpr int kTimeout = 10000; + pollfd pfd = { + .fd = listen_fd.get(), + .events = POLLIN, + }; + ASSERT_THAT(poll(&pfd, 1, kTimeout), SyscallSucceedsWithValue(1)); + ASSERT_EQ(pfd.revents, POLLIN); + + FileDescriptor connecting_client = ASSERT_NO_ERRNO_AND_VALUE( + Socket(connector.family(), SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP)); + // Keep the last client in connecting state. + int ret = connect(connecting_client.get(), AsSockAddr(&conn_addr), + connector.addr_len); + if (ret != 0) { + EXPECT_THAT(ret, SyscallFailsWithErrno(EINPROGRESS)); } - stopListen(listen_fd); + hangup(listen_fd); - for (auto& client : clients) { - constexpr int kTimeout = 10000; + std::array<std::pair<int, int>, 2> sockets = { + std::make_pair(established_client.get(), ECONNRESET), + std::make_pair(connecting_client.get(), ECONNREFUSED), + }; + for (size_t i = 0; i < sockets.size(); i++) { + SCOPED_TRACE(absl::StrCat("i=", i)); + auto [fd, expected_errno] = sockets[i]; pollfd pfd = { - .fd = client.get(), - .events = POLLIN, + .fd = fd, }; - // When the listening socket is closed, then we expect the remote to reset - // the connection. - ASSERT_THAT(poll(&pfd, 1, kTimeout), SyscallSucceedsWithValue(1)); - ASSERT_EQ(pfd.revents, POLLIN | POLLHUP | POLLERR); + // When the listening socket is closed, the peer would reset the connection. + EXPECT_THAT(poll(&pfd, 1, kTimeout), SyscallSucceedsWithValue(1)); + EXPECT_EQ(pfd.revents, POLLHUP | POLLERR); char c; - // Subsequent read can fail with: - // ECONNRESET: If the client connection was established and was reset by the - // remote. - // ECONNREFUSED: If the client connection failed to be established. - ASSERT_THAT(read(client.get(), &c, sizeof(c)), - AnyOf(SyscallFailsWithErrno(ECONNRESET), - SyscallFailsWithErrno(ECONNREFUSED))); - // The last client connection would be in connecting (SYN_SENT) state. - if (client.get() == clients[kClients - 1].get()) { - ASSERT_EQ(errno, ECONNREFUSED) << strerror(errno); - } + EXPECT_THAT(read(fd, &c, sizeof(c)), SyscallFailsWithErrno(expected_errno)); } } -TEST_P(SocketInetLoopbackTest, TCPListenCloseWhileConnect) { - TestListenWhileConnect(GetParam(), [](FileDescriptor& f) { +TEST_P(SocketInetLoopbackTest, TCPListenCloseConnectingRead) { + TestListenHangupConnectingRead(GetParam(), [](FileDescriptor& f) { ASSERT_THAT(close(f.release()), SyscallSucceeds()); }); } -TEST_P(SocketInetLoopbackTest, TCPListenShutdownWhileConnect) { - TestListenWhileConnect(GetParam(), [](FileDescriptor& f) { +TEST_P(SocketInetLoopbackTest, TCPListenShutdownConnectingRead) { + TestListenHangupConnectingRead(GetParam(), [](FileDescriptor& f) { ASSERT_THAT(shutdown(f.get(), SHUT_RD), SyscallSucceeds()); }); } -// TODO(b/157236388): Remove _NoRandomSave once bug is fixed. Test fails w/ +// TODO(b/157236388): Remove once bug is fixed. Test fails w/ // random save as established connections which can't be delivered to the accept // queue because the queue is full are not correctly delivered after restore // causing the last accept to timeout on the restore. -TEST_P(SocketInetLoopbackTest, TCPbacklog_NoRandomSave) { +TEST_P(SocketInetLoopbackTest, TCPAcceptBacklogSizes) { auto const& param = GetParam(); TestAddress const& listener = param.listener; @@ -580,21 +635,70 @@ TEST_P(SocketInetLoopbackTest, TCPbacklog_NoRandomSave) { const FileDescriptor listen_fd = ASSERT_NO_ERRNO_AND_VALUE( Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP)); sockaddr_storage listen_addr = listener.addr; - ASSERT_THAT(bind(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), - listener.addr_len), + ASSERT_THAT( + bind(listen_fd.get(), AsSockAddr(&listen_addr), listener.addr_len), + SyscallSucceeds()); + // Get the port bound by the listening socket. + socklen_t addrlen = listener.addr_len; + ASSERT_THAT(getsockname(listen_fd.get(), AsSockAddr(&listen_addr), &addrlen), SyscallSucceeds()); + uint16_t const port = + ASSERT_NO_ERRNO_AND_VALUE(AddrPort(listener.family(), listen_addr)); + std::array<int, 3> backlogs = {-1, 0, 1}; + for (auto& backlog : backlogs) { + ASSERT_THAT(listen(listen_fd.get(), backlog), SyscallSucceeds()); + + int expected_accepts; + if (backlog < 0) { + expected_accepts = 1024; + } else { + expected_accepts = backlog + 1; + } + for (int i = 0; i < expected_accepts; i++) { + SCOPED_TRACE(absl::StrCat("i=", i)); + // Connect to the listening socket. + const FileDescriptor conn_fd = ASSERT_NO_ERRNO_AND_VALUE( + Socket(connector.family(), SOCK_STREAM, IPPROTO_TCP)); + sockaddr_storage conn_addr = connector.addr; + ASSERT_NO_ERRNO(SetAddrPort(connector.family(), &conn_addr, port)); + ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(), AsSockAddr(&conn_addr), + connector.addr_len), + SyscallSucceeds()); + const FileDescriptor accepted = + ASSERT_NO_ERRNO_AND_VALUE(Accept(listen_fd.get(), nullptr, nullptr)); + } + } +} + +// TODO(b/157236388): Remove once bug is fixed. Test fails w/ +// random save as established connections which can't be delivered to the accept +// queue because the queue is full are not correctly delivered after restore +// causing the last accept to timeout on the restore. +TEST_P(SocketInetLoopbackTest, TCPBacklog) { + auto const& param = GetParam(); + + TestAddress const& listener = param.listener; + TestAddress const& connector = param.connector; + + // Create the listening socket. + const FileDescriptor listen_fd = ASSERT_NO_ERRNO_AND_VALUE( + Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP)); + sockaddr_storage listen_addr = listener.addr; + ASSERT_THAT( + bind(listen_fd.get(), AsSockAddr(&listen_addr), listener.addr_len), + SyscallSucceeds()); constexpr int kBacklogSize = 2; ASSERT_THAT(listen(listen_fd.get(), kBacklogSize), SyscallSucceeds()); // Get the port bound by the listening socket. socklen_t addrlen = listener.addr_len; - ASSERT_THAT(getsockname(listen_fd.get(), - reinterpret_cast<sockaddr*>(&listen_addr), &addrlen), + ASSERT_THAT(getsockname(listen_fd.get(), AsSockAddr(&listen_addr), &addrlen), SyscallSucceeds()); uint16_t const port = ASSERT_NO_ERRNO_AND_VALUE(AddrPort(listener.family(), listen_addr)); int i = 0; while (1) { + SCOPED_TRACE(absl::StrCat("i=", i)); int ret; // Connect to the listening socket. @@ -602,8 +706,7 @@ TEST_P(SocketInetLoopbackTest, TCPbacklog_NoRandomSave) { Socket(connector.family(), SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP)); sockaddr_storage conn_addr = connector.addr; ASSERT_NO_ERRNO(SetAddrPort(connector.family(), &conn_addr, port)); - ret = connect(conn_fd.get(), reinterpret_cast<sockaddr*>(&conn_addr), - connector.addr_len); + ret = connect(conn_fd.get(), AsSockAddr(&conn_addr), connector.addr_len); if (ret != 0) { EXPECT_THAT(ret, SyscallFailsWithErrno(EINPROGRESS)); pollfd pfd = { @@ -620,103 +723,130 @@ TEST_P(SocketInetLoopbackTest, TCPbacklog_NoRandomSave) { i++; } + int client_conns = i; + int accepted_conns = 0; for (; i != 0; i--) { - // Accept the connection. - // - // We have to assign a name to the accepted socket, as unamed temporary - // objects are destructed upon full evaluation of the expression it is in, - // potentially causing the connecting socket to fail to shutdown properly. - auto accepted = - ASSERT_NO_ERRNO_AND_VALUE(Accept(listen_fd.get(), nullptr, nullptr)); + SCOPED_TRACE(absl::StrCat("i=", i)); + pollfd pfd = { + .fd = listen_fd.get(), + .events = POLLIN, + }; + // Look for incoming connections to accept. The last connect request could + // be established from the client side, but the ACK of the handshake could + // be dropped by the listener if the accept queue was filled up by the + // previous connect. + int ret; + ASSERT_THAT(ret = poll(&pfd, 1, 3000), SyscallSucceeds()); + if (ret == 0) break; + if (pfd.revents == POLLIN) { + // Accept the connection. + // + // We have to assign a name to the accepted socket, as unamed temporary + // objects are destructed upon full evaluation of the expression it is in, + // potentially causing the connecting socket to fail to shutdown properly. + auto accepted = + ASSERT_NO_ERRNO_AND_VALUE(Accept(listen_fd.get(), nullptr, nullptr)); + accepted_conns++; + } } + // We should accept at least listen backlog + 1 connections. As the stack is + // enqueuing established connections to the accept queue, newer SYNs could + // still be replied to causing those client connections would be accepted as + // we start dequeuing the queue. + ASSERT_GE(accepted_conns, kBacklogSize + 1); + ASSERT_GE(client_conns, accepted_conns); } -// Test if the stack completes atmost listen backlog number of client -// connections. It exercises the path of the stack that enqueues completed -// connections to accept queue vs new incoming SYNs. -TEST_P(SocketInetLoopbackTest, TCPConnectBacklog_NoRandomSave) { - const auto& param = GetParam(); - const TestAddress& listener = param.listener; - const TestAddress& connector = param.connector; +// TODO(b/157236388): Remove once bug is fixed. Test fails w/ +// random save as established connections which can't be delivered to the accept +// queue because the queue is full are not correctly delivered after restore +// causing the last accept to timeout on the restore. +TEST_P(SocketInetLoopbackTest, TCPBacklogAcceptAll) { + auto const& param = GetParam(); + TestAddress const& listener = param.listener; + TestAddress const& connector = param.connector; + // Create the listening socket. + FileDescriptor listen_fd = ASSERT_NO_ERRNO_AND_VALUE( + Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP)); + sockaddr_storage listen_addr = listener.addr; + ASSERT_THAT( + bind(listen_fd.get(), AsSockAddr(&listen_addr), listener.addr_len), + SyscallSucceeds()); constexpr int kBacklog = 1; - // Keep the number of client connections more than the listen backlog. - // Linux completes one more connection than the listen backlog argument. - // gVisor differs in this behavior though, gvisor.dev/issue/3153. - int kClients = kBacklog + 2; - if (IsRunningOnGvisor()) { - kClients--; - } + ASSERT_THAT(listen(listen_fd.get(), kBacklog), SyscallSucceeds()); - // Run the following test for few iterations to test race between accept queue - // getting filled with incoming SYNs. - for (int num = 0; num < 10; num++) { - FileDescriptor listen_fd = ASSERT_NO_ERRNO_AND_VALUE( - Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP)); - sockaddr_storage listen_addr = listener.addr; - ASSERT_THAT(bind(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), - listener.addr_len), - SyscallSucceeds()); - ASSERT_THAT(listen(listen_fd.get(), kBacklog), SyscallSucceeds()); + // Get the port bound by the listening socket. + socklen_t addrlen = listener.addr_len; + ASSERT_THAT(getsockname(listen_fd.get(), AsSockAddr(&listen_addr), &addrlen), + SyscallSucceeds()); + uint16_t const port = + ASSERT_NO_ERRNO_AND_VALUE(AddrPort(listener.family(), listen_addr)); - socklen_t addrlen = listener.addr_len; - ASSERT_THAT( - getsockname(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), - &addrlen), - SyscallSucceeds()); - uint16_t const port = - ASSERT_NO_ERRNO_AND_VALUE(AddrPort(listener.family(), listen_addr)); - sockaddr_storage conn_addr = connector.addr; - ASSERT_NO_ERRNO(SetAddrPort(connector.family(), &conn_addr, port)); + sockaddr_storage conn_addr = connector.addr; + ASSERT_NO_ERRNO(SetAddrPort(connector.family(), &conn_addr, port)); - std::vector<FileDescriptor> clients; - // Issue multiple non-blocking client connects. - for (int i = 0; i < kClients; i++) { - FileDescriptor client = ASSERT_NO_ERRNO_AND_VALUE( - Socket(connector.family(), SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP)); - int ret = connect(client.get(), reinterpret_cast<sockaddr*>(&conn_addr), - connector.addr_len); - if (ret != 0) { - EXPECT_THAT(ret, SyscallFailsWithErrno(EINPROGRESS)); - } - clients.push_back(std::move(client)); + // Fill up the accept queue and trigger more client connections which would be + // waiting to be accepted. + std::array<FileDescriptor, kBacklog + 1> established_clients; + for (auto& fd : established_clients) { + fd = ASSERT_NO_ERRNO_AND_VALUE( + Socket(connector.family(), SOCK_STREAM, IPPROTO_TCP)); + ASSERT_THAT(connect(fd.get(), AsSockAddr(&conn_addr), connector.addr_len), + SyscallSucceeds()); + } + std::array<FileDescriptor, kBacklog> waiting_clients; + for (auto& fd : waiting_clients) { + fd = ASSERT_NO_ERRNO_AND_VALUE( + Socket(connector.family(), SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP)); + int ret = connect(fd.get(), AsSockAddr(&conn_addr), connector.addr_len); + if (ret != 0) { + EXPECT_THAT(ret, SyscallFailsWithErrno(EINPROGRESS)); } + } - // Now that client connects are issued, wait for the accept queue to get - // filled and ensure no new client connection is completed. - for (int i = 0; i < kClients; i++) { - pollfd pfd = { - .fd = clients[i].get(), - .events = POLLOUT, - }; - if (i < kClients - 1) { - // Poll for client side connection completions with a large timeout. - // We cannot poll on the listener side without calling accept as poll - // stays level triggered with non-zero accept queue length. - // - // Client side poll would not guarantee that the completed connection - // has been enqueued in to the acccept queue, but the fact that the - // listener ACKd the SYN, means that it cannot complete any new incoming - // SYNs when it has already ACKd for > backlog number of SYNs. - ASSERT_THAT(poll(&pfd, 1, 10000), SyscallSucceedsWithValue(1)) - << "num=" << num << " i=" << i << " kClients=" << kClients; - ASSERT_EQ(pfd.revents, POLLOUT) << "num=" << num << " i=" << i; - } else { - // Now that we expect accept queue filled up, ensure that the last - // client connection never completes with a smaller poll timeout. - ASSERT_THAT(poll(&pfd, 1, 1000), SyscallSucceedsWithValue(0)) - << "num=" << num << " i=" << i; - } + auto accept_connection = [&]() { + constexpr int kTimeout = 10000; + pollfd pfd = { + .fd = listen_fd.get(), + .events = POLLIN, + }; + ASSERT_THAT(poll(&pfd, 1, kTimeout), SyscallSucceedsWithValue(1)); + ASSERT_EQ(pfd.revents, POLLIN); + // Accept the connection. + // + // We have to assign a name to the accepted socket, as unamed temporary + // objects are destructed upon full evaluation of the expression it is in, + // potentially causing the connecting socket to fail to shutdown properly. + auto accepted = + ASSERT_NO_ERRNO_AND_VALUE(Accept(listen_fd.get(), nullptr, nullptr)); + }; - ASSERT_THAT(close(clients[i].release()), SyscallSucceedsWithValue(0)) - << "num=" << num << " i=" << i; - } - clients.clear(); - // We close the listening side and open a new listener. We could instead - // drain the accept queue by calling accept() and reuse the listener, but - // that is racy as the retransmitted SYNs could get ACKd as we make room in - // the accept queue. - ASSERT_THAT(close(listen_fd.release()), SyscallSucceedsWithValue(0)); + // Ensure that we accept all client connections. The waiting connections would + // get enqueued as we drain the accept queue. + for (int i = 0; i < std::size(established_clients); i++) { + SCOPED_TRACE(absl::StrCat("established clients i=", i)); + accept_connection(); + } + + // The waiting client connections could be in one of these 2 states: + // (1) SYN_SENT: if the SYN was dropped because accept queue was full + // (2) ESTABLISHED: if the listener sent back a SYNACK, but may have dropped + // the ACK from the client if the accept queue was full (send out a data to + // re-send that ACK, to address that case). + for (int i = 0; i < std::size(waiting_clients); i++) { + SCOPED_TRACE(absl::StrCat("waiting clients i=", i)); + constexpr int kTimeout = 10000; + pollfd pfd = { + .fd = waiting_clients[i].get(), + .events = POLLOUT, + }; + EXPECT_THAT(poll(&pfd, 1, kTimeout), SyscallSucceedsWithValue(1)); + EXPECT_EQ(pfd.revents, POLLOUT); + char c; + EXPECT_THAT(RetryEINTR(send)(waiting_clients[i].get(), &c, sizeof(c), 0), + SyscallSucceedsWithValue(sizeof(c))); + accept_connection(); } } @@ -728,7 +858,7 @@ TEST_P(SocketInetLoopbackTest, TCPConnectBacklog_NoRandomSave) { // // TCP timers are not S/R today, this can cause this test to be flaky when run // under random S/R due to timer being reset on a restore. -TEST_P(SocketInetLoopbackTest, TCPFinWait2Test_NoRandomSave) { +TEST_P(SocketInetLoopbackTest, TCPFinWait2Test) { auto const& param = GetParam(); TestAddress const& listener = param.listener; TestAddress const& connector = param.connector; @@ -737,15 +867,14 @@ TEST_P(SocketInetLoopbackTest, TCPFinWait2Test_NoRandomSave) { const FileDescriptor listen_fd = ASSERT_NO_ERRNO_AND_VALUE( Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP)); sockaddr_storage listen_addr = listener.addr; - ASSERT_THAT(bind(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), - listener.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(listen_fd.get(), AsSockAddr(&listen_addr), listener.addr_len), + SyscallSucceeds()); ASSERT_THAT(listen(listen_fd.get(), SOMAXCONN), SyscallSucceeds()); // Get the port bound by the listening socket. socklen_t addrlen = listener.addr_len; - ASSERT_THAT(getsockname(listen_fd.get(), - reinterpret_cast<sockaddr*>(&listen_addr), &addrlen), + ASSERT_THAT(getsockname(listen_fd.get(), AsSockAddr(&listen_addr), &addrlen), SyscallSucceeds()); uint16_t const port = @@ -763,8 +892,7 @@ TEST_P(SocketInetLoopbackTest, TCPFinWait2Test_NoRandomSave) { sockaddr_storage conn_addr = connector.addr; ASSERT_NO_ERRNO(SetAddrPort(connector.family(), &conn_addr, port)); - ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(), - reinterpret_cast<sockaddr*>(&conn_addr), + ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(), AsSockAddr(&conn_addr), connector.addr_len), SyscallSucceeds()); @@ -776,8 +904,7 @@ TEST_P(SocketInetLoopbackTest, TCPFinWait2Test_NoRandomSave) { sockaddr_storage conn_bound_addr; socklen_t conn_addrlen = connector.addr_len; ASSERT_THAT( - getsockname(conn_fd.get(), reinterpret_cast<sockaddr*>(&conn_bound_addr), - &conn_addrlen), + getsockname(conn_fd.get(), AsSockAddr(&conn_bound_addr), &conn_addrlen), SyscallSucceeds()); // close the connecting FD to trigger FIN_WAIT2 on the connected fd. @@ -792,8 +919,7 @@ TEST_P(SocketInetLoopbackTest, TCPFinWait2Test_NoRandomSave) { // be restarted causing the final bind/connect to fail. DisableSave ds; - ASSERT_THAT(bind(conn_fd2.get(), - reinterpret_cast<sockaddr*>(&conn_bound_addr), conn_addrlen), + ASSERT_THAT(bind(conn_fd2.get(), AsSockAddr(&conn_bound_addr), conn_addrlen), SyscallFailsWithErrno(EADDRINUSE)); // Sleep for a little over the linger timeout to reduce flakiness in @@ -802,10 +928,9 @@ TEST_P(SocketInetLoopbackTest, TCPFinWait2Test_NoRandomSave) { ds.reset(); - ASSERT_THAT(RetryEINTR(connect)(conn_fd2.get(), - reinterpret_cast<sockaddr*>(&conn_addr), - conn_addrlen), - SyscallSucceeds()); + ASSERT_THAT( + RetryEINTR(connect)(conn_fd2.get(), AsSockAddr(&conn_addr), conn_addrlen), + SyscallSucceeds()); } // TCPLinger2TimeoutAfterClose creates a pair of connected sockets @@ -815,7 +940,7 @@ TEST_P(SocketInetLoopbackTest, TCPFinWait2Test_NoRandomSave) { // // TCP timers are not S/R today, this can cause this test to be flaky when run // under random S/R due to timer being reset on a restore. -TEST_P(SocketInetLoopbackTest, TCPLinger2TimeoutAfterClose_NoRandomSave) { +TEST_P(SocketInetLoopbackTest, TCPLinger2TimeoutAfterClose) { auto const& param = GetParam(); TestAddress const& listener = param.listener; TestAddress const& connector = param.connector; @@ -824,15 +949,14 @@ TEST_P(SocketInetLoopbackTest, TCPLinger2TimeoutAfterClose_NoRandomSave) { const FileDescriptor listen_fd = ASSERT_NO_ERRNO_AND_VALUE( Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP)); sockaddr_storage listen_addr = listener.addr; - ASSERT_THAT(bind(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), - listener.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(listen_fd.get(), AsSockAddr(&listen_addr), listener.addr_len), + SyscallSucceeds()); ASSERT_THAT(listen(listen_fd.get(), SOMAXCONN), SyscallSucceeds()); // Get the port bound by the listening socket. socklen_t addrlen = listener.addr_len; - ASSERT_THAT(getsockname(listen_fd.get(), - reinterpret_cast<sockaddr*>(&listen_addr), &addrlen), + ASSERT_THAT(getsockname(listen_fd.get(), AsSockAddr(&listen_addr), &addrlen), SyscallSucceeds()); uint16_t const port = @@ -844,8 +968,7 @@ TEST_P(SocketInetLoopbackTest, TCPLinger2TimeoutAfterClose_NoRandomSave) { sockaddr_storage conn_addr = connector.addr; ASSERT_NO_ERRNO(SetAddrPort(connector.family(), &conn_addr, port)); - ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(), - reinterpret_cast<sockaddr*>(&conn_addr), + ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(), AsSockAddr(&conn_addr), connector.addr_len), SyscallSucceeds()); @@ -857,8 +980,7 @@ TEST_P(SocketInetLoopbackTest, TCPLinger2TimeoutAfterClose_NoRandomSave) { sockaddr_storage conn_bound_addr; socklen_t conn_addrlen = connector.addr_len; ASSERT_THAT( - getsockname(conn_fd.get(), reinterpret_cast<sockaddr*>(&conn_bound_addr), - &conn_addrlen), + getsockname(conn_fd.get(), AsSockAddr(&conn_bound_addr), &conn_addrlen), SyscallSucceeds()); // Disable cooperative saves after this point as TCP timers are not restored @@ -884,13 +1006,11 @@ TEST_P(SocketInetLoopbackTest, TCPLinger2TimeoutAfterClose_NoRandomSave) { const FileDescriptor conn_fd2 = ASSERT_NO_ERRNO_AND_VALUE( Socket(connector.family(), SOCK_STREAM, IPPROTO_TCP)); - ASSERT_THAT(bind(conn_fd2.get(), - reinterpret_cast<sockaddr*>(&conn_bound_addr), conn_addrlen), - SyscallSucceeds()); - ASSERT_THAT(RetryEINTR(connect)(conn_fd2.get(), - reinterpret_cast<sockaddr*>(&conn_addr), - conn_addrlen), + ASSERT_THAT(bind(conn_fd2.get(), AsSockAddr(&conn_bound_addr), conn_addrlen), SyscallSucceeds()); + ASSERT_THAT( + RetryEINTR(connect)(conn_fd2.get(), AsSockAddr(&conn_addr), conn_addrlen), + SyscallSucceeds()); } // TCPResetAfterClose creates a pair of connected sockets then closes @@ -906,15 +1026,14 @@ TEST_P(SocketInetLoopbackTest, TCPResetAfterClose) { const FileDescriptor listen_fd = ASSERT_NO_ERRNO_AND_VALUE( Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP)); sockaddr_storage listen_addr = listener.addr; - ASSERT_THAT(bind(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), - listener.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(listen_fd.get(), AsSockAddr(&listen_addr), listener.addr_len), + SyscallSucceeds()); ASSERT_THAT(listen(listen_fd.get(), SOMAXCONN), SyscallSucceeds()); // Get the port bound by the listening socket. socklen_t addrlen = listener.addr_len; - ASSERT_THAT(getsockname(listen_fd.get(), - reinterpret_cast<sockaddr*>(&listen_addr), &addrlen), + ASSERT_THAT(getsockname(listen_fd.get(), AsSockAddr(&listen_addr), &addrlen), SyscallSucceeds()); uint16_t const port = @@ -926,8 +1045,7 @@ TEST_P(SocketInetLoopbackTest, TCPResetAfterClose) { sockaddr_storage conn_addr = connector.addr; ASSERT_NO_ERRNO(SetAddrPort(connector.family(), &conn_addr, port)); - ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(), - reinterpret_cast<sockaddr*>(&conn_addr), + ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(), AsSockAddr(&conn_addr), connector.addr_len), SyscallSucceeds()); @@ -975,15 +1093,14 @@ void setupTimeWaitClose(const TestAddress* listener, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); } - ASSERT_THAT(bind(listen_fd.get(), reinterpret_cast<sockaddr*>(listen_addr), - listener->addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(listen_fd.get(), AsSockAddr(listen_addr), listener->addr_len), + SyscallSucceeds()); ASSERT_THAT(listen(listen_fd.get(), SOMAXCONN), SyscallSucceeds()); // Get the port bound by the listening socket. socklen_t addrlen = listener->addr_len; - ASSERT_THAT(getsockname(listen_fd.get(), - reinterpret_cast<sockaddr*>(listen_addr), &addrlen), + ASSERT_THAT(getsockname(listen_fd.get(), AsSockAddr(listen_addr), &addrlen), SyscallSucceeds()); uint16_t const port = @@ -1005,8 +1122,7 @@ void setupTimeWaitClose(const TestAddress* listener, sockaddr_storage conn_addr = connector->addr; ASSERT_NO_ERRNO(SetAddrPort(connector->family(), &conn_addr, port)); - ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(), - reinterpret_cast<sockaddr*>(&conn_addr), + ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(), AsSockAddr(&conn_addr), connector->addr_len), SyscallSucceeds()); @@ -1017,8 +1133,7 @@ void setupTimeWaitClose(const TestAddress* listener, // Get the address/port bound by the connecting socket. socklen_t conn_addrlen = connector->addr_len; ASSERT_THAT( - getsockname(conn_fd.get(), reinterpret_cast<sockaddr*>(conn_bound_addr), - &conn_addrlen), + getsockname(conn_fd.get(), AsSockAddr(conn_bound_addr), &conn_addrlen), SyscallSucceeds()); FileDescriptor active_closefd, passive_closefd; @@ -1064,7 +1179,7 @@ void setupTimeWaitClose(const TestAddress* listener, // // Test re-binding of client and server bound addresses when the older // connection is in TIME_WAIT. -TEST_P(SocketInetLoopbackTest, TCPPassiveCloseNoTimeWaitTest_NoRandomSave) { +TEST_P(SocketInetLoopbackTest, TCPPassiveCloseNoTimeWaitTest) { auto const& param = GetParam(); sockaddr_storage listen_addr, conn_bound_addr; listen_addr = param.listener.addr; @@ -1075,19 +1190,18 @@ TEST_P(SocketInetLoopbackTest, TCPPassiveCloseNoTimeWaitTest_NoRandomSave) { // bound by the conn_fd as it never entered TIME_WAIT. const FileDescriptor conn_fd = ASSERT_NO_ERRNO_AND_VALUE( Socket(param.connector.family(), SOCK_STREAM, IPPROTO_TCP)); - ASSERT_THAT(bind(conn_fd.get(), reinterpret_cast<sockaddr*>(&conn_bound_addr), + ASSERT_THAT(bind(conn_fd.get(), AsSockAddr(&conn_bound_addr), param.connector.addr_len), SyscallSucceeds()); FileDescriptor listen_fd = ASSERT_NO_ERRNO_AND_VALUE( Socket(param.listener.family(), SOCK_STREAM, IPPROTO_TCP)); - ASSERT_THAT(bind(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), - param.listener.addr_len), - SyscallFailsWithErrno(EADDRINUSE)); + ASSERT_THAT( + bind(listen_fd.get(), AsSockAddr(&listen_addr), param.listener.addr_len), + SyscallFailsWithErrno(EADDRINUSE)); } -TEST_P(SocketInetLoopbackTest, - TCPPassiveCloseNoTimeWaitReuseTest_NoRandomSave) { +TEST_P(SocketInetLoopbackTest, TCPPassiveCloseNoTimeWaitReuseTest) { auto const& param = GetParam(); sockaddr_storage listen_addr, conn_bound_addr; listen_addr = param.listener.addr; @@ -1099,9 +1213,9 @@ TEST_P(SocketInetLoopbackTest, ASSERT_THAT(setsockopt(listen_fd.get(), SOL_SOCKET, SO_REUSEADDR, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), - param.listener.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(listen_fd.get(), AsSockAddr(&listen_addr), param.listener.addr_len), + SyscallSucceeds()); ASSERT_THAT(listen(listen_fd.get(), SOMAXCONN), SyscallSucceeds()); // Now bind and connect new socket and verify that we can immediately rebind @@ -1111,7 +1225,7 @@ TEST_P(SocketInetLoopbackTest, ASSERT_THAT(setsockopt(conn_fd.get(), SOL_SOCKET, SO_REUSEADDR, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(conn_fd.get(), reinterpret_cast<sockaddr*>(&conn_bound_addr), + ASSERT_THAT(bind(conn_fd.get(), AsSockAddr(&conn_bound_addr), param.connector.addr_len), SyscallSucceeds()); @@ -1119,13 +1233,12 @@ TEST_P(SocketInetLoopbackTest, ASSERT_NO_ERRNO_AND_VALUE(AddrPort(param.listener.family(), listen_addr)); sockaddr_storage conn_addr = param.connector.addr; ASSERT_NO_ERRNO(SetAddrPort(param.connector.family(), &conn_addr, port)); - ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(), - reinterpret_cast<sockaddr*>(&conn_addr), + ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(), AsSockAddr(&conn_addr), param.connector.addr_len), SyscallSucceeds()); } -TEST_P(SocketInetLoopbackTest, TCPActiveCloseTimeWaitTest_NoRandomSave) { +TEST_P(SocketInetLoopbackTest, TCPActiveCloseTimeWaitTest) { auto const& param = GetParam(); sockaddr_storage listen_addr, conn_bound_addr; listen_addr = param.listener.addr; @@ -1134,12 +1247,12 @@ TEST_P(SocketInetLoopbackTest, TCPActiveCloseTimeWaitTest_NoRandomSave) { FileDescriptor conn_fd = ASSERT_NO_ERRNO_AND_VALUE( Socket(param.connector.family(), SOCK_STREAM, IPPROTO_TCP)); - ASSERT_THAT(bind(conn_fd.get(), reinterpret_cast<sockaddr*>(&conn_bound_addr), + ASSERT_THAT(bind(conn_fd.get(), AsSockAddr(&conn_bound_addr), param.connector.addr_len), SyscallFailsWithErrno(EADDRINUSE)); } -TEST_P(SocketInetLoopbackTest, TCPActiveCloseTimeWaitReuseTest_NoRandomSave) { +TEST_P(SocketInetLoopbackTest, TCPActiveCloseTimeWaitReuseTest) { auto const& param = GetParam(); sockaddr_storage listen_addr, conn_bound_addr; listen_addr = param.listener.addr; @@ -1150,7 +1263,7 @@ TEST_P(SocketInetLoopbackTest, TCPActiveCloseTimeWaitReuseTest_NoRandomSave) { ASSERT_THAT(setsockopt(conn_fd.get(), SOL_SOCKET, SO_REUSEADDR, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(conn_fd.get(), reinterpret_cast<sockaddr*>(&conn_bound_addr), + ASSERT_THAT(bind(conn_fd.get(), AsSockAddr(&conn_bound_addr), param.connector.addr_len), SyscallFailsWithErrno(EADDRINUSE)); } @@ -1164,15 +1277,14 @@ TEST_P(SocketInetLoopbackTest, AcceptedInheritsTCPUserTimeout) { const FileDescriptor listen_fd = ASSERT_NO_ERRNO_AND_VALUE( Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP)); sockaddr_storage listen_addr = listener.addr; - ASSERT_THAT(bind(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), - listener.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(listen_fd.get(), AsSockAddr(&listen_addr), listener.addr_len), + SyscallSucceeds()); ASSERT_THAT(listen(listen_fd.get(), SOMAXCONN), SyscallSucceeds()); // Get the port bound by the listening socket. socklen_t addrlen = listener.addr_len; - ASSERT_THAT(getsockname(listen_fd.get(), - reinterpret_cast<sockaddr*>(&listen_addr), &addrlen), + ASSERT_THAT(getsockname(listen_fd.get(), AsSockAddr(&listen_addr), &addrlen), SyscallSucceeds()); const uint16_t port = @@ -1190,8 +1302,7 @@ TEST_P(SocketInetLoopbackTest, AcceptedInheritsTCPUserTimeout) { sockaddr_storage conn_addr = connector.addr; ASSERT_NO_ERRNO(SetAddrPort(connector.family(), &conn_addr, port)); - ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(), - reinterpret_cast<sockaddr*>(&conn_addr), + ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(), AsSockAddr(&conn_addr), connector.addr_len), SyscallSucceeds()); @@ -1218,17 +1329,16 @@ TEST_P(SocketInetLoopbackTest, TCPAcceptAfterReset) { const FileDescriptor listen_fd = ASSERT_NO_ERRNO_AND_VALUE( Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP)); sockaddr_storage listen_addr = listener.addr; - ASSERT_THAT(bind(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), - listener.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(listen_fd.get(), AsSockAddr(&listen_addr), listener.addr_len), + SyscallSucceeds()); ASSERT_THAT(listen(listen_fd.get(), SOMAXCONN), SyscallSucceeds()); // Get the port bound by the listening socket. { socklen_t addrlen = listener.addr_len; ASSERT_THAT( - getsockname(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), - &addrlen), + getsockname(listen_fd.get(), AsSockAddr(&listen_addr), &addrlen), SyscallSucceeds()); } @@ -1244,8 +1354,7 @@ TEST_P(SocketInetLoopbackTest, TCPAcceptAfterReset) { // TODO(b/157236388): Reenable Cooperative S/R once bug is fixed. DisableSave ds; - ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(), - reinterpret_cast<sockaddr*>(&conn_addr), + ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(), AsSockAddr(&conn_addr), connector.addr_len), SyscallSucceeds()); @@ -1272,8 +1381,8 @@ TEST_P(SocketInetLoopbackTest, TCPAcceptAfterReset) { sockaddr_storage accept_addr; socklen_t addrlen = sizeof(accept_addr); - auto accept_fd = ASSERT_NO_ERRNO_AND_VALUE(Accept( - listen_fd.get(), reinterpret_cast<sockaddr*>(&accept_addr), &addrlen)); + auto accept_fd = ASSERT_NO_ERRNO_AND_VALUE( + Accept(listen_fd.get(), AsSockAddr(&accept_addr), &addrlen)); ASSERT_EQ(addrlen, listener.addr_len); // Wait for accept_fd to process the RST. @@ -1311,15 +1420,14 @@ TEST_P(SocketInetLoopbackTest, TCPAcceptAfterReset) { sockaddr_storage peer_addr; socklen_t addrlen = sizeof(peer_addr); // The socket is not connected anymore and should return ENOTCONN. - ASSERT_THAT(getpeername(accept_fd.get(), - reinterpret_cast<sockaddr*>(&peer_addr), &addrlen), + ASSERT_THAT(getpeername(accept_fd.get(), AsSockAddr(&peer_addr), &addrlen), SyscallFailsWithErrno(ENOTCONN)); } } // TODO(gvisor.dev/issue/1688): Partially completed passive endpoints are not // saved. Enable S/R once issue is fixed. -TEST_P(SocketInetLoopbackTest, TCPDeferAccept_NoRandomSave) { +TEST_P(SocketInetLoopbackTest, TCPDeferAccept) { // TODO(gvisor.dev/issue/1688): Partially completed passive endpoints are not // saved. Enable S/R issue is fixed. DisableSave ds; @@ -1332,15 +1440,14 @@ TEST_P(SocketInetLoopbackTest, TCPDeferAccept_NoRandomSave) { const FileDescriptor listen_fd = ASSERT_NO_ERRNO_AND_VALUE( Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP)); sockaddr_storage listen_addr = listener.addr; - ASSERT_THAT(bind(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), - listener.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(listen_fd.get(), AsSockAddr(&listen_addr), listener.addr_len), + SyscallSucceeds()); ASSERT_THAT(listen(listen_fd.get(), SOMAXCONN), SyscallSucceeds()); // Get the port bound by the listening socket. socklen_t addrlen = listener.addr_len; - ASSERT_THAT(getsockname(listen_fd.get(), - reinterpret_cast<sockaddr*>(&listen_addr), &addrlen), + ASSERT_THAT(getsockname(listen_fd.get(), AsSockAddr(&listen_addr), &addrlen), SyscallSucceeds()); const uint16_t port = @@ -1358,8 +1465,7 @@ TEST_P(SocketInetLoopbackTest, TCPDeferAccept_NoRandomSave) { sockaddr_storage conn_addr = connector.addr; ASSERT_NO_ERRNO(SetAddrPort(connector.family(), &conn_addr, port)); - ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(), - reinterpret_cast<sockaddr*>(&conn_addr), + ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(), AsSockAddr(&conn_addr), connector.addr_len), SyscallSucceeds()); @@ -1401,7 +1507,7 @@ TEST_P(SocketInetLoopbackTest, TCPDeferAccept_NoRandomSave) { // TODO(gvisor.dev/issue/1688): Partially completed passive endpoints are not // saved. Enable S/R once issue is fixed. -TEST_P(SocketInetLoopbackTest, TCPDeferAcceptTimeout_NoRandomSave) { +TEST_P(SocketInetLoopbackTest, TCPDeferAcceptTimeout) { // TODO(gvisor.dev/issue/1688): Partially completed passive endpoints are not // saved. Enable S/R once issue is fixed. DisableSave ds; @@ -1414,15 +1520,14 @@ TEST_P(SocketInetLoopbackTest, TCPDeferAcceptTimeout_NoRandomSave) { const FileDescriptor listen_fd = ASSERT_NO_ERRNO_AND_VALUE( Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP)); sockaddr_storage listen_addr = listener.addr; - ASSERT_THAT(bind(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), - listener.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(listen_fd.get(), AsSockAddr(&listen_addr), listener.addr_len), + SyscallSucceeds()); ASSERT_THAT(listen(listen_fd.get(), SOMAXCONN), SyscallSucceeds()); // Get the port bound by the listening socket. socklen_t addrlen = listener.addr_len; - ASSERT_THAT(getsockname(listen_fd.get(), - reinterpret_cast<sockaddr*>(&listen_addr), &addrlen), + ASSERT_THAT(getsockname(listen_fd.get(), AsSockAddr(&listen_addr), &addrlen), SyscallSucceeds()); const uint16_t port = @@ -1440,8 +1545,7 @@ TEST_P(SocketInetLoopbackTest, TCPDeferAcceptTimeout_NoRandomSave) { sockaddr_storage conn_addr = connector.addr; ASSERT_NO_ERRNO(SetAddrPort(connector.family(), &conn_addr, port)); - ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(), - reinterpret_cast<sockaddr*>(&conn_addr), + ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(), AsSockAddr(&conn_addr), connector.addr_len), SyscallSucceeds()); @@ -1507,9 +1611,9 @@ INSTANTIATE_TEST_SUITE_P( using SocketInetReusePortTest = ::testing::TestWithParam<TestParam>; -// TODO(gvisor.dev/issue/940): Remove _NoRandomSave when portHint/stack.Seed is +// TODO(gvisor.dev/issue/940): Remove when portHint/stack.Seed is // saved/restored. -TEST_P(SocketInetReusePortTest, TcpPortReuseMultiThread_NoRandomSave) { +TEST_P(SocketInetReusePortTest, TcpPortReuseMultiThread) { auto const& param = GetParam(); TestAddress const& listener = param.listener; @@ -1529,9 +1633,8 @@ TEST_P(SocketInetReusePortTest, TcpPortReuseMultiThread_NoRandomSave) { ASSERT_THAT(setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT( - bind(fd, reinterpret_cast<sockaddr*>(&listen_addr), listener.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(fd, AsSockAddr(&listen_addr), listener.addr_len), + SyscallSucceeds()); ASSERT_THAT(listen(fd, 40), SyscallSucceeds()); // On the first bind we need to determine which port was bound. @@ -1542,8 +1645,7 @@ TEST_P(SocketInetReusePortTest, TcpPortReuseMultiThread_NoRandomSave) { // Get the port bound by the listening socket. socklen_t addrlen = listener.addr_len; ASSERT_THAT( - getsockname(listener_fds[0].get(), - reinterpret_cast<sockaddr*>(&listen_addr), &addrlen), + getsockname(listener_fds[0].get(), AsSockAddr(&listen_addr), &addrlen), SyscallSucceeds()); uint16_t const port = ASSERT_NO_ERRNO_AND_VALUE(AddrPort(listener.family(), listen_addr)); @@ -1601,10 +1703,9 @@ TEST_P(SocketInetReusePortTest, TcpPortReuseMultiThread_NoRandomSave) { for (int32_t i = 0; i < kConnectAttempts; i++) { const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE( Socket(connector.family(), SOCK_STREAM, IPPROTO_TCP)); - ASSERT_THAT( - RetryEINTR(connect)(fd.get(), reinterpret_cast<sockaddr*>(&conn_addr), - connector.addr_len), - SyscallSucceeds()); + ASSERT_THAT(RetryEINTR(connect)(fd.get(), AsSockAddr(&conn_addr), + connector.addr_len), + SyscallSucceeds()); EXPECT_THAT(RetryEINTR(send)(fd.get(), &i, sizeof(i), 0), SyscallSucceedsWithValue(sizeof(i))); @@ -1622,7 +1723,7 @@ TEST_P(SocketInetReusePortTest, TcpPortReuseMultiThread_NoRandomSave) { EquivalentWithin((kConnectAttempts / kThreadCount), 0.10)); } -TEST_P(SocketInetReusePortTest, UdpPortReuseMultiThread_NoRandomSave) { +TEST_P(SocketInetReusePortTest, UdpPortReuseMultiThread) { auto const& param = GetParam(); TestAddress const& listener = param.listener; @@ -1641,9 +1742,8 @@ TEST_P(SocketInetReusePortTest, UdpPortReuseMultiThread_NoRandomSave) { ASSERT_THAT(setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT( - bind(fd, reinterpret_cast<sockaddr*>(&listen_addr), listener.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(fd, AsSockAddr(&listen_addr), listener.addr_len), + SyscallSucceeds()); // On the first bind we need to determine which port was bound. if (i != 0) { @@ -1653,8 +1753,7 @@ TEST_P(SocketInetReusePortTest, UdpPortReuseMultiThread_NoRandomSave) { // Get the port bound by the listening socket. socklen_t addrlen = listener.addr_len; ASSERT_THAT( - getsockname(listener_fds[0].get(), - reinterpret_cast<sockaddr*>(&listen_addr), &addrlen), + getsockname(listener_fds[0].get(), AsSockAddr(&listen_addr), &addrlen), SyscallSucceeds()); uint16_t const port = ASSERT_NO_ERRNO_AND_VALUE(AddrPort(listener.family(), listen_addr)); @@ -1677,9 +1776,9 @@ TEST_P(SocketInetReusePortTest, UdpPortReuseMultiThread_NoRandomSave) { socklen_t addrlen = sizeof(addr); int data; - auto ret = RetryEINTR(recvfrom)( - listener_fds[i].get(), &data, sizeof(data), 0, - reinterpret_cast<struct sockaddr*>(&addr), &addrlen); + auto ret = + RetryEINTR(recvfrom)(listener_fds[i].get(), &data, sizeof(data), + 0, AsSockAddr(&addr), &addrlen); if (packets_received < kConnectAttempts) { ASSERT_THAT(ret, SyscallSucceedsWithValue(sizeof(data))); @@ -1697,10 +1796,10 @@ TEST_P(SocketInetReusePortTest, UdpPortReuseMultiThread_NoRandomSave) { // A response is required to synchronize with the main thread, // otherwise the main thread can send more than can fit into receive // queues. - EXPECT_THAT(RetryEINTR(sendto)( - listener_fds[i].get(), &data, sizeof(data), 0, - reinterpret_cast<sockaddr*>(&addr), addrlen), - SyscallSucceedsWithValue(sizeof(data))); + EXPECT_THAT( + RetryEINTR(sendto)(listener_fds[i].get(), &data, sizeof(data), + 0, AsSockAddr(&addr), addrlen), + SyscallSucceedsWithValue(sizeof(data))); } while (packets_received < kConnectAttempts); // Shutdown all sockets to wake up other threads. @@ -1713,10 +1812,10 @@ TEST_P(SocketInetReusePortTest, UdpPortReuseMultiThread_NoRandomSave) { for (int i = 0; i < kConnectAttempts; i++) { const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Socket(connector.family(), SOCK_DGRAM, 0)); - EXPECT_THAT(RetryEINTR(sendto)(fd.get(), &i, sizeof(i), 0, - reinterpret_cast<sockaddr*>(&conn_addr), - connector.addr_len), - SyscallSucceedsWithValue(sizeof(i))); + EXPECT_THAT( + RetryEINTR(sendto)(fd.get(), &i, sizeof(i), 0, AsSockAddr(&conn_addr), + connector.addr_len), + SyscallSucceedsWithValue(sizeof(i))); int data; EXPECT_THAT(RetryEINTR(recv)(fd.get(), &data, sizeof(data), 0), SyscallSucceedsWithValue(sizeof(data))); @@ -1735,7 +1834,7 @@ TEST_P(SocketInetReusePortTest, UdpPortReuseMultiThread_NoRandomSave) { EquivalentWithin((kConnectAttempts / kThreadCount), 0.10)); } -TEST_P(SocketInetReusePortTest, UdpPortReuseMultiThreadShort_NoRandomSave) { +TEST_P(SocketInetReusePortTest, UdpPortReuseMultiThreadShort) { auto const& param = GetParam(); TestAddress const& listener = param.listener; @@ -1757,9 +1856,8 @@ TEST_P(SocketInetReusePortTest, UdpPortReuseMultiThreadShort_NoRandomSave) { ASSERT_THAT(setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT( - bind(fd, reinterpret_cast<sockaddr*>(&listen_addr), listener.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(fd, AsSockAddr(&listen_addr), listener.addr_len), + SyscallSucceeds()); // On the first bind we need to determine which port was bound. if (i != 0) { @@ -1769,8 +1867,7 @@ TEST_P(SocketInetReusePortTest, UdpPortReuseMultiThreadShort_NoRandomSave) { // Get the port bound by the listening socket. socklen_t addrlen = listener.addr_len; ASSERT_THAT( - getsockname(listener_fds[0].get(), - reinterpret_cast<sockaddr*>(&listen_addr), &addrlen), + getsockname(listener_fds[0].get(), AsSockAddr(&listen_addr), &addrlen), SyscallSucceeds()); uint16_t const port = ASSERT_NO_ERRNO_AND_VALUE(AddrPort(listener.family(), listen_addr)); @@ -1787,8 +1884,7 @@ TEST_P(SocketInetReusePortTest, UdpPortReuseMultiThreadShort_NoRandomSave) { client_fds[i] = ASSERT_NO_ERRNO_AND_VALUE(Socket(connector.family(), SOCK_DGRAM, 0)); EXPECT_THAT(RetryEINTR(sendto)(client_fds[i].get(), &i, sizeof(i), 0, - reinterpret_cast<sockaddr*>(&conn_addr), - connector.addr_len), + AsSockAddr(&conn_addr), connector.addr_len), SyscallSucceedsWithValue(sizeof(i))); } ds.reset(); @@ -1797,8 +1893,7 @@ TEST_P(SocketInetReusePortTest, UdpPortReuseMultiThreadShort_NoRandomSave) { // not been change after save/restore. for (int i = 0; i < kConnectAttempts; i++) { EXPECT_THAT(RetryEINTR(sendto)(client_fds[i].get(), &i, sizeof(i), 0, - reinterpret_cast<sockaddr*>(&conn_addr), - connector.addr_len), + AsSockAddr(&conn_addr), connector.addr_len), SyscallSucceedsWithValue(sizeof(i))); } @@ -1826,9 +1921,8 @@ TEST_P(SocketInetReusePortTest, UdpPortReuseMultiThreadShort_NoRandomSave) { struct sockaddr_storage addr = {}; socklen_t addrlen = sizeof(addr); int data; - EXPECT_THAT(RetryEINTR(recvfrom)( - fd, &data, sizeof(data), 0, - reinterpret_cast<struct sockaddr*>(&addr), &addrlen), + EXPECT_THAT(RetryEINTR(recvfrom)(fd, &data, sizeof(data), 0, + AsSockAddr(&addr), &addrlen), SyscallSucceedsWithValue(sizeof(data))); uint16_t const port = ASSERT_NO_ERRNO_AND_VALUE(AddrPort(connector.family(), addr)); @@ -1882,14 +1976,13 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4MappedLoopbackOnlyReservesV4) { sockaddr_storage addr_dual = test_addr_dual.addr; const FileDescriptor fd_dual = ASSERT_NO_ERRNO_AND_VALUE( Socket(test_addr_dual.family(), param.type, 0)); - ASSERT_THAT(bind(fd_dual.get(), reinterpret_cast<sockaddr*>(&addr_dual), - test_addr_dual.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(fd_dual.get(), AsSockAddr(&addr_dual), test_addr_dual.addr_len), + SyscallSucceeds()); // Get the port that we bound. socklen_t addrlen = test_addr_dual.addr_len; - ASSERT_THAT(getsockname(fd_dual.get(), - reinterpret_cast<sockaddr*>(&addr_dual), &addrlen), + ASSERT_THAT(getsockname(fd_dual.get(), AsSockAddr(&addr_dual), &addrlen), SyscallSucceeds()); uint16_t const port = ASSERT_NO_ERRNO_AND_VALUE(AddrPort(test_addr_dual.family(), addr_dual)); @@ -1900,8 +1993,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4MappedLoopbackOnlyReservesV4) { ASSERT_NO_ERRNO(SetAddrPort(test_addr_v6.family(), &addr_v6, port)); const FileDescriptor fd_v6 = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr_v6.family(), param.type, 0)); - int ret = bind(fd_v6.get(), reinterpret_cast<sockaddr*>(&addr_v6), - test_addr_v6.addr_len); + int ret = bind(fd_v6.get(), AsSockAddr(&addr_v6), test_addr_v6.addr_len); if (ret == -1 && errno == EADDRINUSE) { // Port may have been in use. ASSERT_LT(i, 100); // Give up after 100 tries. @@ -1916,8 +2008,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4MappedLoopbackOnlyReservesV4) { ASSERT_NO_ERRNO(SetAddrPort(test_addr_v4.family(), &addr_v4, port)); const FileDescriptor fd_v4 = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr_v4.family(), param.type, 0)); - ASSERT_THAT(bind(fd_v4.get(), reinterpret_cast<sockaddr*>(&addr_v4), - test_addr_v4.addr_len), + ASSERT_THAT(bind(fd_v4.get(), AsSockAddr(&addr_v4), test_addr_v4.addr_len), SyscallFailsWithErrno(EADDRINUSE)); // No need to try again. @@ -1934,14 +2025,13 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4MappedAnyOnlyReservesV4) { sockaddr_storage addr_dual = test_addr_dual.addr; const FileDescriptor fd_dual = ASSERT_NO_ERRNO_AND_VALUE( Socket(test_addr_dual.family(), param.type, 0)); - ASSERT_THAT(bind(fd_dual.get(), reinterpret_cast<sockaddr*>(&addr_dual), - test_addr_dual.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(fd_dual.get(), AsSockAddr(&addr_dual), test_addr_dual.addr_len), + SyscallSucceeds()); // Get the port that we bound. socklen_t addrlen = test_addr_dual.addr_len; - ASSERT_THAT(getsockname(fd_dual.get(), - reinterpret_cast<sockaddr*>(&addr_dual), &addrlen), + ASSERT_THAT(getsockname(fd_dual.get(), AsSockAddr(&addr_dual), &addrlen), SyscallSucceeds()); uint16_t const port = ASSERT_NO_ERRNO_AND_VALUE(AddrPort(test_addr_dual.family(), addr_dual)); @@ -1952,8 +2042,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4MappedAnyOnlyReservesV4) { ASSERT_NO_ERRNO(SetAddrPort(test_addr_v6.family(), &addr_v6, port)); const FileDescriptor fd_v6 = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr_v6.family(), param.type, 0)); - int ret = bind(fd_v6.get(), reinterpret_cast<sockaddr*>(&addr_v6), - test_addr_v6.addr_len); + int ret = bind(fd_v6.get(), AsSockAddr(&addr_v6), test_addr_v6.addr_len); if (ret == -1 && errno == EADDRINUSE) { // Port may have been in use. ASSERT_LT(i, 100); // Give up after 100 tries. @@ -1968,8 +2057,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4MappedAnyOnlyReservesV4) { ASSERT_NO_ERRNO(SetAddrPort(test_addr_v4.family(), &addr_v4, port)); const FileDescriptor fd_v4 = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr_v4.family(), param.type, 0)); - ASSERT_THAT(bind(fd_v4.get(), reinterpret_cast<sockaddr*>(&addr_v4), - test_addr_v4.addr_len), + ASSERT_THAT(bind(fd_v4.get(), AsSockAddr(&addr_v4), test_addr_v4.addr_len), SyscallFailsWithErrno(EADDRINUSE)); // No need to try again. @@ -1985,14 +2073,13 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, DualStackV6AnyReservesEverything) { sockaddr_storage addr_dual = test_addr_dual.addr; const FileDescriptor fd_dual = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr_dual.family(), param.type, 0)); - ASSERT_THAT(bind(fd_dual.get(), reinterpret_cast<sockaddr*>(&addr_dual), - test_addr_dual.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(fd_dual.get(), AsSockAddr(&addr_dual), test_addr_dual.addr_len), + SyscallSucceeds()); // Get the port that we bound. socklen_t addrlen = test_addr_dual.addr_len; - ASSERT_THAT(getsockname(fd_dual.get(), - reinterpret_cast<sockaddr*>(&addr_dual), &addrlen), + ASSERT_THAT(getsockname(fd_dual.get(), AsSockAddr(&addr_dual), &addrlen), SyscallSucceeds()); uint16_t const port = ASSERT_NO_ERRNO_AND_VALUE(AddrPort(test_addr_dual.family(), addr_dual)); @@ -2003,8 +2090,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, DualStackV6AnyReservesEverything) { ASSERT_NO_ERRNO(SetAddrPort(test_addr_v6.family(), &addr_v6, port)); const FileDescriptor fd_v6 = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr_v6.family(), param.type, 0)); - ASSERT_THAT(bind(fd_v6.get(), reinterpret_cast<sockaddr*>(&addr_v6), - test_addr_v6.addr_len), + ASSERT_THAT(bind(fd_v6.get(), AsSockAddr(&addr_v6), test_addr_v6.addr_len), SyscallFailsWithErrno(EADDRINUSE)); // Verify that binding the v4 loopback on the same port with a v6 socket @@ -2015,10 +2101,9 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, DualStackV6AnyReservesEverything) { SetAddrPort(test_addr_v4_mapped.family(), &addr_v4_mapped, port)); const FileDescriptor fd_v4_mapped = ASSERT_NO_ERRNO_AND_VALUE( Socket(test_addr_v4_mapped.family(), param.type, 0)); - ASSERT_THAT( - bind(fd_v4_mapped.get(), reinterpret_cast<sockaddr*>(&addr_v4_mapped), - test_addr_v4_mapped.addr_len), - SyscallFailsWithErrno(EADDRINUSE)); + ASSERT_THAT(bind(fd_v4_mapped.get(), AsSockAddr(&addr_v4_mapped), + test_addr_v4_mapped.addr_len), + SyscallFailsWithErrno(EADDRINUSE)); // Verify that binding the v4 loopback on the same port with a v4 socket // fails. @@ -2027,8 +2112,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, DualStackV6AnyReservesEverything) { ASSERT_NO_ERRNO(SetAddrPort(test_addr_v4.family(), &addr_v4, port)); const FileDescriptor fd_v4 = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr_v4.family(), param.type, 0)); - ASSERT_THAT(bind(fd_v4.get(), reinterpret_cast<sockaddr*>(&addr_v4), - test_addr_v4.addr_len), + ASSERT_THAT(bind(fd_v4.get(), AsSockAddr(&addr_v4), test_addr_v4.addr_len), SyscallFailsWithErrno(EADDRINUSE)); // Verify that binding the v4 any on the same port with a v4 socket @@ -2038,7 +2122,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, DualStackV6AnyReservesEverything) { ASSERT_NO_ERRNO(SetAddrPort(test_addr_v4_any.family(), &addr_v4_any, port)); const FileDescriptor fd_v4_any = ASSERT_NO_ERRNO_AND_VALUE( Socket(test_addr_v4_any.family(), param.type, 0)); - ASSERT_THAT(bind(fd_v4_any.get(), reinterpret_cast<sockaddr*>(&addr_v4_any), + ASSERT_THAT(bind(fd_v4_any.get(), AsSockAddr(&addr_v4_any), test_addr_v4_any.addr_len), SyscallFailsWithErrno(EADDRINUSE)); } @@ -2055,14 +2139,13 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, ASSERT_THAT(setsockopt(fd_dual.get(), SOL_SOCKET, SO_REUSEADDR, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(fd_dual.get(), reinterpret_cast<sockaddr*>(&addr_dual), - test_addr_dual.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(fd_dual.get(), AsSockAddr(&addr_dual), test_addr_dual.addr_len), + SyscallSucceeds()); // Get the port that we bound. socklen_t addrlen = test_addr_dual.addr_len; - ASSERT_THAT(getsockname(fd_dual.get(), - reinterpret_cast<sockaddr*>(&addr_dual), &addrlen), + ASSERT_THAT(getsockname(fd_dual.get(), AsSockAddr(&addr_dual), &addrlen), SyscallSucceeds()); uint16_t const port = ASSERT_NO_ERRNO_AND_VALUE(AddrPort(test_addr_dual.family(), addr_dual)); @@ -2076,7 +2159,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, ASSERT_THAT(setsockopt(fd_v4_any.get(), SOL_SOCKET, SO_REUSEADDR, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(fd_v4_any.get(), reinterpret_cast<sockaddr*>(&addr_v4_any), + ASSERT_THAT(bind(fd_v4_any.get(), AsSockAddr(&addr_v4_any), test_addr_v4_any.addr_len), SyscallSucceeds()); } @@ -2096,16 +2179,15 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, ASSERT_THAT(setsockopt(fd_dual.get(), SOL_SOCKET, SO_REUSEADDR, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(fd_dual.get(), reinterpret_cast<sockaddr*>(&addr_dual), - test_addr_dual.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(fd_dual.get(), AsSockAddr(&addr_dual), test_addr_dual.addr_len), + SyscallSucceeds()); ASSERT_THAT(listen(fd_dual.get(), 5), SyscallSucceeds()); // Get the port that we bound. socklen_t addrlen = test_addr_dual.addr_len; - ASSERT_THAT(getsockname(fd_dual.get(), - reinterpret_cast<sockaddr*>(&addr_dual), &addrlen), + ASSERT_THAT(getsockname(fd_dual.get(), AsSockAddr(&addr_dual), &addrlen), SyscallSucceeds()); uint16_t const port = ASSERT_NO_ERRNO_AND_VALUE(AddrPort(test_addr_dual.family(), addr_dual)); @@ -2120,7 +2202,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(fd_v4_any.get(), reinterpret_cast<sockaddr*>(&addr_v4_any), + ASSERT_THAT(bind(fd_v4_any.get(), AsSockAddr(&addr_v4_any), test_addr_v4_any.addr_len), SyscallFailsWithErrno(EADDRINUSE)); } @@ -2137,16 +2219,15 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, sockaddr_storage addr_dual = test_addr_dual.addr; const FileDescriptor fd_dual = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr_dual.family(), param.type, 0)); - ASSERT_THAT(bind(fd_dual.get(), reinterpret_cast<sockaddr*>(&addr_dual), - test_addr_dual.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(fd_dual.get(), AsSockAddr(&addr_dual), test_addr_dual.addr_len), + SyscallSucceeds()); ASSERT_THAT(listen(fd_dual.get(), 5), SyscallSucceeds()); // Get the port that we bound. socklen_t addrlen = test_addr_dual.addr_len; - ASSERT_THAT(getsockname(fd_dual.get(), - reinterpret_cast<sockaddr*>(&addr_dual), &addrlen), + ASSERT_THAT(getsockname(fd_dual.get(), AsSockAddr(&addr_dual), &addrlen), SyscallSucceeds()); uint16_t const port = ASSERT_NO_ERRNO_AND_VALUE(AddrPort(test_addr_dual.family(), addr_dual)); @@ -2157,8 +2238,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, ASSERT_NO_ERRNO(SetAddrPort(test_addr_v6.family(), &addr_v6, port)); const FileDescriptor fd_v6 = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr_v6.family(), param.type, 0)); - ASSERT_THAT(bind(fd_v6.get(), reinterpret_cast<sockaddr*>(&addr_v6), - test_addr_v6.addr_len), + ASSERT_THAT(bind(fd_v6.get(), AsSockAddr(&addr_v6), test_addr_v6.addr_len), SyscallFailsWithErrno(EADDRINUSE)); // Verify that binding the v4 loopback on the same port with a v6 socket @@ -2169,10 +2249,9 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, SetAddrPort(test_addr_v4_mapped.family(), &addr_v4_mapped, port)); const FileDescriptor fd_v4_mapped = ASSERT_NO_ERRNO_AND_VALUE( Socket(test_addr_v4_mapped.family(), param.type, 0)); - ASSERT_THAT( - bind(fd_v4_mapped.get(), reinterpret_cast<sockaddr*>(&addr_v4_mapped), - test_addr_v4_mapped.addr_len), - SyscallFailsWithErrno(EADDRINUSE)); + ASSERT_THAT(bind(fd_v4_mapped.get(), AsSockAddr(&addr_v4_mapped), + test_addr_v4_mapped.addr_len), + SyscallFailsWithErrno(EADDRINUSE)); // Verify that binding the v4 loopback on the same port with a v4 socket // fails. @@ -2181,8 +2260,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, ASSERT_NO_ERRNO(SetAddrPort(test_addr_v4.family(), &addr_v4, port)); const FileDescriptor fd_v4 = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr_v4.family(), param.type, 0)); - ASSERT_THAT(bind(fd_v4.get(), reinterpret_cast<sockaddr*>(&addr_v4), - test_addr_v4.addr_len), + ASSERT_THAT(bind(fd_v4.get(), AsSockAddr(&addr_v4), test_addr_v4.addr_len), SyscallFailsWithErrno(EADDRINUSE)); // Verify that binding the v4 any on the same port with a v4 socket @@ -2192,7 +2270,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, ASSERT_NO_ERRNO(SetAddrPort(test_addr_v4_any.family(), &addr_v4_any, port)); const FileDescriptor fd_v4_any = ASSERT_NO_ERRNO_AND_VALUE( Socket(test_addr_v4_any.family(), param.type, 0)); - ASSERT_THAT(bind(fd_v4_any.get(), reinterpret_cast<sockaddr*>(&addr_v4_any), + ASSERT_THAT(bind(fd_v4_any.get(), AsSockAddr(&addr_v4_any), test_addr_v4_any.addr_len), SyscallFailsWithErrno(EADDRINUSE)); } @@ -2209,14 +2287,13 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V6OnlyV6AnyReservesV6) { EXPECT_THAT(setsockopt(fd_dual.get(), IPPROTO_IPV6, IPV6_V6ONLY, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(fd_dual.get(), reinterpret_cast<sockaddr*>(&addr_dual), - test_addr_dual.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(fd_dual.get(), AsSockAddr(&addr_dual), test_addr_dual.addr_len), + SyscallSucceeds()); // Get the port that we bound. socklen_t addrlen = test_addr_dual.addr_len; - ASSERT_THAT(getsockname(fd_dual.get(), - reinterpret_cast<sockaddr*>(&addr_dual), &addrlen), + ASSERT_THAT(getsockname(fd_dual.get(), AsSockAddr(&addr_dual), &addrlen), SyscallSucceeds()); uint16_t const port = ASSERT_NO_ERRNO_AND_VALUE(AddrPort(test_addr_dual.family(), addr_dual)); @@ -2227,8 +2304,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V6OnlyV6AnyReservesV6) { ASSERT_NO_ERRNO(SetAddrPort(test_addr_v6.family(), &addr_v6, port)); const FileDescriptor fd_v6 = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr_v6.family(), param.type, 0)); - ASSERT_THAT(bind(fd_v6.get(), reinterpret_cast<sockaddr*>(&addr_v6), - test_addr_v6.addr_len), + ASSERT_THAT(bind(fd_v6.get(), AsSockAddr(&addr_v6), test_addr_v6.addr_len), SyscallFailsWithErrno(EADDRINUSE)); // Verify that we can still bind the v4 loopback on the same port. @@ -2238,9 +2314,8 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V6OnlyV6AnyReservesV6) { SetAddrPort(test_addr_v4_mapped.family(), &addr_v4_mapped, port)); const FileDescriptor fd_v4_mapped = ASSERT_NO_ERRNO_AND_VALUE( Socket(test_addr_v4_mapped.family(), param.type, 0)); - int ret = - bind(fd_v4_mapped.get(), reinterpret_cast<sockaddr*>(&addr_v4_mapped), - test_addr_v4_mapped.addr_len); + int ret = bind(fd_v4_mapped.get(), AsSockAddr(&addr_v4_mapped), + test_addr_v4_mapped.addr_len); if (ret == -1 && errno == EADDRINUSE) { // Port may have been in use. ASSERT_LT(i, 100); // Give up after 100 tries. @@ -2262,9 +2337,9 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V6EphemeralPortReserved) { sockaddr_storage bound_addr = test_addr.addr; const FileDescriptor bound_fd = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr.family(), param.type, 0)); - ASSERT_THAT(bind(bound_fd.get(), reinterpret_cast<sockaddr*>(&bound_addr), - test_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(bound_fd.get(), AsSockAddr(&bound_addr), test_addr.addr_len), + SyscallSucceeds()); // Listen iff TCP. if (param.type == SOCK_STREAM) { @@ -2274,23 +2349,20 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V6EphemeralPortReserved) { // Get the port that we bound. socklen_t bound_addr_len = test_addr.addr_len; ASSERT_THAT( - getsockname(bound_fd.get(), reinterpret_cast<sockaddr*>(&bound_addr), - &bound_addr_len), + getsockname(bound_fd.get(), AsSockAddr(&bound_addr), &bound_addr_len), SyscallSucceeds()); // Connect to bind an ephemeral port. const FileDescriptor connected_fd = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr.family(), param.type, 0)); - ASSERT_THAT(RetryEINTR(connect)(connected_fd.get(), - reinterpret_cast<sockaddr*>(&bound_addr), + ASSERT_THAT(RetryEINTR(connect)(connected_fd.get(), AsSockAddr(&bound_addr), bound_addr_len), SyscallSucceeds()); // Get the ephemeral port. sockaddr_storage connected_addr = {}; socklen_t connected_addr_len = sizeof(connected_addr); - ASSERT_THAT(getsockname(connected_fd.get(), - reinterpret_cast<sockaddr*>(&connected_addr), + ASSERT_THAT(getsockname(connected_fd.get(), AsSockAddr(&connected_addr), &connected_addr_len), SyscallSucceeds()); uint16_t const ephemeral_port = @@ -2302,10 +2374,9 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V6EphemeralPortReserved) { // Verify that the ephemeral port is reserved. const FileDescriptor checking_fd = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr.family(), param.type, 0)); - EXPECT_THAT( - bind(checking_fd.get(), reinterpret_cast<sockaddr*>(&connected_addr), - connected_addr_len), - SyscallFailsWithErrno(EADDRINUSE)); + EXPECT_THAT(bind(checking_fd.get(), AsSockAddr(&connected_addr), + connected_addr_len), + SyscallFailsWithErrno(EADDRINUSE)); // Verify that binding the v6 loopback with the same port fails. TestAddress const& test_addr_v6 = V6Loopback(); @@ -2314,8 +2385,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V6EphemeralPortReserved) { SetAddrPort(test_addr_v6.family(), &addr_v6, ephemeral_port)); const FileDescriptor fd_v6 = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr_v6.family(), param.type, 0)); - ASSERT_THAT(bind(fd_v6.get(), reinterpret_cast<sockaddr*>(&addr_v6), - test_addr_v6.addr_len), + ASSERT_THAT(bind(fd_v6.get(), AsSockAddr(&addr_v6), test_addr_v6.addr_len), SyscallFailsWithErrno(EADDRINUSE)); // Verify that we can still bind the v4 loopback on the same port. @@ -2325,9 +2395,8 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V6EphemeralPortReserved) { ephemeral_port)); const FileDescriptor fd_v4_mapped = ASSERT_NO_ERRNO_AND_VALUE( Socket(test_addr_v4_mapped.family(), param.type, 0)); - int ret = - bind(fd_v4_mapped.get(), reinterpret_cast<sockaddr*>(&addr_v4_mapped), - test_addr_v4_mapped.addr_len); + int ret = bind(fd_v4_mapped.get(), AsSockAddr(&addr_v4_mapped), + test_addr_v4_mapped.addr_len); if (ret == -1 && errno == EADDRINUSE) { // Port may have been in use. ASSERT_LT(i, 100); // Give up after 100 tries. @@ -2348,8 +2417,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V6EphemeralPortReservedReuseAddr) { sockaddr_storage bound_addr = test_addr.addr; const FileDescriptor bound_fd = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr.family(), param.type, 0)); - ASSERT_THAT(bind(bound_fd.get(), reinterpret_cast<sockaddr*>(&bound_addr), - test_addr.addr_len), + ASSERT_THAT(bind(bound_fd.get(), AsSockAddr(&bound_addr), test_addr.addr_len), SyscallSucceeds()); ASSERT_THAT(setsockopt(bound_fd.get(), SOL_SOCKET, SO_REUSEADDR, &kSockOptOn, sizeof(kSockOptOn)), @@ -2363,8 +2431,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V6EphemeralPortReservedReuseAddr) { // Get the port that we bound. socklen_t bound_addr_len = test_addr.addr_len; ASSERT_THAT( - getsockname(bound_fd.get(), reinterpret_cast<sockaddr*>(&bound_addr), - &bound_addr_len), + getsockname(bound_fd.get(), AsSockAddr(&bound_addr), &bound_addr_len), SyscallSucceeds()); // Connect to bind an ephemeral port. @@ -2373,16 +2440,14 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V6EphemeralPortReservedReuseAddr) { ASSERT_THAT(setsockopt(connected_fd.get(), SOL_SOCKET, SO_REUSEADDR, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(RetryEINTR(connect)(connected_fd.get(), - reinterpret_cast<sockaddr*>(&bound_addr), + ASSERT_THAT(RetryEINTR(connect)(connected_fd.get(), AsSockAddr(&bound_addr), bound_addr_len), SyscallSucceeds()); // Get the ephemeral port. sockaddr_storage connected_addr = {}; socklen_t connected_addr_len = sizeof(connected_addr); - ASSERT_THAT(getsockname(connected_fd.get(), - reinterpret_cast<sockaddr*>(&connected_addr), + ASSERT_THAT(getsockname(connected_fd.get(), AsSockAddr(&connected_addr), &connected_addr_len), SyscallSucceeds()); uint16_t const ephemeral_port = @@ -2398,8 +2463,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V6EphemeralPortReservedReuseAddr) { &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); EXPECT_THAT( - bind(checking_fd.get(), reinterpret_cast<sockaddr*>(&connected_addr), - connected_addr_len), + bind(checking_fd.get(), AsSockAddr(&connected_addr), connected_addr_len), SyscallSucceeds()); } @@ -2412,9 +2476,9 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4MappedEphemeralPortReserved) { sockaddr_storage bound_addr = test_addr.addr; const FileDescriptor bound_fd = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr.family(), param.type, 0)); - ASSERT_THAT(bind(bound_fd.get(), reinterpret_cast<sockaddr*>(&bound_addr), - test_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(bound_fd.get(), AsSockAddr(&bound_addr), test_addr.addr_len), + SyscallSucceeds()); // Listen iff TCP. if (param.type == SOCK_STREAM) { @@ -2424,23 +2488,20 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4MappedEphemeralPortReserved) { // Get the port that we bound. socklen_t bound_addr_len = test_addr.addr_len; ASSERT_THAT( - getsockname(bound_fd.get(), reinterpret_cast<sockaddr*>(&bound_addr), - &bound_addr_len), + getsockname(bound_fd.get(), AsSockAddr(&bound_addr), &bound_addr_len), SyscallSucceeds()); // Connect to bind an ephemeral port. const FileDescriptor connected_fd = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr.family(), param.type, 0)); - ASSERT_THAT(RetryEINTR(connect)(connected_fd.get(), - reinterpret_cast<sockaddr*>(&bound_addr), + ASSERT_THAT(RetryEINTR(connect)(connected_fd.get(), AsSockAddr(&bound_addr), bound_addr_len), SyscallSucceeds()); // Get the ephemeral port. sockaddr_storage connected_addr = {}; socklen_t connected_addr_len = sizeof(connected_addr); - ASSERT_THAT(getsockname(connected_fd.get(), - reinterpret_cast<sockaddr*>(&connected_addr), + ASSERT_THAT(getsockname(connected_fd.get(), AsSockAddr(&connected_addr), &connected_addr_len), SyscallSucceeds()); uint16_t const ephemeral_port = @@ -2452,10 +2513,9 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4MappedEphemeralPortReserved) { // Verify that the ephemeral port is reserved. const FileDescriptor checking_fd = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr.family(), param.type, 0)); - EXPECT_THAT( - bind(checking_fd.get(), reinterpret_cast<sockaddr*>(&connected_addr), - connected_addr_len), - SyscallFailsWithErrno(EADDRINUSE)); + EXPECT_THAT(bind(checking_fd.get(), AsSockAddr(&connected_addr), + connected_addr_len), + SyscallFailsWithErrno(EADDRINUSE)); // Verify that binding the v4 loopback on the same port with a v4 socket // fails. @@ -2465,8 +2525,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4MappedEphemeralPortReserved) { SetAddrPort(test_addr_v4.family(), &addr_v4, ephemeral_port)); const FileDescriptor fd_v4 = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr_v4.family(), param.type, 0)); - EXPECT_THAT(bind(fd_v4.get(), reinterpret_cast<sockaddr*>(&addr_v4), - test_addr_v4.addr_len), + EXPECT_THAT(bind(fd_v4.get(), AsSockAddr(&addr_v4), test_addr_v4.addr_len), SyscallFailsWithErrno(EADDRINUSE)); // Verify that binding the v6 any on the same port with a dual-stack socket @@ -2477,7 +2536,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4MappedEphemeralPortReserved) { SetAddrPort(test_addr_v6_any.family(), &addr_v6_any, ephemeral_port)); const FileDescriptor fd_v6_any = ASSERT_NO_ERRNO_AND_VALUE( Socket(test_addr_v6_any.family(), param.type, 0)); - ASSERT_THAT(bind(fd_v6_any.get(), reinterpret_cast<sockaddr*>(&addr_v6_any), + ASSERT_THAT(bind(fd_v6_any.get(), AsSockAddr(&addr_v6_any), test_addr_v6_any.addr_len), SyscallFailsWithErrno(EADDRINUSE)); @@ -2496,8 +2555,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4MappedEphemeralPortReserved) { SetAddrPort(test_addr_v6.family(), &addr_v6, ephemeral_port)); const FileDescriptor fd_v6 = ASSERT_NO_ERRNO_AND_VALUE( Socket(test_addr_v6.family(), param.type, 0)); - ret = bind(fd_v6.get(), reinterpret_cast<sockaddr*>(&addr_v6), - test_addr_v6.addr_len); + ret = bind(fd_v6.get(), AsSockAddr(&addr_v6), test_addr_v6.addr_len); } else { // Verify that we can still bind the v6 any on the same port with a // v6-only socket. @@ -2506,9 +2564,8 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4MappedEphemeralPortReserved) { EXPECT_THAT(setsockopt(fd_v6_only_any.get(), IPPROTO_IPV6, IPV6_V6ONLY, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ret = - bind(fd_v6_only_any.get(), reinterpret_cast<sockaddr*>(&addr_v6_any), - test_addr_v6_any.addr_len); + ret = bind(fd_v6_only_any.get(), AsSockAddr(&addr_v6_any), + test_addr_v6_any.addr_len); } if (ret == -1 && errno == EADDRINUSE) { @@ -2532,8 +2589,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, sockaddr_storage bound_addr = test_addr.addr; const FileDescriptor bound_fd = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr.family(), param.type, 0)); - ASSERT_THAT(bind(bound_fd.get(), reinterpret_cast<sockaddr*>(&bound_addr), - test_addr.addr_len), + ASSERT_THAT(bind(bound_fd.get(), AsSockAddr(&bound_addr), test_addr.addr_len), SyscallSucceeds()); ASSERT_THAT(setsockopt(bound_fd.get(), SOL_SOCKET, SO_REUSEADDR, &kSockOptOn, @@ -2548,8 +2604,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, // Get the port that we bound. socklen_t bound_addr_len = test_addr.addr_len; ASSERT_THAT( - getsockname(bound_fd.get(), reinterpret_cast<sockaddr*>(&bound_addr), - &bound_addr_len), + getsockname(bound_fd.get(), AsSockAddr(&bound_addr), &bound_addr_len), SyscallSucceeds()); // Connect to bind an ephemeral port. @@ -2558,16 +2613,14 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, ASSERT_THAT(setsockopt(connected_fd.get(), SOL_SOCKET, SO_REUSEADDR, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(RetryEINTR(connect)(connected_fd.get(), - reinterpret_cast<sockaddr*>(&bound_addr), + ASSERT_THAT(RetryEINTR(connect)(connected_fd.get(), AsSockAddr(&bound_addr), bound_addr_len), SyscallSucceeds()); // Get the ephemeral port. sockaddr_storage connected_addr = {}; socklen_t connected_addr_len = sizeof(connected_addr); - ASSERT_THAT(getsockname(connected_fd.get(), - reinterpret_cast<sockaddr*>(&connected_addr), + ASSERT_THAT(getsockname(connected_fd.get(), AsSockAddr(&connected_addr), &connected_addr_len), SyscallSucceeds()); uint16_t const ephemeral_port = @@ -2583,8 +2636,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); EXPECT_THAT( - bind(checking_fd.get(), reinterpret_cast<sockaddr*>(&connected_addr), - connected_addr_len), + bind(checking_fd.get(), AsSockAddr(&connected_addr), connected_addr_len), SyscallSucceeds()); } @@ -2597,9 +2649,9 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4EphemeralPortReserved) { sockaddr_storage bound_addr = test_addr.addr; const FileDescriptor bound_fd = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr.family(), param.type, 0)); - ASSERT_THAT(bind(bound_fd.get(), reinterpret_cast<sockaddr*>(&bound_addr), - test_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(bound_fd.get(), AsSockAddr(&bound_addr), test_addr.addr_len), + SyscallSucceeds()); // Listen iff TCP. if (param.type == SOCK_STREAM) { @@ -2609,23 +2661,20 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4EphemeralPortReserved) { // Get the port that we bound. socklen_t bound_addr_len = test_addr.addr_len; ASSERT_THAT( - getsockname(bound_fd.get(), reinterpret_cast<sockaddr*>(&bound_addr), - &bound_addr_len), + getsockname(bound_fd.get(), AsSockAddr(&bound_addr), &bound_addr_len), SyscallSucceeds()); // Connect to bind an ephemeral port. const FileDescriptor connected_fd = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr.family(), param.type, 0)); - ASSERT_THAT(RetryEINTR(connect)(connected_fd.get(), - reinterpret_cast<sockaddr*>(&bound_addr), + ASSERT_THAT(RetryEINTR(connect)(connected_fd.get(), AsSockAddr(&bound_addr), bound_addr_len), SyscallSucceeds()); // Get the ephemeral port. sockaddr_storage connected_addr = {}; socklen_t connected_addr_len = sizeof(connected_addr); - ASSERT_THAT(getsockname(connected_fd.get(), - reinterpret_cast<sockaddr*>(&connected_addr), + ASSERT_THAT(getsockname(connected_fd.get(), AsSockAddr(&connected_addr), &connected_addr_len), SyscallSucceeds()); uint16_t const ephemeral_port = @@ -2637,10 +2686,9 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4EphemeralPortReserved) { // Verify that the ephemeral port is reserved. const FileDescriptor checking_fd = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr.family(), param.type, 0)); - EXPECT_THAT( - bind(checking_fd.get(), reinterpret_cast<sockaddr*>(&connected_addr), - connected_addr_len), - SyscallFailsWithErrno(EADDRINUSE)); + EXPECT_THAT(bind(checking_fd.get(), AsSockAddr(&connected_addr), + connected_addr_len), + SyscallFailsWithErrno(EADDRINUSE)); // Verify that binding the v4 loopback on the same port with a v6 socket // fails. @@ -2650,10 +2698,9 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4EphemeralPortReserved) { ephemeral_port)); const FileDescriptor fd_v4_mapped = ASSERT_NO_ERRNO_AND_VALUE( Socket(test_addr_v4_mapped.family(), param.type, 0)); - EXPECT_THAT( - bind(fd_v4_mapped.get(), reinterpret_cast<sockaddr*>(&addr_v4_mapped), - test_addr_v4_mapped.addr_len), - SyscallFailsWithErrno(EADDRINUSE)); + EXPECT_THAT(bind(fd_v4_mapped.get(), AsSockAddr(&addr_v4_mapped), + test_addr_v4_mapped.addr_len), + SyscallFailsWithErrno(EADDRINUSE)); // Verify that binding the v6 any on the same port with a dual-stack socket // fails. @@ -2663,7 +2710,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4EphemeralPortReserved) { SetAddrPort(test_addr_v6_any.family(), &addr_v6_any, ephemeral_port)); const FileDescriptor fd_v6_any = ASSERT_NO_ERRNO_AND_VALUE( Socket(test_addr_v6_any.family(), param.type, 0)); - ASSERT_THAT(bind(fd_v6_any.get(), reinterpret_cast<sockaddr*>(&addr_v6_any), + ASSERT_THAT(bind(fd_v6_any.get(), AsSockAddr(&addr_v6_any), test_addr_v6_any.addr_len), SyscallFailsWithErrno(EADDRINUSE)); @@ -2682,8 +2729,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4EphemeralPortReserved) { SetAddrPort(test_addr_v6.family(), &addr_v6, ephemeral_port)); const FileDescriptor fd_v6 = ASSERT_NO_ERRNO_AND_VALUE( Socket(test_addr_v6.family(), param.type, 0)); - ret = bind(fd_v6.get(), reinterpret_cast<sockaddr*>(&addr_v6), - test_addr_v6.addr_len); + ret = bind(fd_v6.get(), AsSockAddr(&addr_v6), test_addr_v6.addr_len); } else { // Verify that we can still bind the v6 any on the same port with a // v6-only socket. @@ -2692,9 +2738,8 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4EphemeralPortReserved) { EXPECT_THAT(setsockopt(fd_v6_only_any.get(), IPPROTO_IPV6, IPV6_V6ONLY, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ret = - bind(fd_v6_only_any.get(), reinterpret_cast<sockaddr*>(&addr_v6_any), - test_addr_v6_any.addr_len); + ret = bind(fd_v6_only_any.get(), AsSockAddr(&addr_v6_any), + test_addr_v6_any.addr_len); } if (ret == -1 && errno == EADDRINUSE) { @@ -2722,8 +2767,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4EphemeralPortReservedReuseAddr) { sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(bound_fd.get(), reinterpret_cast<sockaddr*>(&bound_addr), - test_addr.addr_len), + ASSERT_THAT(bind(bound_fd.get(), AsSockAddr(&bound_addr), test_addr.addr_len), SyscallSucceeds()); // Listen iff TCP. @@ -2734,8 +2778,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4EphemeralPortReservedReuseAddr) { // Get the port that we bound. socklen_t bound_addr_len = test_addr.addr_len; ASSERT_THAT( - getsockname(bound_fd.get(), reinterpret_cast<sockaddr*>(&bound_addr), - &bound_addr_len), + getsockname(bound_fd.get(), AsSockAddr(&bound_addr), &bound_addr_len), SyscallSucceeds()); // Connect to bind an ephemeral port. @@ -2746,16 +2789,14 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4EphemeralPortReservedReuseAddr) { &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(RetryEINTR(connect)(connected_fd.get(), - reinterpret_cast<sockaddr*>(&bound_addr), + ASSERT_THAT(RetryEINTR(connect)(connected_fd.get(), AsSockAddr(&bound_addr), bound_addr_len), SyscallSucceeds()); // Get the ephemeral port. sockaddr_storage connected_addr = {}; socklen_t connected_addr_len = sizeof(connected_addr); - ASSERT_THAT(getsockname(connected_fd.get(), - reinterpret_cast<sockaddr*>(&connected_addr), + ASSERT_THAT(getsockname(connected_fd.get(), AsSockAddr(&connected_addr), &connected_addr_len), SyscallSucceeds()); uint16_t const ephemeral_port = @@ -2771,8 +2812,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4EphemeralPortReservedReuseAddr) { &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); EXPECT_THAT( - bind(checking_fd.get(), reinterpret_cast<sockaddr*>(&connected_addr), - connected_addr_len), + bind(checking_fd.get(), AsSockAddr(&connected_addr), connected_addr_len), SyscallSucceeds()); } @@ -2791,14 +2831,12 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, ASSERT_THAT(setsockopt(bound_fd.get(), SOL_SOCKET, SO_REUSEADDR, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(bound_fd.get(), reinterpret_cast<sockaddr*>(&bound_addr), - test_addr.addr_len), + ASSERT_THAT(bind(bound_fd.get(), AsSockAddr(&bound_addr), test_addr.addr_len), SyscallSucceeds()); // Get the port that we bound. socklen_t bound_addr_len = test_addr.addr_len; ASSERT_THAT( - getsockname(bound_fd.get(), reinterpret_cast<sockaddr*>(&bound_addr), - &bound_addr_len), + getsockname(bound_fd.get(), AsSockAddr(&bound_addr), &bound_addr_len), SyscallSucceeds()); // Now create a socket and bind it to the same port, this should @@ -2809,9 +2847,9 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, ASSERT_THAT(setsockopt(second_fd.get(), SOL_SOCKET, SO_REUSEADDR, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(second_fd.get(), reinterpret_cast<sockaddr*>(&bound_addr), - test_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(second_fd.get(), AsSockAddr(&bound_addr), test_addr.addr_len), + SyscallSucceeds()); } TEST_P(SocketMultiProtocolInetLoopbackTest, PortReuseTwoSockets) { @@ -2830,10 +2868,9 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, PortReuseTwoSockets) { setsockopt(fd1, SOL_SOCKET, SO_REUSEPORT, &portreuse1, sizeof(int)), SyscallSucceeds()); - ASSERT_THAT(bind(fd1, reinterpret_cast<sockaddr*>(&addr), addrlen), - SyscallSucceeds()); + ASSERT_THAT(bind(fd1, AsSockAddr(&addr), addrlen), SyscallSucceeds()); - ASSERT_THAT(getsockname(fd1, reinterpret_cast<sockaddr*>(&addr), &addrlen), + ASSERT_THAT(getsockname(fd1, AsSockAddr(&addr), &addrlen), SyscallSucceeds()); if (param.type == SOCK_STREAM) { ASSERT_THAT(listen(fd1, 1), SyscallSucceeds()); @@ -2852,7 +2889,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, PortReuseTwoSockets) { SyscallSucceeds()); std::cout << portreuse1 << " " << portreuse2 << std::endl; - int ret = bind(fd2, reinterpret_cast<sockaddr*>(&addr), addrlen); + int ret = bind(fd2, AsSockAddr(&addr), addrlen); // Verify that two sockets can be bound to the same port only if // SO_REUSEPORT is set for both of them. @@ -2880,10 +2917,8 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, NoReusePortFollowingReusePort) { ASSERT_THAT( setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &portreuse, sizeof(portreuse)), SyscallSucceeds()); - ASSERT_THAT(bind(fd, reinterpret_cast<sockaddr*>(&addr), addrlen), - SyscallSucceeds()); - ASSERT_THAT(getsockname(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen), - SyscallSucceeds()); + ASSERT_THAT(bind(fd, AsSockAddr(&addr), addrlen), SyscallSucceeds()); + ASSERT_THAT(getsockname(fd, AsSockAddr(&addr), &addrlen), SyscallSucceeds()); ASSERT_EQ(addrlen, test_addr.addr_len); s.reset(); @@ -2895,8 +2930,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, NoReusePortFollowingReusePort) { ASSERT_THAT( setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &portreuse, sizeof(portreuse)), SyscallSucceeds()); - ASSERT_THAT(bind(fd, reinterpret_cast<sockaddr*>(&addr), addrlen), - SyscallSucceeds()); + ASSERT_THAT(bind(fd, AsSockAddr(&addr), addrlen), SyscallSucceeds()); } INSTANTIATE_TEST_SUITE_P( diff --git a/test/syscalls/linux/socket_inet_loopback_nogotsan.cc b/test/syscalls/linux/socket_inet_loopback_nogotsan.cc index 1a0b53394..601ae107b 100644 --- a/test/syscalls/linux/socket_inet_loopback_nogotsan.cc +++ b/test/syscalls/linux/socket_inet_loopback_nogotsan.cc @@ -86,7 +86,7 @@ using SocketInetLoopbackTest = ::testing::TestWithParam<TestParam>; // We disable S/R because this test creates a large number of sockets. // // FIXME(b/162475855): This test is failing reliably. -TEST_P(SocketInetLoopbackTest, DISABLED_TestTCPPortExhaustion_NoRandomSave) { +TEST_P(SocketInetLoopbackTest, DISABLED_TestTCPPortExhaustion) { auto const& param = GetParam(); TestAddress const& listener = param.listener; TestAddress const& connector = param.connector; @@ -98,15 +98,14 @@ TEST_P(SocketInetLoopbackTest, DISABLED_TestTCPPortExhaustion_NoRandomSave) { auto listen_fd = ASSERT_NO_ERRNO_AND_VALUE( Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP)); sockaddr_storage listen_addr = listener.addr; - ASSERT_THAT(bind(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr), - listener.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(listen_fd.get(), AsSockAddr(&listen_addr), listener.addr_len), + SyscallSucceeds()); ASSERT_THAT(listen(listen_fd.get(), kBacklog), SyscallSucceeds()); // Get the port bound by the listening socket. socklen_t addrlen = listener.addr_len; - ASSERT_THAT(getsockname(listen_fd.get(), - reinterpret_cast<sockaddr*>(&listen_addr), &addrlen), + ASSERT_THAT(getsockname(listen_fd.get(), AsSockAddr(&listen_addr), &addrlen), SyscallSucceeds()); uint16_t const port = ASSERT_NO_ERRNO_AND_VALUE(AddrPort(listener.family(), listen_addr)); @@ -124,8 +123,7 @@ TEST_P(SocketInetLoopbackTest, DISABLED_TestTCPPortExhaustion_NoRandomSave) { for (int i = 0; i < kClients; i++) { FileDescriptor client = ASSERT_NO_ERRNO_AND_VALUE( Socket(connector.family(), SOCK_STREAM, IPPROTO_TCP)); - int ret = connect(client.get(), reinterpret_cast<sockaddr*>(&conn_addr), - connector.addr_len); + int ret = connect(client.get(), AsSockAddr(&conn_addr), connector.addr_len); if (ret == 0) { clients.push_back(std::move(client)); FileDescriptor server = @@ -181,8 +179,7 @@ std::string DescribeProtocolTestParam( using SocketMultiProtocolInetLoopbackTest = ::testing::TestWithParam<ProtocolTestParam>; -TEST_P(SocketMultiProtocolInetLoopbackTest, - BindAvoidsListeningPortsReuseAddr_NoRandomSave) { +TEST_P(SocketMultiProtocolInetLoopbackTest, BindAvoidsListeningPortsReuseAddr) { const auto& param = GetParam(); // UDP sockets are allowed to bind/listen on the port w/ SO_REUSEADDR, for TCP // this is only permitted if there is no other listening socket. @@ -205,8 +202,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - int ret = bind(bound_fd.get(), reinterpret_cast<sockaddr*>(&bound_addr), - test_addr.addr_len); + int ret = bind(bound_fd.get(), AsSockAddr(&bound_addr), test_addr.addr_len); if (ret != 0) { ASSERT_EQ(errno, EADDRINUSE); break; @@ -214,8 +210,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, // Get the port that we bound. socklen_t bound_addr_len = test_addr.addr_len; ASSERT_THAT( - getsockname(bound_fd.get(), reinterpret_cast<sockaddr*>(&bound_addr), - &bound_addr_len), + getsockname(bound_fd.get(), AsSockAddr(&bound_addr), &bound_addr_len), SyscallSucceeds()); uint16_t port = reinterpret_cast<sockaddr_in*>(&bound_addr)->sin_port; diff --git a/test/syscalls/linux/socket_ip_tcp_generic.cc b/test/syscalls/linux/socket_ip_tcp_generic.cc index f10f55b27..59b56dc1a 100644 --- a/test/syscalls/linux/socket_ip_tcp_generic.cc +++ b/test/syscalls/linux/socket_ip_tcp_generic.cc @@ -1153,7 +1153,7 @@ TEST_P(TCPSocketPairTest, IpMulticastLoopDefault) { EXPECT_EQ(get, 1); } -TEST_P(TCPSocketPairTest, TCPResetDuringClose_NoRandomSave) { +TEST_P(TCPSocketPairTest, TCPResetDuringClose) { DisableSave ds; // Too many syscalls. constexpr int kThreadCount = 1000; std::unique_ptr<ScopedThread> instances[kThreadCount]; diff --git a/test/syscalls/linux/socket_ip_unbound_netlink.cc b/test/syscalls/linux/socket_ip_unbound_netlink.cc index 7fb1c0faf..b02222999 100644 --- a/test/syscalls/linux/socket_ip_unbound_netlink.cc +++ b/test/syscalls/linux/socket_ip_unbound_netlink.cc @@ -35,7 +35,7 @@ namespace testing { // Test fixture for tests that apply to pairs of IP sockets. using IPv6UnboundSocketTest = SimpleSocketTest; -TEST_P(IPv6UnboundSocketTest, ConnectToBadLocalAddress_NoRandomSave) { +TEST_P(IPv6UnboundSocketTest, ConnectToBadLocalAddress) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN))); // TODO(gvisor.dev/issue/4595): Addresses on net devices are not saved @@ -57,8 +57,7 @@ TEST_P(IPv6UnboundSocketTest, ConnectToBadLocalAddress_NoRandomSave) { TestAddress addr = V6Loopback(); reinterpret_cast<sockaddr_in6*>(&addr.addr)->sin6_port = 65535; auto sock = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); - EXPECT_THAT(connect(sock->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + EXPECT_THAT(connect(sock->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallFailsWithErrno(EADDRNOTAVAIL)); } @@ -69,7 +68,7 @@ INSTANTIATE_TEST_SUITE_P(IPUnboundSockets, IPv6UnboundSocketTest, using IPv4UnboundSocketTest = SimpleSocketTest; -TEST_P(IPv4UnboundSocketTest, ConnectToBadLocalAddress_NoRandomSave) { +TEST_P(IPv4UnboundSocketTest, ConnectToBadLocalAddress) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN))); // TODO(gvisor.dev/issue/4595): Addresses on net devices are not saved @@ -90,8 +89,7 @@ TEST_P(IPv4UnboundSocketTest, ConnectToBadLocalAddress_NoRandomSave) { TestAddress addr = V4Loopback(); reinterpret_cast<sockaddr_in*>(&addr.addr)->sin_port = 65535; auto sock = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); - EXPECT_THAT(connect(sock->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + EXPECT_THAT(connect(sock->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallFailsWithErrno(ENETUNREACH)); } diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound.cc b/test/syscalls/linux/socket_ipv4_udp_unbound.cc index 8eec31a46..18be4dcc7 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound.cc +++ b/test/syscalls/linux/socket_ipv4_udp_unbound.cc @@ -44,20 +44,17 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackNoGroup) { // IP_MULTICAST_IF for setting the default send interface. auto sender_addr = V4Loopback(); EXPECT_THAT( - bind(socket1->get(), reinterpret_cast<sockaddr*>(&sender_addr.addr), - sender_addr.addr_len), + bind(socket1->get(), AsSockAddr(&sender_addr.addr), sender_addr.addr_len), SyscallSucceeds()); // Bind the second FD to the v4 any address. If multicast worked like unicast, // this would ensure that we get the packet. auto receiver_addr = V4Any(); - EXPECT_THAT( - bind(socket2->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + EXPECT_THAT(bind(socket2->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket2->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket2->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -68,10 +65,10 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackNoGroup) { reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - EXPECT_THAT(RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + EXPECT_THAT( + RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we did not receive the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -83,19 +80,19 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackNoGroup) { // Check that not setting a default send interface prevents multicast packets // from being sent. Group membership interface configured by address. TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackAddrNoDefaultSendIf) { + // TODO(b/185517803): Fix for native test. + SKIP_IF(!IsRunningOnGvisor()); auto socket1 = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); auto socket2 = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); // Bind the second FD to the v4 any address to ensure that we can receive any // unicast packet. auto receiver_addr = V4Any(); - EXPECT_THAT( - bind(socket2->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + EXPECT_THAT(bind(socket2->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket2->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket2->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -114,28 +111,28 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackAddrNoDefaultSendIf) { reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - EXPECT_THAT(RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallFailsWithErrno(ENETUNREACH)); + EXPECT_THAT( + RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallFailsWithErrno(ENETUNREACH)); } // Check that not setting a default send interface prevents multicast packets // from being sent. Group membership interface configured by NIC ID. TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackNicNoDefaultSendIf) { + // TODO(b/185517803): Fix for native test. + SKIP_IF(!IsRunningOnGvisor()); auto socket1 = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); auto socket2 = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); // Bind the second FD to the v4 any address to ensure that we can receive any // unicast packet. auto receiver_addr = V4Any(); - ASSERT_THAT( - bind(socket2->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(socket2->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket2->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket2->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -154,10 +151,10 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackNicNoDefaultSendIf) { reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - EXPECT_THAT(RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallFailsWithErrno(ENETUNREACH)); + EXPECT_THAT( + RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallFailsWithErrno(ENETUNREACH)); } // Check that multicast works when the default send interface is configured by @@ -170,20 +167,17 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackAddr) { // IP_MULTICAST_IF for setting the default send interface. auto sender_addr = V4Loopback(); ASSERT_THAT( - bind(socket1->get(), reinterpret_cast<sockaddr*>(&sender_addr.addr), - sender_addr.addr_len), + bind(socket1->get(), AsSockAddr(&sender_addr.addr), sender_addr.addr_len), SyscallSucceeds()); // Bind the second FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - ASSERT_THAT( - bind(socket2->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(socket2->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket2->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket2->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -202,10 +196,10 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackAddr) { reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we received the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -226,20 +220,17 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackNic) { // IP_MULTICAST_IF for setting the default send interface. auto sender_addr = V4Loopback(); ASSERT_THAT( - bind(socket1->get(), reinterpret_cast<sockaddr*>(&sender_addr.addr), - sender_addr.addr_len), + bind(socket1->get(), AsSockAddr(&sender_addr.addr), sender_addr.addr_len), SyscallSucceeds()); // Bind the second FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - ASSERT_THAT( - bind(socket2->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(socket2->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket2->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket2->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -258,10 +249,10 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackNic) { reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we received the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -289,13 +280,11 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackIfAddr) { // Bind the second FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - ASSERT_THAT( - bind(socket2->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(socket2->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket2->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket2->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -314,10 +303,10 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackIfAddr) { reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we received the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -345,13 +334,11 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackIfNic) { // Bind the second FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - ASSERT_THAT( - bind(socket2->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(socket2->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket2->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket2->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -370,10 +357,10 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackIfNic) { reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we received the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -401,13 +388,11 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackIfAddrConnect) { // Bind the second FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - ASSERT_THAT( - bind(socket2->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(socket2->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket2->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket2->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -425,8 +410,7 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackIfAddrConnect) { reinterpret_cast<sockaddr_in*>(&connect_addr.addr)->sin_port = reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; ASSERT_THAT( - RetryEINTR(connect)(socket1->get(), - reinterpret_cast<sockaddr*>(&connect_addr.addr), + RetryEINTR(connect)(socket1->get(), AsSockAddr(&connect_addr.addr), connect_addr.addr_len), SyscallSucceeds()); @@ -461,13 +445,11 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackIfNicConnect) { // Bind the second FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - ASSERT_THAT( - bind(socket2->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(socket2->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket2->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket2->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -485,8 +467,7 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackIfNicConnect) { reinterpret_cast<sockaddr_in*>(&connect_addr.addr)->sin_port = reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; ASSERT_THAT( - RetryEINTR(connect)(socket1->get(), - reinterpret_cast<sockaddr*>(&connect_addr.addr), + RetryEINTR(connect)(socket1->get(), AsSockAddr(&connect_addr.addr), connect_addr.addr_len), SyscallSucceeds()); @@ -521,13 +502,11 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackIfAddrSelf) { // Bind the first FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - ASSERT_THAT( - bind(socket1->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(socket1->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket1->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket1->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -546,10 +525,10 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackIfAddrSelf) { reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we received the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -577,13 +556,11 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackIfNicSelf) { // Bind the first FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - ASSERT_THAT( - bind(socket1->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(socket1->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket1->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket1->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -602,10 +579,10 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackIfNicSelf) { reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we received the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -633,13 +610,11 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackIfAddrSelfConnect) { // Bind the first FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - ASSERT_THAT( - bind(socket1->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(socket1->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket1->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket1->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -657,8 +632,7 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackIfAddrSelfConnect) { reinterpret_cast<sockaddr_in*>(&connect_addr.addr)->sin_port = reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; EXPECT_THAT( - RetryEINTR(connect)(socket1->get(), - reinterpret_cast<sockaddr*>(&connect_addr.addr), + RetryEINTR(connect)(socket1->get(), AsSockAddr(&connect_addr.addr), connect_addr.addr_len), SyscallSucceeds()); @@ -691,13 +665,11 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackIfNicSelfConnect) { // Bind the first FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - ASSERT_THAT( - bind(socket1->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(socket1->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket1->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket1->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -715,8 +687,7 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackIfNicSelfConnect) { reinterpret_cast<sockaddr_in*>(&connect_addr.addr)->sin_port = reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; ASSERT_THAT( - RetryEINTR(connect)(socket1->get(), - reinterpret_cast<sockaddr*>(&connect_addr.addr), + RetryEINTR(connect)(socket1->get(), AsSockAddr(&connect_addr.addr), connect_addr.addr_len), SyscallSucceeds()); @@ -753,13 +724,11 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackIfAddrSelfNoLoop) { // Bind the first FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - ASSERT_THAT( - bind(socket1->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(socket1->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket1->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket1->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -778,10 +747,10 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackIfAddrSelfNoLoop) { reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we received the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -813,13 +782,11 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackIfNicSelfNoLoop) { // Bind the second FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - ASSERT_THAT( - bind(socket1->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(socket1->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket1->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket1->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -838,10 +805,10 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackIfNicSelfNoLoop) { reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we received the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -877,20 +844,17 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastDropAddr) { // IP_MULTICAST_IF for setting the default send interface. auto sender_addr = V4Loopback(); EXPECT_THAT( - bind(socket1->get(), reinterpret_cast<sockaddr*>(&sender_addr.addr), - sender_addr.addr_len), + bind(socket1->get(), AsSockAddr(&sender_addr.addr), sender_addr.addr_len), SyscallSucceeds()); // Bind the second FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - EXPECT_THAT( - bind(socket2->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + EXPECT_THAT(bind(socket2->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket2->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket2->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -912,10 +876,10 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastDropAddr) { reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - EXPECT_THAT(RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + EXPECT_THAT( + RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we did not receive the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -935,20 +899,17 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastDropNic) { // IP_MULTICAST_IF for setting the default send interface. auto sender_addr = V4Loopback(); EXPECT_THAT( - bind(socket1->get(), reinterpret_cast<sockaddr*>(&sender_addr.addr), - sender_addr.addr_len), + bind(socket1->get(), AsSockAddr(&sender_addr.addr), sender_addr.addr_len), SyscallSucceeds()); // Bind the second FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - EXPECT_THAT( - bind(socket2->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + EXPECT_THAT(bind(socket2->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket2->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket2->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -970,10 +931,10 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastDropNic) { reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - EXPECT_THAT(RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + EXPECT_THAT( + RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we did not receive the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -1194,6 +1155,8 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastIfSetNic) { } TEST_P(IPv4UDPUnboundSocketTest, TestJoinGroupNoIf) { + // TODO(b/185517803): Fix for native test. + SKIP_IF(!IsRunningOnGvisor()); auto socket1 = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); auto socket2 = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); @@ -1292,16 +1255,15 @@ TEST_P(IPv4UDPUnboundSocketTest, TestMcastReceptionOnTwoSockets) { ASSERT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, sizeof(group)), SyscallSucceeds()); - ASSERT_THAT(bind(sockets->second_fd(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(bind(sockets->second_fd(), AsSockAddr(&receiver_addr.addr), receiver_addr.addr_len), SyscallSucceeds()); // Get the port assigned. socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(sockets->second_fd(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), - &receiver_addr_len), - SyscallSucceeds()); + ASSERT_THAT( + getsockname(sockets->second_fd(), AsSockAddr(&receiver_addr.addr), + &receiver_addr_len), + SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); // On the first iteration, save the port we are bound to. On the second // iteration, verify the port is the same as the one from the first @@ -1324,8 +1286,7 @@ TEST_P(IPv4UDPUnboundSocketTest, TestMcastReceptionOnTwoSockets) { RandomizeBuffer(send_buf, sizeof(send_buf)); ASSERT_THAT( RetryEINTR(sendto)(sockets->first_fd(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), + AsSockAddr(&send_addr.addr), send_addr.addr_len), SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we received the multicast packet on both sockets. @@ -1367,16 +1328,15 @@ TEST_P(IPv4UDPUnboundSocketTest, TestMcastReceptionWhenDroppingMemberships) { ASSERT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, sizeof(group)), SyscallSucceeds()); - ASSERT_THAT(bind(sockets->second_fd(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(bind(sockets->second_fd(), AsSockAddr(&receiver_addr.addr), receiver_addr.addr_len), SyscallSucceeds()); // Get the port assigned. socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(sockets->second_fd(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), - &receiver_addr_len), - SyscallSucceeds()); + ASSERT_THAT( + getsockname(sockets->second_fd(), AsSockAddr(&receiver_addr.addr), + &receiver_addr_len), + SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); // On the first iteration, save the port we are bound to. On the second // iteration, verify the port is the same as the one from the first @@ -1403,8 +1363,7 @@ TEST_P(IPv4UDPUnboundSocketTest, TestMcastReceptionWhenDroppingMemberships) { RandomizeBuffer(send_buf, sizeof(send_buf)); ASSERT_THAT( RetryEINTR(sendto)(sockets->first_fd(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), + AsSockAddr(&send_addr.addr), send_addr.addr_len), SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we received the multicast packet on both sockets. @@ -1427,8 +1386,7 @@ TEST_P(IPv4UDPUnboundSocketTest, TestMcastReceptionWhenDroppingMemberships) { char send_buf[200]; ASSERT_THAT( RetryEINTR(sendto)(sockets->first_fd(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), + AsSockAddr(&send_addr.addr), send_addr.addr_len), SyscallSucceedsWithValue(sizeof(send_buf))); char recv_buf[sizeof(send_buf)] = {}; @@ -1448,14 +1406,12 @@ TEST_P(IPv4UDPUnboundSocketTest, TestBindToMcastThenJoinThenReceive) { // Bind second socket (receiver) to the multicast address. auto receiver_addr = V4Multicast(); - ASSERT_THAT( - bind(socket2->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(socket2->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); // Update receiver_addr with the correct port number. socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket2->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket2->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -1479,10 +1435,10 @@ TEST_P(IPv4UDPUnboundSocketTest, TestBindToMcastThenJoinThenReceive) { reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&sendto_addr.addr), - sendto_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&sendto_addr.addr), sendto_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we received the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -1500,14 +1456,12 @@ TEST_P(IPv4UDPUnboundSocketTest, TestBindToMcastThenNoJoinThenNoReceive) { // Bind second socket (receiver) to the multicast address. auto receiver_addr = V4Multicast(); - ASSERT_THAT( - bind(socket2->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(socket2->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); // Update receiver_addr with the correct port number. socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket2->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket2->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -1523,10 +1477,10 @@ TEST_P(IPv4UDPUnboundSocketTest, TestBindToMcastThenNoJoinThenNoReceive) { reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&sendto_addr.addr), - sendto_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&sendto_addr.addr), sendto_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we don't receive the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -1543,13 +1497,11 @@ TEST_P(IPv4UDPUnboundSocketTest, TestBindToMcastThenSend) { // Bind second socket (receiver) to the ANY address. auto receiver_addr = V4Any(); - ASSERT_THAT( - bind(socket2->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(socket2->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket2->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket2->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -1557,12 +1509,10 @@ TEST_P(IPv4UDPUnboundSocketTest, TestBindToMcastThenSend) { // Bind the first socket (sender) to the multicast address. auto sender_addr = V4Multicast(); ASSERT_THAT( - bind(socket1->get(), reinterpret_cast<sockaddr*>(&sender_addr.addr), - sender_addr.addr_len), + bind(socket1->get(), AsSockAddr(&sender_addr.addr), sender_addr.addr_len), SyscallSucceeds()); socklen_t sender_addr_len = sender_addr.addr_len; - ASSERT_THAT(getsockname(socket1->get(), - reinterpret_cast<sockaddr*>(&sender_addr.addr), + ASSERT_THAT(getsockname(socket1->get(), AsSockAddr(&sender_addr.addr), &sender_addr_len), SyscallSucceeds()); EXPECT_EQ(sender_addr_len, sender_addr.addr_len); @@ -1573,10 +1523,10 @@ TEST_P(IPv4UDPUnboundSocketTest, TestBindToMcastThenSend) { reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&sendto_addr.addr), - sendto_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&sendto_addr.addr), sendto_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we received the packet. char recv_buf[sizeof(send_buf)] = {}; @@ -1594,13 +1544,11 @@ TEST_P(IPv4UDPUnboundSocketTest, TestBindToBcastThenReceive) { // Bind second socket (receiver) to the broadcast address. auto receiver_addr = V4Broadcast(); - ASSERT_THAT( - bind(socket2->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(socket2->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket2->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket2->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -1611,19 +1559,18 @@ TEST_P(IPv4UDPUnboundSocketTest, TestBindToBcastThenReceive) { SyscallSucceedsWithValue(0)); // Note: Binding to the loopback interface makes the broadcast go out of it. auto sender_bind_addr = V4Loopback(); - ASSERT_THAT( - bind(socket1->get(), reinterpret_cast<sockaddr*>(&sender_bind_addr.addr), - sender_bind_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(socket1->get(), AsSockAddr(&sender_bind_addr.addr), + sender_bind_addr.addr_len), + SyscallSucceeds()); auto sendto_addr = V4Broadcast(); reinterpret_cast<sockaddr_in*>(&sendto_addr.addr)->sin_port = reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&sendto_addr.addr), - sendto_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&sendto_addr.addr), sendto_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we received the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -1641,13 +1588,11 @@ TEST_P(IPv4UDPUnboundSocketTest, TestBindToBcastThenSend) { // Bind second socket (receiver) to the ANY address. auto receiver_addr = V4Any(); - ASSERT_THAT( - bind(socket2->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(socket2->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(socket2->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(socket2->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -1655,12 +1600,10 @@ TEST_P(IPv4UDPUnboundSocketTest, TestBindToBcastThenSend) { // Bind the first socket (sender) to the broadcast address. auto sender_addr = V4Broadcast(); ASSERT_THAT( - bind(socket1->get(), reinterpret_cast<sockaddr*>(&sender_addr.addr), - sender_addr.addr_len), + bind(socket1->get(), AsSockAddr(&sender_addr.addr), sender_addr.addr_len), SyscallSucceeds()); socklen_t sender_addr_len = sender_addr.addr_len; - ASSERT_THAT(getsockname(socket1->get(), - reinterpret_cast<sockaddr*>(&sender_addr.addr), + ASSERT_THAT(getsockname(socket1->get(), AsSockAddr(&sender_addr.addr), &sender_addr_len), SyscallSucceeds()); EXPECT_EQ(sender_addr_len, sender_addr.addr_len); @@ -1671,10 +1614,10 @@ TEST_P(IPv4UDPUnboundSocketTest, TestBindToBcastThenSend) { reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&sendto_addr.addr), - sendto_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(socket1->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&sendto_addr.addr), sendto_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we received the packet. char recv_buf[sizeof(send_buf)] = {}; @@ -1688,7 +1631,7 @@ TEST_P(IPv4UDPUnboundSocketTest, TestBindToBcastThenSend) { // // FIXME(gvisor.dev/issue/873): Endpoint order is not restored correctly. Enable // random and co-op save (below) once that is fixed. -TEST_P(IPv4UDPUnboundSocketTest, ReuseAddrDistribution_NoRandomSave) { +TEST_P(IPv4UDPUnboundSocketTest, ReuseAddrDistribution) { std::vector<std::unique_ptr<FileDescriptor>> sockets; sockets.emplace_back(ASSERT_NO_ERRNO_AND_VALUE(NewSocket())); @@ -1698,12 +1641,10 @@ TEST_P(IPv4UDPUnboundSocketTest, ReuseAddrDistribution_NoRandomSave) { // Bind the first socket to the loopback and take note of the selected port. auto addr = V4Loopback(); - ASSERT_THAT(bind(sockets[0]->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(sockets[0]->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); socklen_t addr_len = addr.addr_len; - ASSERT_THAT(getsockname(sockets[0]->get(), - reinterpret_cast<sockaddr*>(&addr.addr), &addr_len), + ASSERT_THAT(getsockname(sockets[0]->get(), AsSockAddr(&addr.addr), &addr_len), SyscallSucceeds()); EXPECT_EQ(addr_len, addr.addr_len); @@ -1719,8 +1660,7 @@ TEST_P(IPv4UDPUnboundSocketTest, ReuseAddrDistribution_NoRandomSave) { ASSERT_THAT(setsockopt(last->get(), SOL_SOCKET, SO_REUSEADDR, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(last->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(last->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); // Send a new message to the SO_REUSEADDR group. We use a new socket each @@ -1730,8 +1670,7 @@ TEST_P(IPv4UDPUnboundSocketTest, ReuseAddrDistribution_NoRandomSave) { char send_buf[kMessageSize]; RandomizeBuffer(send_buf, sizeof(send_buf)); EXPECT_THAT(RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceedsWithValue(sizeof(send_buf))); // Verify that the most recent socket got the message. We don't expect any @@ -1763,12 +1702,10 @@ TEST_P(IPv4UDPUnboundSocketTest, BindReuseAddrThenReusePort) { // Bind the first socket to the loopback and take note of the selected port. auto addr = V4Loopback(); - ASSERT_THAT(bind(socket1->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket1->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); socklen_t addr_len = addr.addr_len; - ASSERT_THAT(getsockname(socket1->get(), - reinterpret_cast<sockaddr*>(&addr.addr), &addr_len), + ASSERT_THAT(getsockname(socket1->get(), AsSockAddr(&addr.addr), &addr_len), SyscallSucceeds()); EXPECT_EQ(addr_len, addr.addr_len); @@ -1776,8 +1713,7 @@ TEST_P(IPv4UDPUnboundSocketTest, BindReuseAddrThenReusePort) { ASSERT_THAT(setsockopt(socket2->get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(socket2->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket2->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallFailsWithErrno(EADDRINUSE)); } @@ -1792,12 +1728,10 @@ TEST_P(IPv4UDPUnboundSocketTest, BindReusePortThenReuseAddr) { // Bind the first socket to the loopback and take note of the selected port. auto addr = V4Loopback(); - ASSERT_THAT(bind(socket1->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket1->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); socklen_t addr_len = addr.addr_len; - ASSERT_THAT(getsockname(socket1->get(), - reinterpret_cast<sockaddr*>(&addr.addr), &addr_len), + ASSERT_THAT(getsockname(socket1->get(), AsSockAddr(&addr.addr), &addr_len), SyscallSucceeds()); EXPECT_EQ(addr_len, addr.addr_len); @@ -1805,8 +1739,7 @@ TEST_P(IPv4UDPUnboundSocketTest, BindReusePortThenReuseAddr) { ASSERT_THAT(setsockopt(socket2->get(), SOL_SOCKET, SO_REUSEADDR, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(socket2->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket2->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallFailsWithErrno(EADDRINUSE)); } @@ -1825,12 +1758,10 @@ TEST_P(IPv4UDPUnboundSocketTest, BindReuseAddrReusePortConvertibleToReusePort) { // Bind the first socket to the loopback and take note of the selected port. auto addr = V4Loopback(); - ASSERT_THAT(bind(socket1->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket1->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); socklen_t addr_len = addr.addr_len; - ASSERT_THAT(getsockname(socket1->get(), - reinterpret_cast<sockaddr*>(&addr.addr), &addr_len), + ASSERT_THAT(getsockname(socket1->get(), AsSockAddr(&addr.addr), &addr_len), SyscallSucceeds()); EXPECT_EQ(addr_len, addr.addr_len); @@ -1838,16 +1769,14 @@ TEST_P(IPv4UDPUnboundSocketTest, BindReuseAddrReusePortConvertibleToReusePort) { ASSERT_THAT(setsockopt(socket2->get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(socket2->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket2->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); // Bind socket3 to the same address as socket1, only with REUSEADDR. ASSERT_THAT(setsockopt(socket3->get(), SOL_SOCKET, SO_REUSEADDR, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(socket3->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket3->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallFailsWithErrno(EADDRINUSE)); } @@ -1866,12 +1795,10 @@ TEST_P(IPv4UDPUnboundSocketTest, BindReuseAddrReusePortConvertibleToReuseAddr) { // Bind the first socket to the loopback and take note of the selected port. auto addr = V4Loopback(); - ASSERT_THAT(bind(socket1->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket1->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); socklen_t addr_len = addr.addr_len; - ASSERT_THAT(getsockname(socket1->get(), - reinterpret_cast<sockaddr*>(&addr.addr), &addr_len), + ASSERT_THAT(getsockname(socket1->get(), AsSockAddr(&addr.addr), &addr_len), SyscallSucceeds()); EXPECT_EQ(addr_len, addr.addr_len); @@ -1879,16 +1806,14 @@ TEST_P(IPv4UDPUnboundSocketTest, BindReuseAddrReusePortConvertibleToReuseAddr) { ASSERT_THAT(setsockopt(socket2->get(), SOL_SOCKET, SO_REUSEADDR, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(socket2->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket2->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); // Bind socket3 to the same address as socket1, only with REUSEPORT. ASSERT_THAT(setsockopt(socket3->get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(socket3->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket3->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallFailsWithErrno(EADDRINUSE)); } @@ -1907,12 +1832,10 @@ TEST_P(IPv4UDPUnboundSocketTest, BindReuseAddrReusePortConversionReversable1) { // Bind the first socket to the loopback and take note of the selected port. auto addr = V4Loopback(); - ASSERT_THAT(bind(socket1->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket1->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); socklen_t addr_len = addr.addr_len; - ASSERT_THAT(getsockname(socket1->get(), - reinterpret_cast<sockaddr*>(&addr.addr), &addr_len), + ASSERT_THAT(getsockname(socket1->get(), AsSockAddr(&addr.addr), &addr_len), SyscallSucceeds()); EXPECT_EQ(addr_len, addr.addr_len); @@ -1920,8 +1843,7 @@ TEST_P(IPv4UDPUnboundSocketTest, BindReuseAddrReusePortConversionReversable1) { ASSERT_THAT(setsockopt(socket2->get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(socket2->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket2->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); // Close socket2 to revert to just socket1 with REUSEADDR and REUSEPORT. @@ -1931,8 +1853,7 @@ TEST_P(IPv4UDPUnboundSocketTest, BindReuseAddrReusePortConversionReversable1) { ASSERT_THAT(setsockopt(socket3->get(), SOL_SOCKET, SO_REUSEADDR, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(socket3->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket3->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); } @@ -1951,12 +1872,10 @@ TEST_P(IPv4UDPUnboundSocketTest, BindReuseAddrReusePortConversionReversable2) { // Bind the first socket to the loopback and take note of the selected port. auto addr = V4Loopback(); - ASSERT_THAT(bind(socket1->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket1->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); socklen_t addr_len = addr.addr_len; - ASSERT_THAT(getsockname(socket1->get(), - reinterpret_cast<sockaddr*>(&addr.addr), &addr_len), + ASSERT_THAT(getsockname(socket1->get(), AsSockAddr(&addr.addr), &addr_len), SyscallSucceeds()); EXPECT_EQ(addr_len, addr.addr_len); @@ -1964,8 +1883,7 @@ TEST_P(IPv4UDPUnboundSocketTest, BindReuseAddrReusePortConversionReversable2) { ASSERT_THAT(setsockopt(socket2->get(), SOL_SOCKET, SO_REUSEADDR, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(socket2->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket2->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); // Close socket2 to revert to just socket1 with REUSEADDR and REUSEPORT. @@ -1975,8 +1893,7 @@ TEST_P(IPv4UDPUnboundSocketTest, BindReuseAddrReusePortConversionReversable2) { ASSERT_THAT(setsockopt(socket3->get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(socket3->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket3->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); } @@ -1995,12 +1912,10 @@ TEST_P(IPv4UDPUnboundSocketTest, BindDoubleReuseAddrReusePortThenReusePort) { // Bind the first socket to the loopback and take note of the selected port. auto addr = V4Loopback(); - ASSERT_THAT(bind(socket1->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket1->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); socklen_t addr_len = addr.addr_len; - ASSERT_THAT(getsockname(socket1->get(), - reinterpret_cast<sockaddr*>(&addr.addr), &addr_len), + ASSERT_THAT(getsockname(socket1->get(), AsSockAddr(&addr.addr), &addr_len), SyscallSucceeds()); EXPECT_EQ(addr_len, addr.addr_len); @@ -2013,16 +1928,14 @@ TEST_P(IPv4UDPUnboundSocketTest, BindDoubleReuseAddrReusePortThenReusePort) { sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(socket2->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket2->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); // Bind socket3 to the same address as socket1, only with REUSEPORT. ASSERT_THAT(setsockopt(socket3->get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(socket3->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket3->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); } @@ -2041,12 +1954,10 @@ TEST_P(IPv4UDPUnboundSocketTest, BindDoubleReuseAddrReusePortThenReuseAddr) { // Bind the first socket to the loopback and take note of the selected port. auto addr = V4Loopback(); - ASSERT_THAT(bind(socket1->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket1->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); socklen_t addr_len = addr.addr_len; - ASSERT_THAT(getsockname(socket1->get(), - reinterpret_cast<sockaddr*>(&addr.addr), &addr_len), + ASSERT_THAT(getsockname(socket1->get(), AsSockAddr(&addr.addr), &addr_len), SyscallSucceeds()); EXPECT_EQ(addr_len, addr.addr_len); @@ -2059,16 +1970,14 @@ TEST_P(IPv4UDPUnboundSocketTest, BindDoubleReuseAddrReusePortThenReuseAddr) { sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(socket2->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket2->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); // Bind socket3 to the same address as socket1, only with REUSEADDR. ASSERT_THAT(setsockopt(socket3->get(), SOL_SOCKET, SO_REUSEADDR, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(socket3->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(socket3->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); } @@ -2086,12 +1995,10 @@ TEST_P(IPv4UDPUnboundSocketTest, ReuseAddrReusePortDistribution) { // Bind the first socket to the loopback and take note of the selected port. auto addr = V4Loopback(); - ASSERT_THAT(bind(receiver1->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(receiver1->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); socklen_t addr_len = addr.addr_len; - ASSERT_THAT(getsockname(receiver1->get(), - reinterpret_cast<sockaddr*>(&addr.addr), &addr_len), + ASSERT_THAT(getsockname(receiver1->get(), AsSockAddr(&addr.addr), &addr_len), SyscallSucceeds()); EXPECT_EQ(addr_len, addr.addr_len); @@ -2103,8 +2010,7 @@ TEST_P(IPv4UDPUnboundSocketTest, ReuseAddrReusePortDistribution) { ASSERT_THAT(setsockopt(receiver2->get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT(bind(receiver2->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(receiver2->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); constexpr int kMessageSize = 10; @@ -2119,8 +2025,7 @@ TEST_P(IPv4UDPUnboundSocketTest, ReuseAddrReusePortDistribution) { auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); char send_buf[kMessageSize] = {}; EXPECT_THAT(RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceedsWithValue(sizeof(send_buf))); } @@ -2149,13 +2054,11 @@ TEST_P(IPv4UDPUnboundSocketTest, SetAndReceiveIPPKTINFO) { int level = SOL_IP; int type = IP_PKTINFO; - ASSERT_THAT( - bind(receiver->get(), reinterpret_cast<sockaddr*>(&sender_addr.addr), - sender_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(receiver->get(), AsSockAddr(&sender_addr.addr), + sender_addr.addr_len), + SyscallSucceeds()); socklen_t sender_addr_len = sender_addr.addr_len; - ASSERT_THAT(getsockname(receiver->get(), - reinterpret_cast<sockaddr*>(&sender_addr.addr), + ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&sender_addr.addr), &sender_addr_len), SyscallSucceeds()); EXPECT_EQ(sender_addr_len, sender_addr.addr_len); @@ -2163,10 +2066,9 @@ TEST_P(IPv4UDPUnboundSocketTest, SetAndReceiveIPPKTINFO) { auto receiver_addr = V4Loopback(); reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port = reinterpret_cast<sockaddr_in*>(&sender_addr.addr)->sin_port; - ASSERT_THAT( - connect(sender->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(connect(sender->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); // Allow socket to receive control message. ASSERT_THAT( @@ -2230,29 +2132,25 @@ TEST_P(IPv4UDPUnboundSocketTest, SetAndReceiveIPReceiveOrigDstAddr) { int level = SOL_IP; int type = IP_RECVORIGDSTADDR; - ASSERT_THAT( - bind(receiver->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); // Retrieve the port bound by the receiver. socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(receiver->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); - ASSERT_THAT( - connect(sender->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(connect(sender->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); // Get address and port bound by the sender. sockaddr_storage sender_addr_storage; socklen_t sender_addr_len = sizeof(sender_addr_storage); - ASSERT_THAT(getsockname(sender->get(), - reinterpret_cast<sockaddr*>(&sender_addr_storage), + ASSERT_THAT(getsockname(sender->get(), AsSockAddr(&sender_addr_storage), &sender_addr_len), SyscallSucceeds()); ASSERT_EQ(sender_addr_len, sizeof(struct sockaddr_in)); @@ -2407,9 +2305,7 @@ TEST_P(IPv4UDPUnboundSocketTest, SetSocketRecvBuf) { SyscallSucceeds()); // Linux doubles the value set by SO_SNDBUF/SO_RCVBUF. - if (!IsRunningOnGvisor()) { - quarter_sz *= 2; - } + quarter_sz *= 2; ASSERT_EQ(quarter_sz, val); } @@ -2524,22 +2420,19 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastIPPacketInfo) { // Bind the first FD to the loopback. This is an alternative to // IP_MULTICAST_IF for setting the default send interface. auto sender_addr = V4Loopback(); - ASSERT_THAT( - bind(sender_socket->get(), reinterpret_cast<sockaddr*>(&sender_addr.addr), - sender_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(sender_socket->get(), AsSockAddr(&sender_addr.addr), + sender_addr.addr_len), + SyscallSucceeds()); // Bind the second FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - ASSERT_THAT(bind(receiver_socket->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(bind(receiver_socket->get(), AsSockAddr(&receiver_addr.addr), receiver_addr.addr_len), SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; ASSERT_THAT(getsockname(receiver_socket->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), - &receiver_addr_len), + AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -2565,8 +2458,7 @@ TEST_P(IPv4UDPUnboundSocketTest, IpMulticastIPPacketInfo) { RandomizeBuffer(send_buf, sizeof(send_buf)); ASSERT_THAT( RetryEINTR(sendto)(sender_socket->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), + AsSockAddr(&send_addr.addr), send_addr.addr_len), SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we received the multicast packet. diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc index 940289d15..c6e775b2a 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc +++ b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc @@ -50,38 +50,35 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, // Bind the first socket to the ANY address and let the system assign a port. auto rcv1_addr = V4Any(); - ASSERT_THAT(bind(rcvr1->get(), reinterpret_cast<sockaddr*>(&rcv1_addr.addr), - rcv1_addr.addr_len), - SyscallSucceedsWithValue(0)); + ASSERT_THAT( + bind(rcvr1->get(), AsSockAddr(&rcv1_addr.addr), rcv1_addr.addr_len), + SyscallSucceedsWithValue(0)); // Retrieve port number from first socket so that it can be bound to the // second socket. socklen_t rcv_addr_sz = rcv1_addr.addr_len; ASSERT_THAT( - getsockname(rcvr1->get(), reinterpret_cast<sockaddr*>(&rcv1_addr.addr), - &rcv_addr_sz), + getsockname(rcvr1->get(), AsSockAddr(&rcv1_addr.addr), &rcv_addr_sz), SyscallSucceedsWithValue(0)); EXPECT_EQ(rcv_addr_sz, rcv1_addr.addr_len); auto port = reinterpret_cast<sockaddr_in*>(&rcv1_addr.addr)->sin_port; // Bind the second socket to the same address:port as the first. - ASSERT_THAT(bind(rcvr2->get(), reinterpret_cast<sockaddr*>(&rcv1_addr.addr), - rcv_addr_sz), + ASSERT_THAT(bind(rcvr2->get(), AsSockAddr(&rcv1_addr.addr), rcv_addr_sz), SyscallSucceedsWithValue(0)); // Bind the non-receiving socket to an ephemeral port. auto norecv_addr = V4Any(); - ASSERT_THAT(bind(norcv->get(), reinterpret_cast<sockaddr*>(&norecv_addr.addr), - norecv_addr.addr_len), - SyscallSucceedsWithValue(0)); + ASSERT_THAT( + bind(norcv->get(), AsSockAddr(&norecv_addr.addr), norecv_addr.addr_len), + SyscallSucceedsWithValue(0)); // Broadcast a test message. auto dst_addr = V4Broadcast(); reinterpret_cast<sockaddr_in*>(&dst_addr.addr)->sin_port = port; constexpr char kTestMsg[] = "hello, world"; - EXPECT_THAT( - sendto(sender->get(), kTestMsg, sizeof(kTestMsg), 0, - reinterpret_cast<sockaddr*>(&dst_addr.addr), dst_addr.addr_len), - SyscallSucceedsWithValue(sizeof(kTestMsg))); + EXPECT_THAT(sendto(sender->get(), kTestMsg, sizeof(kTestMsg), 0, + AsSockAddr(&dst_addr.addr), dst_addr.addr_len), + SyscallSucceedsWithValue(sizeof(kTestMsg))); // Verify that the receiving sockets received the test message. char buf[sizeof(kTestMsg)] = {}; @@ -130,15 +127,14 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, // Bind the first socket the ANY address and let the system assign a port. auto rcv1_addr = V4Any(); - ASSERT_THAT(bind(rcvr1->get(), reinterpret_cast<sockaddr*>(&rcv1_addr.addr), - rcv1_addr.addr_len), - SyscallSucceedsWithValue(0)); + ASSERT_THAT( + bind(rcvr1->get(), AsSockAddr(&rcv1_addr.addr), rcv1_addr.addr_len), + SyscallSucceedsWithValue(0)); // Retrieve port number from first socket so that it can be bound to the // second socket. socklen_t rcv_addr_sz = rcv1_addr.addr_len; ASSERT_THAT( - getsockname(rcvr1->get(), reinterpret_cast<sockaddr*>(&rcv1_addr.addr), - &rcv_addr_sz), + getsockname(rcvr1->get(), AsSockAddr(&rcv1_addr.addr), &rcv_addr_sz), SyscallSucceedsWithValue(0)); EXPECT_EQ(rcv_addr_sz, rcv1_addr.addr_len); auto port = reinterpret_cast<sockaddr_in*>(&rcv1_addr.addr)->sin_port; @@ -146,26 +142,25 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, // Bind the second socket to the broadcast address. auto rcv2_addr = V4Broadcast(); reinterpret_cast<sockaddr_in*>(&rcv2_addr.addr)->sin_port = port; - ASSERT_THAT(bind(rcvr2->get(), reinterpret_cast<sockaddr*>(&rcv2_addr.addr), - rcv2_addr.addr_len), - SyscallSucceedsWithValue(0)); + ASSERT_THAT( + bind(rcvr2->get(), AsSockAddr(&rcv2_addr.addr), rcv2_addr.addr_len), + SyscallSucceedsWithValue(0)); // Bind the non-receiving socket to the unicast ethernet address. auto norecv_addr = rcv1_addr; reinterpret_cast<sockaddr_in*>(&norecv_addr.addr)->sin_addr = eth_if_addr_.sin_addr; - ASSERT_THAT(bind(norcv->get(), reinterpret_cast<sockaddr*>(&norecv_addr.addr), - norecv_addr.addr_len), - SyscallSucceedsWithValue(0)); + ASSERT_THAT( + bind(norcv->get(), AsSockAddr(&norecv_addr.addr), norecv_addr.addr_len), + SyscallSucceedsWithValue(0)); // Broadcast a test message. auto dst_addr = V4Broadcast(); reinterpret_cast<sockaddr_in*>(&dst_addr.addr)->sin_port = port; constexpr char kTestMsg[] = "hello, world"; - EXPECT_THAT( - sendto(sender->get(), kTestMsg, sizeof(kTestMsg), 0, - reinterpret_cast<sockaddr*>(&dst_addr.addr), dst_addr.addr_len), - SyscallSucceedsWithValue(sizeof(kTestMsg))); + EXPECT_THAT(sendto(sender->get(), kTestMsg, sizeof(kTestMsg), 0, + AsSockAddr(&dst_addr.addr), dst_addr.addr_len), + SyscallSucceedsWithValue(sizeof(kTestMsg))); // Verify that the receiving sockets received the test message. char buf[sizeof(kTestMsg)] = {}; @@ -199,12 +194,11 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, // Bind the sender to the broadcast address. auto src_addr = V4Broadcast(); - ASSERT_THAT(bind(sender->get(), reinterpret_cast<sockaddr*>(&src_addr.addr), - src_addr.addr_len), - SyscallSucceedsWithValue(0)); + ASSERT_THAT( + bind(sender->get(), AsSockAddr(&src_addr.addr), src_addr.addr_len), + SyscallSucceedsWithValue(0)); socklen_t src_sz = src_addr.addr_len; - ASSERT_THAT(getsockname(sender->get(), - reinterpret_cast<sockaddr*>(&src_addr.addr), &src_sz), + ASSERT_THAT(getsockname(sender->get(), AsSockAddr(&src_addr.addr), &src_sz), SyscallSucceedsWithValue(0)); EXPECT_EQ(src_sz, src_addr.addr_len); @@ -213,10 +207,9 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, reinterpret_cast<sockaddr_in*>(&dst_addr.addr)->sin_port = reinterpret_cast<sockaddr_in*>(&src_addr.addr)->sin_port; constexpr char kTestMsg[] = "hello, world"; - EXPECT_THAT( - sendto(sender->get(), kTestMsg, sizeof(kTestMsg), 0, - reinterpret_cast<sockaddr*>(&dst_addr.addr), dst_addr.addr_len), - SyscallSucceedsWithValue(sizeof(kTestMsg))); + EXPECT_THAT(sendto(sender->get(), kTestMsg, sizeof(kTestMsg), 0, + AsSockAddr(&dst_addr.addr), dst_addr.addr_len), + SyscallSucceedsWithValue(sizeof(kTestMsg))); // Verify that the message was received. char buf[sizeof(kTestMsg)] = {}; @@ -241,12 +234,11 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, // Bind the sender to the ANY address. auto src_addr = V4Any(); - ASSERT_THAT(bind(sender->get(), reinterpret_cast<sockaddr*>(&src_addr.addr), - src_addr.addr_len), - SyscallSucceedsWithValue(0)); + ASSERT_THAT( + bind(sender->get(), AsSockAddr(&src_addr.addr), src_addr.addr_len), + SyscallSucceedsWithValue(0)); socklen_t src_sz = src_addr.addr_len; - ASSERT_THAT(getsockname(sender->get(), - reinterpret_cast<sockaddr*>(&src_addr.addr), &src_sz), + ASSERT_THAT(getsockname(sender->get(), AsSockAddr(&src_addr.addr), &src_sz), SyscallSucceedsWithValue(0)); EXPECT_EQ(src_sz, src_addr.addr_len); @@ -255,10 +247,9 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, reinterpret_cast<sockaddr_in*>(&dst_addr.addr)->sin_port = reinterpret_cast<sockaddr_in*>(&src_addr.addr)->sin_port; constexpr char kTestMsg[] = "hello, world"; - EXPECT_THAT( - sendto(sender->get(), kTestMsg, sizeof(kTestMsg), 0, - reinterpret_cast<sockaddr*>(&dst_addr.addr), dst_addr.addr_len), - SyscallSucceedsWithValue(sizeof(kTestMsg))); + EXPECT_THAT(sendto(sender->get(), kTestMsg, sizeof(kTestMsg), 0, + AsSockAddr(&dst_addr.addr), dst_addr.addr_len), + SyscallSucceedsWithValue(sizeof(kTestMsg))); // Verify that the message was received. char buf[sizeof(kTestMsg)] = {}; @@ -280,7 +271,7 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, TestSendBroadcast) { constexpr char kTestMsg[] = "hello, world"; EXPECT_THAT(sendto(sender->get(), kTestMsg, sizeof(kTestMsg), 0, - reinterpret_cast<sockaddr*>(&addr.addr), addr.addr_len), + AsSockAddr(&addr.addr), addr.addr_len), SyscallFailsWithErrno(EACCES)); } @@ -294,19 +285,17 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, TestSendUnicastOnUnbound) { addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(0); - ASSERT_THAT(bind(rcvr->get(), reinterpret_cast<struct sockaddr*>(&addr), - sizeof(addr)), + ASSERT_THAT(bind(rcvr->get(), AsSockAddr(&addr), sizeof(addr)), SyscallSucceedsWithValue(0)); memset(&addr, 0, sizeof(addr)); socklen_t addr_sz = sizeof(addr); - ASSERT_THAT(getsockname(rcvr->get(), - reinterpret_cast<struct sockaddr*>(&addr), &addr_sz), + ASSERT_THAT(getsockname(rcvr->get(), AsSockAddr(&addr), &addr_sz), SyscallSucceedsWithValue(0)); // Send a test message to the receiver. constexpr char kTestMsg[] = "hello, world"; ASSERT_THAT(sendto(sender->get(), kTestMsg, sizeof(kTestMsg), 0, - reinterpret_cast<struct sockaddr*>(&addr), addr_sz), + AsSockAddr(&addr), addr_sz), SyscallSucceedsWithValue(sizeof(kTestMsg))); char buf[sizeof(kTestMsg)] = {}; ASSERT_THAT(recv(rcvr->get(), buf, sizeof(buf), 0), @@ -326,13 +315,12 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, auto socket = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); auto bind_addr = V4Any(); - ASSERT_THAT(bind(socket->get(), reinterpret_cast<sockaddr*>(&bind_addr.addr), - bind_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(socket->get(), AsSockAddr(&bind_addr.addr), bind_addr.addr_len), + SyscallSucceeds()); socklen_t bind_addr_len = bind_addr.addr_len; ASSERT_THAT( - getsockname(socket->get(), reinterpret_cast<sockaddr*>(&bind_addr.addr), - &bind_addr_len), + getsockname(socket->get(), AsSockAddr(&bind_addr.addr), &bind_addr_len), SyscallSucceeds()); EXPECT_EQ(bind_addr_len, bind_addr.addr_len); @@ -342,10 +330,10 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, reinterpret_cast<sockaddr_in*>(&bind_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(socket->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(socket->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we did not receive the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -361,13 +349,12 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, TestSendMulticastSelf) { auto socket = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); auto bind_addr = V4Any(); - ASSERT_THAT(bind(socket->get(), reinterpret_cast<sockaddr*>(&bind_addr.addr), - bind_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(socket->get(), AsSockAddr(&bind_addr.addr), bind_addr.addr_len), + SyscallSucceeds()); socklen_t bind_addr_len = bind_addr.addr_len; ASSERT_THAT( - getsockname(socket->get(), reinterpret_cast<sockaddr*>(&bind_addr.addr), - &bind_addr_len), + getsockname(socket->get(), AsSockAddr(&bind_addr.addr), &bind_addr_len), SyscallSucceeds()); EXPECT_EQ(bind_addr_len, bind_addr.addr_len); @@ -384,10 +371,10 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, TestSendMulticastSelf) { reinterpret_cast<sockaddr_in*>(&bind_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(socket->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(socket->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we received the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -405,13 +392,12 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, auto socket = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); auto bind_addr = V4Any(); - ASSERT_THAT(bind(socket->get(), reinterpret_cast<sockaddr*>(&bind_addr.addr), - bind_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(socket->get(), AsSockAddr(&bind_addr.addr), bind_addr.addr_len), + SyscallSucceeds()); socklen_t bind_addr_len = bind_addr.addr_len; ASSERT_THAT( - getsockname(socket->get(), reinterpret_cast<sockaddr*>(&bind_addr.addr), - &bind_addr_len), + getsockname(socket->get(), AsSockAddr(&bind_addr.addr), &bind_addr_len), SyscallSucceeds()); EXPECT_EQ(bind_addr_len, bind_addr.addr_len); @@ -433,10 +419,10 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, reinterpret_cast<sockaddr_in*>(&bind_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(socket->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(socket->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we did not receive the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -460,13 +446,11 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, TestSendMulticastNoGroup) { // Bind the second FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - ASSERT_THAT( - bind(receiver->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(receiver->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -477,10 +461,10 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, TestSendMulticastNoGroup) { reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we did not receive the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -499,13 +483,11 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, TestSendMulticast) { // Bind the second FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - ASSERT_THAT( - bind(receiver->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(receiver->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -523,10 +505,10 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, TestSendMulticast) { reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we received the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -547,13 +529,11 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, // Bind the second FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - ASSERT_THAT( - bind(receiver->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(receiver->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -576,10 +556,10 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we did not receive the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -600,13 +580,11 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, // Bind the second FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - ASSERT_THAT( - bind(receiver->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(receiver->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -629,10 +607,10 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we received the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -661,13 +639,11 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); // Bind to ANY to receive multicast packets. - ASSERT_THAT( - bind(receiver->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(receiver->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -696,10 +672,10 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, reinterpret_cast<sockaddr_in*>(&send_addr.addr)->sin_port = bound_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); for (auto& receiver : receivers) { char recv_buf[sizeof(send_buf)] = {}; ASSERT_THAT( @@ -727,13 +703,11 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, ASSERT_THAT(setsockopt(receiver->get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT( - bind(receiver->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(receiver->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -765,10 +739,10 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, reinterpret_cast<sockaddr_in*>(&send_addr.addr)->sin_port = bound_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); for (auto& receiver : receivers) { char recv_buf[sizeof(send_buf)] = {}; ASSERT_THAT( @@ -798,13 +772,11 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, ASSERT_THAT(setsockopt(receiver->get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); - ASSERT_THAT( - bind(receiver->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(receiver->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -840,10 +812,10 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, reinterpret_cast<sockaddr_in*>(&send_addr.addr)->sin_port = bound_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); for (auto& receiver : receivers) { char recv_buf[sizeof(send_buf)] = {}; ASSERT_THAT( @@ -863,13 +835,11 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, auto receiver = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); auto receiver_addr = V4Any(); - ASSERT_THAT( - bind(receiver->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(receiver->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -887,15 +857,13 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, // receiver side). auto sendto_addr = V4Multicast(); reinterpret_cast<sockaddr_in*>(&sendto_addr.addr)->sin_port = receiver_port; - ASSERT_THAT(RetryEINTR(connect)( - sender->get(), reinterpret_cast<sockaddr*>(&sendto_addr.addr), - sendto_addr.addr_len), + ASSERT_THAT(RetryEINTR(connect)(sender->get(), AsSockAddr(&sendto_addr.addr), + sendto_addr.addr_len), SyscallSucceeds()); auto sender_addr = V4EmptyAddress(); - ASSERT_THAT( - getsockname(sender->get(), reinterpret_cast<sockaddr*>(&sender_addr.addr), - &sender_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(getsockname(sender->get(), AsSockAddr(&sender_addr.addr), + &sender_addr.addr_len), + SyscallSucceeds()); ASSERT_EQ(sizeof(struct sockaddr_in), sender_addr.addr_len); sockaddr_in* sender_addr_in = reinterpret_cast<sockaddr_in*>(&sender_addr.addr); @@ -910,8 +878,7 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, auto src_addr = V4EmptyAddress(); ASSERT_THAT( RetryEINTR(recvfrom)(receiver->get(), recv_buf, sizeof(recv_buf), 0, - reinterpret_cast<sockaddr*>(&src_addr.addr), - &src_addr.addr_len), + AsSockAddr(&src_addr.addr), &src_addr.addr_len), SyscallSucceedsWithValue(sizeof(recv_buf))); ASSERT_EQ(sizeof(struct sockaddr_in), src_addr.addr_len); sockaddr_in* src_addr_in = reinterpret_cast<sockaddr_in*>(&src_addr.addr); @@ -931,13 +898,11 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, // Create receiver, bind to ANY and join the multicast group. auto receiver = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); auto receiver_addr = V4Any(); - ASSERT_THAT( - bind(receiver->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(receiver->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -964,18 +929,17 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, auto sendto_addr = V4Multicast(); reinterpret_cast<sockaddr_in*>(&sendto_addr.addr)->sin_port = receiver_port; char send_buf[4] = {}; - ASSERT_THAT(RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&sendto_addr.addr), - sendto_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&sendto_addr.addr), sendto_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Receive a multicast packet. char recv_buf[sizeof(send_buf)] = {}; auto src_addr = V4EmptyAddress(); ASSERT_THAT( RetryEINTR(recvfrom)(receiver->get(), recv_buf, sizeof(recv_buf), 0, - reinterpret_cast<sockaddr*>(&src_addr.addr), - &src_addr.addr_len), + AsSockAddr(&src_addr.addr), &src_addr.addr_len), SyscallSucceedsWithValue(sizeof(recv_buf))); ASSERT_EQ(sizeof(struct sockaddr_in), src_addr.addr_len); sockaddr_in* src_addr_in = reinterpret_cast<sockaddr_in*>(&src_addr.addr); @@ -1000,9 +964,9 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, // Create sender and bind to eth interface. auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); - ASSERT_THAT(bind(sender->get(), reinterpret_cast<sockaddr*>(ð_if_addr_), - sizeof(eth_if_addr_)), - SyscallSucceeds()); + ASSERT_THAT( + bind(sender->get(), AsSockAddr(ð_if_addr_), sizeof(eth_if_addr_)), + SyscallSucceeds()); // Run through all possible combinations of index and address for // IP_MULTICAST_IF that selects the loopback interface. diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_loopback_nogotsan.cc b/test/syscalls/linux/socket_ipv4_udp_unbound_loopback_nogotsan.cc index bcbd2feac..7ca6d52e4 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound_loopback_nogotsan.cc +++ b/test/syscalls/linux/socket_ipv4_udp_unbound_loopback_nogotsan.cc @@ -29,18 +29,15 @@ using IPv4UDPUnboundSocketNogotsanTest = SimpleSocketTest; // Check that connect returns EAGAIN when out of local ephemeral ports. // We disable S/R because this test creates a large number of sockets. -TEST_P(IPv4UDPUnboundSocketNogotsanTest, - UDPConnectPortExhaustion_NoRandomSave) { +TEST_P(IPv4UDPUnboundSocketNogotsanTest, UDPConnectPortExhaustion) { auto receiver1 = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); constexpr int kClients = 65536; // Bind the first socket to the loopback and take note of the selected port. auto addr = V4Loopback(); - ASSERT_THAT(bind(receiver1->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len), + ASSERT_THAT(bind(receiver1->get(), AsSockAddr(&addr.addr), addr.addr_len), SyscallSucceeds()); socklen_t addr_len = addr.addr_len; - ASSERT_THAT(getsockname(receiver1->get(), - reinterpret_cast<sockaddr*>(&addr.addr), &addr_len), + ASSERT_THAT(getsockname(receiver1->get(), AsSockAddr(&addr.addr), &addr_len), SyscallSucceeds()); EXPECT_EQ(addr_len, addr.addr_len); @@ -50,8 +47,7 @@ TEST_P(IPv4UDPUnboundSocketNogotsanTest, for (int i = 0; i < kClients; i++) { auto s = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); - int ret = connect(s->get(), reinterpret_cast<sockaddr*>(&addr.addr), - addr.addr_len); + int ret = connect(s->get(), AsSockAddr(&addr.addr), addr.addr_len); if (ret == 0) { sockets.push_back(std::move(s)); continue; @@ -63,7 +59,7 @@ TEST_P(IPv4UDPUnboundSocketNogotsanTest, // Check that bind returns EADDRINUSE when out of local ephemeral ports. // We disable S/R because this test creates a large number of sockets. -TEST_P(IPv4UDPUnboundSocketNogotsanTest, UDPBindPortExhaustion_NoRandomSave) { +TEST_P(IPv4UDPUnboundSocketNogotsanTest, UDPBindPortExhaustion) { auto receiver1 = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); constexpr int kClients = 65536; auto addr = V4Loopback(); @@ -73,8 +69,7 @@ TEST_P(IPv4UDPUnboundSocketNogotsanTest, UDPBindPortExhaustion_NoRandomSave) { for (int i = 0; i < kClients; i++) { auto s = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); - int ret = - bind(s->get(), reinterpret_cast<sockaddr*>(&addr.addr), addr.addr_len); + int ret = bind(s->get(), AsSockAddr(&addr.addr), addr.addr_len); if (ret == 0) { sockets.push_back(std::move(s)); continue; diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_netlink.cc b/test/syscalls/linux/socket_ipv4_udp_unbound_netlink.cc index 9a9ddc297..020ce5d6e 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound_netlink.cc +++ b/test/syscalls/linux/socket_ipv4_udp_unbound_netlink.cc @@ -56,10 +56,9 @@ TEST_P(IPv4UDPUnboundSocketNetlinkTest, JoinSubnet) { ASSERT_EQ(1, inet_pton(AF_INET, "192.0.2.2", &(reinterpret_cast<sockaddr_in*>(&sender_addr.addr) ->sin_addr.s_addr))); - ASSERT_THAT( - bind(snd_sock->get(), reinterpret_cast<sockaddr*>(&sender_addr.addr), - sender_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(snd_sock->get(), AsSockAddr(&sender_addr.addr), + sender_addr.addr_len), + SyscallSucceeds()); // Send the packet to an unassigned address but an address that is in the // subnet associated with the loopback interface. @@ -69,23 +68,20 @@ TEST_P(IPv4UDPUnboundSocketNetlinkTest, JoinSubnet) { ASSERT_EQ(1, inet_pton(AF_INET, "192.0.2.254", &(reinterpret_cast<sockaddr_in*>(&receiver_addr.addr) ->sin_addr.s_addr))); - ASSERT_THAT( - bind(rcv_sock->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(rcv_sock->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(rcv_sock->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(rcv_sock->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); ASSERT_EQ(receiver_addr_len, receiver_addr.addr_len); char send_buf[kSendBufSize]; RandomizeBuffer(send_buf, kSendBufSize); - ASSERT_THAT( - RetryEINTR(sendto)(snd_sock->get(), send_buf, kSendBufSize, 0, - reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceedsWithValue(kSendBufSize)); + ASSERT_THAT(RetryEINTR(sendto)(snd_sock->get(), send_buf, kSendBufSize, 0, + AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceedsWithValue(kSendBufSize)); // Check that we received the packet. char recv_buf[kSendBufSize] = {}; @@ -155,14 +151,12 @@ TEST_P(IPv4UDPUnboundSocketNetlinkTest, ReuseAddrSubnetDirectedBroadcast) { << "socks[" << idx << "]"; if (bind_wildcard) { - ASSERT_THAT( - bind(sock->get(), reinterpret_cast<sockaddr*>(&any_address.addr), - any_address.addr_len), - SyscallSucceeds()) + ASSERT_THAT(bind(sock->get(), AsSockAddr(&any_address.addr), + any_address.addr_len), + SyscallSucceeds()) << "socks[" << idx << "]"; } else { - ASSERT_THAT(bind(sock->get(), - reinterpret_cast<sockaddr*>(&broadcast_address.addr), + ASSERT_THAT(bind(sock->get(), AsSockAddr(&broadcast_address.addr), broadcast_address.addr_len), SyscallSucceeds()) << "socks[" << idx << "]"; @@ -177,17 +171,16 @@ TEST_P(IPv4UDPUnboundSocketNetlinkTest, ReuseAddrSubnetDirectedBroadcast) { // Broadcasts from each socket should be received by every socket (including // the sending socket). - for (long unsigned int w = 0; w < socks.size(); w++) { + for (size_t w = 0; w < socks.size(); w++) { auto& w_sock = socks[w]; - ASSERT_THAT( - RetryEINTR(sendto)(w_sock->get(), send_buf, kSendBufSize, 0, - reinterpret_cast<sockaddr*>(&broadcast_address.addr), - broadcast_address.addr_len), - SyscallSucceedsWithValue(kSendBufSize)) + ASSERT_THAT(RetryEINTR(sendto)(w_sock->get(), send_buf, kSendBufSize, 0, + AsSockAddr(&broadcast_address.addr), + broadcast_address.addr_len), + SyscallSucceedsWithValue(kSendBufSize)) << "write socks[" << w << "]"; // Check that we received the packet on all sockets. - for (long unsigned int r = 0; r < socks.size(); r++) { + for (size_t r = 0; r < socks.size(); r++) { auto& r_sock = socks[r]; struct pollfd poll_fd = {r_sock->get(), POLLIN, 0}; diff --git a/test/syscalls/linux/socket_ipv6_udp_unbound.cc b/test/syscalls/linux/socket_ipv6_udp_unbound.cc index 08526468e..a4e3371f4 100644 --- a/test/syscalls/linux/socket_ipv6_udp_unbound.cc +++ b/test/syscalls/linux/socket_ipv6_udp_unbound.cc @@ -47,29 +47,25 @@ TEST_P(IPv6UDPUnboundSocketTest, SetAndReceiveIPReceiveOrigDstAddr) { int level = SOL_IPV6; int type = IPV6_RECVORIGDSTADDR; - ASSERT_THAT( - bind(receiver->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); // Retrieve the port bound by the receiver. socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(receiver->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); - ASSERT_THAT( - connect(sender->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(connect(sender->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); // Get address and port bound by the sender. sockaddr_storage sender_addr_storage; socklen_t sender_addr_len = sizeof(sender_addr_storage); - ASSERT_THAT(getsockname(sender->get(), - reinterpret_cast<sockaddr*>(&sender_addr_storage), + ASSERT_THAT(getsockname(sender->get(), AsSockAddr(&sender_addr_storage), &sender_addr_len), SyscallSucceeds()); ASSERT_EQ(sender_addr_len, sizeof(struct sockaddr_in6)); diff --git a/test/syscalls/linux/socket_ipv6_udp_unbound_external_networking.cc b/test/syscalls/linux/socket_ipv6_udp_unbound_external_networking.cc index 7364a1ea5..8390f7c3b 100644 --- a/test/syscalls/linux/socket_ipv6_udp_unbound_external_networking.cc +++ b/test/syscalls/linux/socket_ipv6_udp_unbound_external_networking.cc @@ -24,13 +24,11 @@ TEST_P(IPv6UDPUnboundExternalNetworkingSocketTest, TestJoinLeaveMulticast) { auto receiver = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); auto receiver_addr = V6Any(); - ASSERT_THAT( - bind(receiver->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr), - receiver_addr.addr_len), - SyscallSucceeds()); + ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - ASSERT_THAT(getsockname(receiver->get(), - reinterpret_cast<sockaddr*>(&receiver_addr.addr), + ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); @@ -50,8 +48,7 @@ TEST_P(IPv6UDPUnboundExternalNetworkingSocketTest, TestJoinLeaveMulticast) { // Set the sender to the loopback interface. auto sender_addr = V6Loopback(); ASSERT_THAT( - bind(sender->get(), reinterpret_cast<sockaddr*>(&sender_addr.addr), - sender_addr.addr_len), + bind(sender->get(), AsSockAddr(&sender_addr.addr), sender_addr.addr_len), SyscallSucceeds()); // Send a multicast packet. @@ -60,10 +57,10 @@ TEST_P(IPv6UDPUnboundExternalNetworkingSocketTest, TestJoinLeaveMulticast) { reinterpret_cast<sockaddr_in6*>(&receiver_addr.addr)->sin6_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); // Check that we received the multicast packet. char recv_buf[sizeof(send_buf)] = {}; @@ -77,10 +74,10 @@ TEST_P(IPv6UDPUnboundExternalNetworkingSocketTest, TestJoinLeaveMulticast) { &group_req, sizeof(group_req)), SyscallSucceeds()); RandomizeBuffer(send_buf, sizeof(send_buf)); - ASSERT_THAT(RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, - reinterpret_cast<sockaddr*>(&send_addr.addr), - send_addr.addr_len), - SyscallSucceedsWithValue(sizeof(send_buf))); + ASSERT_THAT( + RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, + AsSockAddr(&send_addr.addr), send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); ASSERT_THAT(RetryEINTR(recv)(receiver->get(), recv_buf, sizeof(recv_buf), MSG_DONTWAIT), SyscallFailsWithErrno(EAGAIN)); diff --git a/test/syscalls/linux/socket_ipv6_udp_unbound_netlink.cc b/test/syscalls/linux/socket_ipv6_udp_unbound_netlink.cc index 2ee218231..48aace78a 100644 --- a/test/syscalls/linux/socket_ipv6_udp_unbound_netlink.cc +++ b/test/syscalls/linux/socket_ipv6_udp_unbound_netlink.cc @@ -44,9 +44,9 @@ TEST_P(IPv6UDPUnboundSocketNetlinkTest, JoinSubnet) { reinterpret_cast<sockaddr_in6*>(&sender_addr.addr) ->sin6_addr.s6_addr)); auto sock = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); - EXPECT_THAT(bind(sock->get(), reinterpret_cast<sockaddr*>(&sender_addr.addr), - sender_addr.addr_len), - SyscallFailsWithErrno(EADDRNOTAVAIL)); + EXPECT_THAT( + bind(sock->get(), AsSockAddr(&sender_addr.addr), sender_addr.addr_len), + SyscallFailsWithErrno(EADDRNOTAVAIL)); } } // namespace testing diff --git a/test/syscalls/linux/socket_stream_blocking.cc b/test/syscalls/linux/socket_stream_blocking.cc index 538ee2268..0743322ac 100644 --- a/test/syscalls/linux/socket_stream_blocking.cc +++ b/test/syscalls/linux/socket_stream_blocking.cc @@ -68,7 +68,7 @@ TEST_P(BlockingStreamSocketPairTest, BlockPartialWriteClosed) { // Random save may interrupt the call to sendmsg() in SendLargeSendMsg(), // causing the write to be incomplete and the test to hang. -TEST_P(BlockingStreamSocketPairTest, SendMsgTooLarge_NoRandomSave) { +TEST_P(BlockingStreamSocketPairTest, SendMsgTooLarge) { auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); int sndbuf; @@ -102,7 +102,7 @@ TEST_P(BlockingStreamSocketPairTest, RecvLessThanBuffer) { // Test that MSG_WAITALL causes recv to block until all requested data is // received. Random save can interrupt blocking and cause received data to be // returned, even if the amount received is less than the full requested amount. -TEST_P(BlockingStreamSocketPairTest, RecvLessThanBufferWaitAll_NoRandomSave) { +TEST_P(BlockingStreamSocketPairTest, RecvLessThanBufferWaitAll) { auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); char sent_data[100]; diff --git a/test/syscalls/linux/socket_test_util.cc b/test/syscalls/linux/socket_test_util.cc index b2a96086c..9e3a129cf 100644 --- a/test/syscalls/linux/socket_test_util.cc +++ b/test/syscalls/linux/socket_test_util.cc @@ -82,8 +82,7 @@ Creator<SocketPair> AcceptBindSocketPairCreator(bool abstract, int domain, RETURN_ERROR_IF_SYSCALL_FAIL(bound = socket(domain, type, protocol)); MaybeSave(); // Successful socket creation. RETURN_ERROR_IF_SYSCALL_FAIL( - bind(bound, reinterpret_cast<struct sockaddr*>(&bind_addr), - sizeof(bind_addr))); + bind(bound, AsSockAddr(&bind_addr), sizeof(bind_addr))); MaybeSave(); // Successful bind. RETURN_ERROR_IF_SYSCALL_FAIL(listen(bound, /* backlog = */ 5)); MaybeSave(); // Successful listen. @@ -92,8 +91,7 @@ Creator<SocketPair> AcceptBindSocketPairCreator(bool abstract, int domain, RETURN_ERROR_IF_SYSCALL_FAIL(connected = socket(domain, type, protocol)); MaybeSave(); // Successful socket creation. RETURN_ERROR_IF_SYSCALL_FAIL( - connect(connected, reinterpret_cast<struct sockaddr*>(&bind_addr), - sizeof(bind_addr))); + connect(connected, AsSockAddr(&bind_addr), sizeof(bind_addr))); MaybeSave(); // Successful connect. int accepted; @@ -145,22 +143,22 @@ Creator<SocketPair> BidirectionalBindSocketPairCreator(bool abstract, RETURN_ERROR_IF_SYSCALL_FAIL(sock1 = socket(domain, type, protocol)); MaybeSave(); // Successful socket creation. RETURN_ERROR_IF_SYSCALL_FAIL( - bind(sock1, reinterpret_cast<struct sockaddr*>(&addr1), sizeof(addr1))); + bind(sock1, AsSockAddr(&addr1), sizeof(addr1))); MaybeSave(); // Successful bind. int sock2; RETURN_ERROR_IF_SYSCALL_FAIL(sock2 = socket(domain, type, protocol)); MaybeSave(); // Successful socket creation. RETURN_ERROR_IF_SYSCALL_FAIL( - bind(sock2, reinterpret_cast<struct sockaddr*>(&addr2), sizeof(addr2))); + bind(sock2, AsSockAddr(&addr2), sizeof(addr2))); MaybeSave(); // Successful bind. - RETURN_ERROR_IF_SYSCALL_FAIL(connect( - sock1, reinterpret_cast<struct sockaddr*>(&addr2), sizeof(addr2))); + RETURN_ERROR_IF_SYSCALL_FAIL( + connect(sock1, AsSockAddr(&addr2), sizeof(addr2))); MaybeSave(); // Successful connect. - RETURN_ERROR_IF_SYSCALL_FAIL(connect( - sock2, reinterpret_cast<struct sockaddr*>(&addr1), sizeof(addr1))); + RETURN_ERROR_IF_SYSCALL_FAIL( + connect(sock2, AsSockAddr(&addr1), sizeof(addr1))); MaybeSave(); // Successful connect. // Cleanup no longer needed resources. @@ -206,15 +204,15 @@ Creator<SocketPair> SocketpairGoferSocketPairCreator(int domain, int type, int sock1; RETURN_ERROR_IF_SYSCALL_FAIL(sock1 = socket(domain, type, protocol)); MaybeSave(); // Successful socket creation. - RETURN_ERROR_IF_SYSCALL_FAIL(connect( - sock1, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr))); + RETURN_ERROR_IF_SYSCALL_FAIL( + connect(sock1, AsSockAddr(&addr), sizeof(addr))); MaybeSave(); // Successful connect. int sock2; RETURN_ERROR_IF_SYSCALL_FAIL(sock2 = socket(domain, type, protocol)); MaybeSave(); // Successful socket creation. - RETURN_ERROR_IF_SYSCALL_FAIL(connect( - sock2, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr))); + RETURN_ERROR_IF_SYSCALL_FAIL( + connect(sock2, AsSockAddr(&addr), sizeof(addr))); MaybeSave(); // Successful connect. // Make and close another socketpair to ensure that the duped ends of the @@ -228,8 +226,8 @@ Creator<SocketPair> SocketpairGoferSocketPairCreator(int domain, int type, for (int i = 0; i < 2; i++) { int sock; RETURN_ERROR_IF_SYSCALL_FAIL(sock = socket(domain, type, protocol)); - RETURN_ERROR_IF_SYSCALL_FAIL(connect( - sock, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr))); + RETURN_ERROR_IF_SYSCALL_FAIL( + connect(sock, AsSockAddr(&addr), sizeof(addr))); RETURN_ERROR_IF_SYSCALL_FAIL(close(sock)); } @@ -308,11 +306,9 @@ template <typename T> PosixErrorOr<T> BindIP(int fd, bool dual_stack) { T addr = {}; LocalhostAddr(&addr, dual_stack); - RETURN_ERROR_IF_SYSCALL_FAIL( - bind(fd, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr))); + RETURN_ERROR_IF_SYSCALL_FAIL(bind(fd, AsSockAddr(&addr), sizeof(addr))); socklen_t addrlen = sizeof(addr); - RETURN_ERROR_IF_SYSCALL_FAIL( - getsockname(fd, reinterpret_cast<struct sockaddr*>(&addr), &addrlen)); + RETURN_ERROR_IF_SYSCALL_FAIL(getsockname(fd, AsSockAddr(&addr), &addrlen)); return addr; } @@ -329,9 +325,8 @@ CreateTCPConnectAcceptSocketPair(int bound, int connected, int type, bool dual_stack, T bind_addr) { int connect_result = 0; RETURN_ERROR_IF_SYSCALL_FAIL( - (connect_result = RetryEINTR(connect)( - connected, reinterpret_cast<struct sockaddr*>(&bind_addr), - sizeof(bind_addr))) == -1 && + (connect_result = RetryEINTR(connect)(connected, AsSockAddr(&bind_addr), + sizeof(bind_addr))) == -1 && errno == EINPROGRESS ? 0 : connect_result); @@ -703,7 +698,7 @@ PosixErrorOr<int> TryPortAvailable(int port, AddressFamily family, } RETURN_ERROR_IF_SYSCALL_FAIL( - bind(fd.get(), reinterpret_cast<sockaddr*>(&storage), storage_size)); + bind(fd.get(), AsSockAddr(&storage), storage_size)); // If the user specified 0 as the port, we will return the port that the // kernel gave us, otherwise we will validate that this socket bound to the @@ -711,8 +706,7 @@ PosixErrorOr<int> TryPortAvailable(int port, AddressFamily family, sockaddr_storage bound_storage = {}; socklen_t bound_storage_size = sizeof(bound_storage); RETURN_ERROR_IF_SYSCALL_FAIL( - getsockname(fd.get(), reinterpret_cast<sockaddr*>(&bound_storage), - &bound_storage_size)); + getsockname(fd.get(), AsSockAddr(&bound_storage), &bound_storage_size)); int available_port = -1; if (bound_storage.ss_family == AF_INET) { diff --git a/test/syscalls/linux/socket_test_util.h b/test/syscalls/linux/socket_test_util.h index b3ab286b8..f7ba90130 100644 --- a/test/syscalls/linux/socket_test_util.h +++ b/test/syscalls/linux/socket_test_util.h @@ -520,6 +520,20 @@ uint16_t UDPChecksum(struct iphdr iphdr, struct udphdr udphdr, uint16_t ICMPChecksum(struct icmphdr icmphdr, const char* payload, ssize_t payload_len); +// Convenient functions for reinterpreting common types to sockaddr pointer. +inline sockaddr* AsSockAddr(sockaddr_storage* s) { + return reinterpret_cast<sockaddr*>(s); +} +inline sockaddr* AsSockAddr(sockaddr_in* s) { + return reinterpret_cast<sockaddr*>(s); +} +inline sockaddr* AsSockAddr(sockaddr_in6* s) { + return reinterpret_cast<sockaddr*>(s); +} +inline sockaddr* AsSockAddr(sockaddr_un* s) { + return reinterpret_cast<sockaddr*>(s); +} + namespace internal { PosixErrorOr<int> TryPortAvailable(int port, AddressFamily family, SocketType type, bool reuse_addr); diff --git a/test/syscalls/linux/socket_unix_non_stream.cc b/test/syscalls/linux/socket_unix_non_stream.cc index 884319e1d..9425e87a6 100644 --- a/test/syscalls/linux/socket_unix_non_stream.cc +++ b/test/syscalls/linux/socket_unix_non_stream.cc @@ -239,7 +239,7 @@ TEST_P(UnixNonStreamSocketPairTest, SendTimeout) { SyscallSucceeds()); // The buffer size should be big enough to avoid many iterations in the next - // loop. Otherwise, this will slow down cooperative_save tests. + // loop. Otherwise, this will slow down save tests. std::vector<char> buf(kPageSize); for (;;) { int ret; diff --git a/test/syscalls/linux/splice.cc b/test/syscalls/linux/splice.cc index e5730a606..c85f6da0b 100644 --- a/test/syscalls/linux/splice.cc +++ b/test/syscalls/linux/splice.cc @@ -883,7 +883,7 @@ TEST(SpliceTest, FromPipeToDevZero) { static volatile int signaled = 0; void SigUsr1Handler(int sig, siginfo_t* info, void* context) { signaled = 1; } -TEST(SpliceTest, ToPipeWithSmallCapacityDoesNotSpin_NoRandomSave) { +TEST(SpliceTest, ToPipeWithSmallCapacityDoesNotSpin) { // Writes to a pipe that are less than PIPE_BUF must be atomic. This test // creates a pipe with only 128 bytes of capacity (< PIPE_BUF) and checks that // splicing to the pipe does not spin. See b/170743336. diff --git a/test/syscalls/linux/symlink.cc b/test/syscalls/linux/symlink.cc index ea219a091..9f6c59446 100644 --- a/test/syscalls/linux/symlink.cc +++ b/test/syscalls/linux/symlink.cc @@ -248,7 +248,7 @@ TEST(SymlinkTest, PwriteToSymlink) { EXPECT_THAT(unlink(linkname.c_str()), SyscallSucceeds()); } -TEST(SymlinkTest, SymlinkAtDegradedPermissions_NoRandomSave) { +TEST(SymlinkTest, SymlinkAtDegradedPermissions) { // Drop capabilities that allow us to override file and directory permissions. ASSERT_NO_ERRNO(SetCapability(CAP_DAC_OVERRIDE, false)); ASSERT_NO_ERRNO(SetCapability(CAP_DAC_READ_SEARCH, false)); @@ -299,7 +299,7 @@ TEST(SymlinkTest, ReadlinkAtDirWithOpath) { EXPECT_EQ(0, strncmp("/dangling", buf.data(), linksize)); } -TEST(SymlinkTest, ReadlinkAtDegradedPermissions_NoRandomSave) { +TEST(SymlinkTest, ReadlinkAtDegradedPermissions) { // Drop capabilities that allow us to override file and directory permissions. ASSERT_NO_ERRNO(SetCapability(CAP_DAC_OVERRIDE, false)); ASSERT_NO_ERRNO(SetCapability(CAP_DAC_READ_SEARCH, false)); diff --git a/test/syscalls/linux/tcp_socket.cc b/test/syscalls/linux/tcp_socket.cc index 7341cf1a6..011b60f0e 100644 --- a/test/syscalls/linux/tcp_socket.cc +++ b/test/syscalls/linux/tcp_socket.cc @@ -139,20 +139,16 @@ void TcpSocketTest::SetUp() { socklen_t addrlen = sizeof(addr); // Bind to some port then start listening. - ASSERT_THAT( - bind(listener_, reinterpret_cast<struct sockaddr*>(&addr), addrlen), - SyscallSucceeds()); + ASSERT_THAT(bind(listener_, AsSockAddr(&addr), addrlen), SyscallSucceeds()); ASSERT_THAT(listen(listener_, SOMAXCONN), SyscallSucceeds()); // Get the address we're listening on, then connect to it. We need to do this // because we're allowing the stack to pick a port for us. - ASSERT_THAT(getsockname(listener_, reinterpret_cast<struct sockaddr*>(&addr), - &addrlen), + ASSERT_THAT(getsockname(listener_, AsSockAddr(&addr), &addrlen), SyscallSucceeds()); - ASSERT_THAT(RetryEINTR(connect)( - first_fd, reinterpret_cast<struct sockaddr*>(&addr), addrlen), + ASSERT_THAT(RetryEINTR(connect)(first_fd, AsSockAddr(&addr), addrlen), SyscallSucceeds()); // Get the initial send buffer size. @@ -229,10 +225,9 @@ TEST_P(TcpSocketTest, SenderAddressIgnored) { socklen_t addrlen = sizeof(addr); memset(&addr, 0, sizeof(addr)); - ASSERT_THAT( - RetryEINTR(recvfrom)(second_fd, buf, sizeof(buf), 0, - reinterpret_cast<struct sockaddr*>(&addr), &addrlen), - SyscallSucceedsWithValue(3)); + ASSERT_THAT(RetryEINTR(recvfrom)(second_fd, buf, sizeof(buf), 0, + AsSockAddr(&addr), &addrlen), + SyscallSucceedsWithValue(3)); // Check that addr remains zeroed-out. const char* ptr = reinterpret_cast<char*>(&addr); @@ -250,10 +245,9 @@ TEST_P(TcpSocketTest, SenderAddressIgnoredOnPeek) { socklen_t addrlen = sizeof(addr); memset(&addr, 0, sizeof(addr)); - ASSERT_THAT( - RetryEINTR(recvfrom)(second_fd, buf, sizeof(buf), MSG_PEEK, - reinterpret_cast<struct sockaddr*>(&addr), &addrlen), - SyscallSucceedsWithValue(3)); + ASSERT_THAT(RetryEINTR(recvfrom)(second_fd, buf, sizeof(buf), MSG_PEEK, + AsSockAddr(&addr), &addrlen), + SyscallSucceedsWithValue(3)); // Check that addr remains zeroed-out. const char* ptr = reinterpret_cast<char*>(&addr); @@ -268,10 +262,9 @@ TEST_P(TcpSocketTest, SendtoAddressIgnored) { addr.ss_family = GetParam(); // FIXME(b/63803955) char data = '\0'; - EXPECT_THAT( - RetryEINTR(sendto)(first_fd, &data, sizeof(data), 0, - reinterpret_cast<sockaddr*>(&addr), sizeof(addr)), - SyscallSucceedsWithValue(1)); + EXPECT_THAT(RetryEINTR(sendto)(first_fd, &data, sizeof(data), 0, + AsSockAddr(&addr), sizeof(addr)), + SyscallSucceedsWithValue(1)); } TEST_P(TcpSocketTest, WritevZeroIovec) { @@ -331,7 +324,7 @@ TEST_P(TcpSocketTest, NonblockingLargeWrite) { // Test that a blocking write with a buffer that is larger than the send buffer // will block until the entire buffer is sent. -TEST_P(TcpSocketTest, BlockingLargeWrite_NoRandomSave) { +TEST_P(TcpSocketTest, BlockingLargeWrite) { // Allocate a buffer three times the size of the send buffer on the heap. We // do this as a vector to avoid allocating on the stack. int size = 3 * sendbuf_size_; @@ -415,7 +408,7 @@ TEST_P(TcpSocketTest, NonblockingLargeSend) { } // Same test as above, but calls send instead of write. -TEST_P(TcpSocketTest, BlockingLargeSend_NoRandomSave) { +TEST_P(TcpSocketTest, BlockingLargeSend) { // Allocate a buffer three times the size of the send buffer. We do this on // with a vector to avoid allocating on the stack. int size = 3 * sendbuf_size_; @@ -869,10 +862,9 @@ TEST_P(SimpleTcpSocketTest, SendtoWithAddressUnconnected) { sockaddr_storage addr = ASSERT_NO_ERRNO_AND_VALUE(InetLoopbackAddr(GetParam())); char data = '\0'; - EXPECT_THAT( - RetryEINTR(sendto)(fd, &data, sizeof(data), 0, - reinterpret_cast<sockaddr*>(&addr), sizeof(addr)), - SyscallFailsWithErrno(EPIPE)); + EXPECT_THAT(RetryEINTR(sendto)(fd, &data, sizeof(data), 0, AsSockAddr(&addr), + sizeof(addr)), + SyscallFailsWithErrno(EPIPE)); } TEST_P(SimpleTcpSocketTest, GetPeerNameUnconnected) { @@ -883,7 +875,7 @@ TEST_P(SimpleTcpSocketTest, GetPeerNameUnconnected) { sockaddr_storage addr; socklen_t addrlen = sizeof(addr); - EXPECT_THAT(getpeername(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen), + EXPECT_THAT(getpeername(fd, AsSockAddr(&addr), &addrlen), SyscallFailsWithErrno(ENOTCONN)); } @@ -974,24 +966,20 @@ TEST_P(SimpleTcpSocketTest, NonBlockingConnectRetry) { socklen_t addrlen = sizeof(addr); // Bind to some port but don't listen yet. - ASSERT_THAT( - bind(listener.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen), - SyscallSucceeds()); + ASSERT_THAT(bind(listener.get(), AsSockAddr(&addr), addrlen), + SyscallSucceeds()); // Get the address we're bound to, then connect to it. We need to do this // because we're allowing the stack to pick a port for us. - ASSERT_THAT(getsockname(listener.get(), - reinterpret_cast<struct sockaddr*>(&addr), &addrlen), + ASSERT_THAT(getsockname(listener.get(), AsSockAddr(&addr), &addrlen), SyscallSucceeds()); FileDescriptor connector = ASSERT_NO_ERRNO_AND_VALUE(Socket(GetParam(), SOCK_STREAM, IPPROTO_TCP)); // Verify that connect fails. - ASSERT_THAT( - RetryEINTR(connect)(connector.get(), - reinterpret_cast<struct sockaddr*>(&addr), addrlen), - SyscallFailsWithErrno(ECONNREFUSED)); + ASSERT_THAT(RetryEINTR(connect)(connector.get(), AsSockAddr(&addr), addrlen), + SyscallFailsWithErrno(ECONNREFUSED)); // Now start listening ASSERT_THAT(listen(listener.get(), SOMAXCONN), SyscallSucceeds()); @@ -1000,17 +988,14 @@ TEST_P(SimpleTcpSocketTest, NonBlockingConnectRetry) { // failed first connect should succeed. if (IsRunningOnGvisor()) { ASSERT_THAT( - RetryEINTR(connect)(connector.get(), - reinterpret_cast<struct sockaddr*>(&addr), addrlen), + RetryEINTR(connect)(connector.get(), AsSockAddr(&addr), addrlen), SyscallFailsWithErrno(ECONNABORTED)); return; } // Verify that connect now succeeds. - ASSERT_THAT( - RetryEINTR(connect)(connector.get(), - reinterpret_cast<struct sockaddr*>(&addr), addrlen), - SyscallSucceeds()); + ASSERT_THAT(RetryEINTR(connect)(connector.get(), AsSockAddr(&addr), addrlen), + SyscallSucceeds()); // Accept the connection. const FileDescriptor accepted = @@ -1030,13 +1015,11 @@ PosixErrorOr<FileDescriptor> nonBlockingConnectNoListener(const int family, int b_sock; RETURN_ERROR_IF_SYSCALL_FAIL(b_sock = socket(family, sock_type, IPPROTO_TCP)); FileDescriptor b(b_sock); - EXPECT_THAT(bind(b.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen), - SyscallSucceeds()); + EXPECT_THAT(bind(b.get(), AsSockAddr(&addr), addrlen), SyscallSucceeds()); // Get the address bound by the listening socket. - EXPECT_THAT( - getsockname(b.get(), reinterpret_cast<struct sockaddr*>(&addr), &addrlen), - SyscallSucceeds()); + EXPECT_THAT(getsockname(b.get(), AsSockAddr(&addr), &addrlen), + SyscallSucceeds()); // Now create another socket and issue a connect on this one. This connect // should fail as there is no listener. @@ -1046,8 +1029,7 @@ PosixErrorOr<FileDescriptor> nonBlockingConnectNoListener(const int family, // Now connect to the bound address and this should fail as nothing // is listening on the bound address. - EXPECT_THAT(RetryEINTR(connect)( - s.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen), + EXPECT_THAT(RetryEINTR(connect)(s.get(), AsSockAddr(&addr), addrlen), SyscallFailsWithErrno(EINPROGRESS)); // Wait for the connect to fail. @@ -1078,8 +1060,7 @@ TEST_P(SimpleTcpSocketTest, NonBlockingConnectNoListener) { opts &= ~O_NONBLOCK; EXPECT_THAT(fcntl(s.get(), F_SETFL, opts), SyscallSucceeds()); // Try connecting again. - ASSERT_THAT(RetryEINTR(connect)( - s.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen), + ASSERT_THAT(RetryEINTR(connect)(s.get(), AsSockAddr(&addr), addrlen), SyscallFailsWithErrno(ECONNABORTED)); } @@ -1094,8 +1075,7 @@ TEST_P(SimpleTcpSocketTest, NonBlockingConnectNoListenerRead) { unsigned char c; ASSERT_THAT(read(s.get(), &c, 1), SyscallFailsWithErrno(ECONNREFUSED)); ASSERT_THAT(read(s.get(), &c, 1), SyscallSucceedsWithValue(0)); - ASSERT_THAT(RetryEINTR(connect)( - s.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen), + ASSERT_THAT(RetryEINTR(connect)(s.get(), AsSockAddr(&addr), addrlen), SyscallFailsWithErrno(ECONNABORTED)); } @@ -1111,12 +1091,11 @@ TEST_P(SimpleTcpSocketTest, NonBlockingConnectNoListenerPeek) { ASSERT_THAT(recv(s.get(), &c, 1, MSG_PEEK), SyscallFailsWithErrno(ECONNREFUSED)); ASSERT_THAT(recv(s.get(), &c, 1, MSG_PEEK), SyscallSucceedsWithValue(0)); - ASSERT_THAT(RetryEINTR(connect)( - s.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen), + ASSERT_THAT(RetryEINTR(connect)(s.get(), AsSockAddr(&addr), addrlen), SyscallFailsWithErrno(ECONNABORTED)); } -TEST_P(SimpleTcpSocketTest, SelfConnectSendRecv_NoRandomSave) { +TEST_P(SimpleTcpSocketTest, SelfConnectSendRecv) { // Initialize address to the loopback one. sockaddr_storage addr = ASSERT_NO_ERRNO_AND_VALUE(InetLoopbackAddr(GetParam())); @@ -1125,15 +1104,11 @@ TEST_P(SimpleTcpSocketTest, SelfConnectSendRecv_NoRandomSave) { const FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(Socket(GetParam(), SOCK_STREAM, IPPROTO_TCP)); - ASSERT_THAT( - (bind)(s.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen), - SyscallSucceeds()); + ASSERT_THAT((bind)(s.get(), AsSockAddr(&addr), addrlen), SyscallSucceeds()); // Get the bound port. - ASSERT_THAT( - getsockname(s.get(), reinterpret_cast<struct sockaddr*>(&addr), &addrlen), - SyscallSucceeds()); - ASSERT_THAT(RetryEINTR(connect)( - s.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen), + ASSERT_THAT(getsockname(s.get(), AsSockAddr(&addr), &addrlen), + SyscallSucceeds()); + ASSERT_THAT(RetryEINTR(connect)(s.get(), AsSockAddr(&addr), addrlen), SyscallSucceeds()); constexpr int kBufSz = 1 << 20; // 1 MiB @@ -1168,7 +1143,7 @@ TEST_P(SimpleTcpSocketTest, SelfConnectSendRecv_NoRandomSave) { EXPECT_EQ(read_bytes, kBufSz); } -TEST_P(SimpleTcpSocketTest, SelfConnectSend_NoRandomSave) { +TEST_P(SimpleTcpSocketTest, SelfConnectSend) { // Initialize address to the loopback one. sockaddr_storage addr = ASSERT_NO_ERRNO_AND_VALUE(InetLoopbackAddr(GetParam())); @@ -1182,14 +1157,11 @@ TEST_P(SimpleTcpSocketTest, SelfConnectSend_NoRandomSave) { setsockopt(s.get(), SOL_TCP, TCP_MAXSEG, &max_seg, sizeof(max_seg)), SyscallSucceeds()); - ASSERT_THAT(bind(s.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen), - SyscallSucceeds()); + ASSERT_THAT(bind(s.get(), AsSockAddr(&addr), addrlen), SyscallSucceeds()); // Get the bound port. - ASSERT_THAT( - getsockname(s.get(), reinterpret_cast<struct sockaddr*>(&addr), &addrlen), - SyscallSucceeds()); - ASSERT_THAT(RetryEINTR(connect)( - s.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen), + ASSERT_THAT(getsockname(s.get(), AsSockAddr(&addr), &addrlen), + SyscallSucceeds()); + ASSERT_THAT(RetryEINTR(connect)(s.get(), AsSockAddr(&addr), addrlen), SyscallSucceeds()); std::vector<char> writebuf(512 << 10); // 512 KiB. @@ -1213,9 +1185,8 @@ void NonBlockingConnect(int family, int16_t pollMask) { socklen_t addrlen = sizeof(addr); // Bind to some port then start listening. - ASSERT_THAT( - bind(listener.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen), - SyscallSucceeds()); + ASSERT_THAT(bind(listener.get(), AsSockAddr(&addr), addrlen), + SyscallSucceeds()); ASSERT_THAT(listen(listener.get(), SOMAXCONN), SyscallSucceeds()); @@ -1228,12 +1199,10 @@ void NonBlockingConnect(int family, int16_t pollMask) { opts |= O_NONBLOCK; ASSERT_THAT(fcntl(s.get(), F_SETFL, opts), SyscallSucceeds()); - ASSERT_THAT(getsockname(listener.get(), - reinterpret_cast<struct sockaddr*>(&addr), &addrlen), + ASSERT_THAT(getsockname(listener.get(), AsSockAddr(&addr), &addrlen), SyscallSucceeds()); - ASSERT_THAT(RetryEINTR(connect)( - s.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen), + ASSERT_THAT(RetryEINTR(connect)(s.get(), AsSockAddr(&addr), addrlen), SyscallFailsWithErrno(EINPROGRESS)); int t; @@ -1276,21 +1245,18 @@ TEST_P(SimpleTcpSocketTest, NonBlockingConnectRemoteClose) { socklen_t addrlen = sizeof(addr); // Bind to some port then start listening. - ASSERT_THAT( - bind(listener.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen), - SyscallSucceeds()); + ASSERT_THAT(bind(listener.get(), AsSockAddr(&addr), addrlen), + SyscallSucceeds()); ASSERT_THAT(listen(listener.get(), SOMAXCONN), SyscallSucceeds()); FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE( Socket(GetParam(), SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP)); - ASSERT_THAT(getsockname(listener.get(), - reinterpret_cast<struct sockaddr*>(&addr), &addrlen), + ASSERT_THAT(getsockname(listener.get(), AsSockAddr(&addr), &addrlen), SyscallSucceeds()); - ASSERT_THAT(RetryEINTR(connect)( - s.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen), + ASSERT_THAT(RetryEINTR(connect)(s.get(), AsSockAddr(&addr), addrlen), SyscallFailsWithErrno(EINPROGRESS)); int t; @@ -1305,12 +1271,10 @@ TEST_P(SimpleTcpSocketTest, NonBlockingConnectRemoteClose) { EXPECT_THAT(RetryEINTR(poll)(&poll_fd, 1, 10000), SyscallSucceedsWithValue(1)); - ASSERT_THAT(RetryEINTR(connect)( - s.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen), + ASSERT_THAT(RetryEINTR(connect)(s.get(), AsSockAddr(&addr), addrlen), SyscallSucceeds()); - ASSERT_THAT(RetryEINTR(connect)( - s.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen), + ASSERT_THAT(RetryEINTR(connect)(s.get(), AsSockAddr(&addr), addrlen), SyscallFailsWithErrno(EISCONN)); } @@ -1325,8 +1289,7 @@ TEST_P(SimpleTcpSocketTest, BlockingConnectRefused) { ASSERT_NO_ERRNO_AND_VALUE(InetLoopbackAddr(GetParam())); socklen_t addrlen = sizeof(addr); - ASSERT_THAT(RetryEINTR(connect)( - s.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen), + ASSERT_THAT(RetryEINTR(connect)(s.get(), AsSockAddr(&addr), addrlen), SyscallFailsWithErrno(ECONNREFUSED)); // Avoiding triggering save in destructor of s. @@ -1346,17 +1309,14 @@ TEST_P(SimpleTcpSocketTest, CleanupOnConnectionRefused) { ASSERT_NO_ERRNO_AND_VALUE(InetLoopbackAddr(GetParam())); socklen_t bound_addrlen = sizeof(bound_addr); - ASSERT_THAT( - bind(bound_s.get(), reinterpret_cast<struct sockaddr*>(&bound_addr), - bound_addrlen), - SyscallSucceeds()); + ASSERT_THAT(bind(bound_s.get(), AsSockAddr(&bound_addr), bound_addrlen), + SyscallSucceeds()); // Get the addresses the socket is bound to because the port is chosen by the // stack. - ASSERT_THAT(getsockname(bound_s.get(), - reinterpret_cast<struct sockaddr*>(&bound_addr), - &bound_addrlen), - SyscallSucceeds()); + ASSERT_THAT( + getsockname(bound_s.get(), AsSockAddr(&bound_addr), &bound_addrlen), + SyscallSucceeds()); // Create, initialize, and bind the socket that is used to test connecting to // the non-listening port. @@ -1367,16 +1327,13 @@ TEST_P(SimpleTcpSocketTest, CleanupOnConnectionRefused) { ASSERT_NO_ERRNO_AND_VALUE(InetLoopbackAddr(GetParam())); socklen_t client_addrlen = sizeof(client_addr); + ASSERT_THAT(bind(client_s.get(), AsSockAddr(&client_addr), client_addrlen), + SyscallSucceeds()); + ASSERT_THAT( - bind(client_s.get(), reinterpret_cast<struct sockaddr*>(&client_addr), - client_addrlen), + getsockname(client_s.get(), AsSockAddr(&client_addr), &client_addrlen), SyscallSucceeds()); - ASSERT_THAT(getsockname(client_s.get(), - reinterpret_cast<struct sockaddr*>(&client_addr), - &client_addrlen), - SyscallSucceeds()); - // Now the test: connect to the bound but not listening socket with the // client socket. The bound socket should return a RST and cause the client // socket to return an error and clean itself up immediately. @@ -1392,10 +1349,8 @@ TEST_P(SimpleTcpSocketTest, CleanupOnConnectionRefused) { // Test binding to the address from the client socket. This should be okay // if it was dropped correctly. - ASSERT_THAT( - bind(new_s.get(), reinterpret_cast<struct sockaddr*>(&client_addr), - client_addrlen), - SyscallSucceeds()); + ASSERT_THAT(bind(new_s.get(), AsSockAddr(&client_addr), client_addrlen), + SyscallSucceeds()); // Attempt #2, with the new socket and reused addr our connect should fail in // the same way as before, not with an EADDRINUSE. @@ -1428,8 +1383,7 @@ TEST_P(SimpleTcpSocketTest, NonBlockingConnectRefused) { ASSERT_NO_ERRNO_AND_VALUE(InetLoopbackAddr(GetParam())); socklen_t addrlen = sizeof(addr); - ASSERT_THAT(RetryEINTR(connect)( - s.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen), + ASSERT_THAT(RetryEINTR(connect)(s.get(), AsSockAddr(&addr), addrlen), SyscallFailsWithErrno(EINPROGRESS)); // We don't need to specify any events to get POLLHUP or POLLERR as these @@ -1720,8 +1674,7 @@ TEST_P(SimpleTcpSocketTest, TCPConnectSoRcvBufRace) { ASSERT_NO_ERRNO_AND_VALUE(InetLoopbackAddr(GetParam())); socklen_t addrlen = sizeof(addr); - RetryEINTR(connect)(s.get(), reinterpret_cast<struct sockaddr*>(&addr), - addrlen); + RetryEINTR(connect)(s.get(), AsSockAddr(&addr), addrlen); int buf_sz = 1 << 18; EXPECT_THAT( setsockopt(s.get(), SOL_SOCKET, SO_RCVBUF, &buf_sz, sizeof(buf_sz)), @@ -2034,8 +1987,7 @@ TEST_P(SimpleTcpSocketTest, GetSocketAcceptConnWithShutdown) { socklen_t addrlen = sizeof(addr); // Bind to some port then start listening. - ASSERT_THAT(bind(s.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen), - SyscallSucceeds()); + ASSERT_THAT(bind(s.get(), AsSockAddr(&addr), addrlen), SyscallSucceeds()); ASSERT_THAT(listen(s.get(), SOMAXCONN), SyscallSucceeds()); @@ -2062,10 +2014,8 @@ TEST_P(SimpleTcpSocketTest, ConnectUnspecifiedAddress) { auto do_connect = [&addr, addrlen]() { FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE( Socket(addr.ss_family, SOCK_STREAM, IPPROTO_TCP)); - ASSERT_THAT( - RetryEINTR(connect)(s.get(), reinterpret_cast<struct sockaddr*>(&addr), - addrlen), - SyscallFailsWithErrno(ECONNREFUSED)); + ASSERT_THAT(RetryEINTR(connect)(s.get(), AsSockAddr(&addr), addrlen), + SyscallFailsWithErrno(ECONNREFUSED)); }; do_connect(); // Test the v4 mapped address as well. diff --git a/test/syscalls/linux/timerfd.cc b/test/syscalls/linux/timerfd.cc index c4f8fdd7a..072c92797 100644 --- a/test/syscalls/linux/timerfd.cc +++ b/test/syscalls/linux/timerfd.cc @@ -114,7 +114,7 @@ TEST_P(TimerfdTest, BlockingRead) { EXPECT_GE((end_time - start_time) + TimerSlack(), kDelay); } -TEST_P(TimerfdTest, NonblockingRead_NoRandomSave) { +TEST_P(TimerfdTest, NonblockingRead) { constexpr absl::Duration kDelay = absl::Seconds(5); auto const tfd = diff --git a/test/syscalls/linux/truncate.cc b/test/syscalls/linux/truncate.cc index 17832c47d..5db0b8276 100644 --- a/test/syscalls/linux/truncate.cc +++ b/test/syscalls/linux/truncate.cc @@ -208,7 +208,7 @@ TEST(TruncateTest, FtruncateWithOpath) { // ftruncate(2) should succeed as long as the file descriptor is writeable, // regardless of whether the file permissions allow writing. -TEST(TruncateTest, FtruncateWithoutWritePermission_NoRandomSave) { +TEST(TruncateTest, FtruncateWithoutWritePermission) { // Drop capabilities that allow us to override file permissions. ASSERT_NO_ERRNO(SetCapability(CAP_DAC_OVERRIDE, false)); @@ -230,7 +230,7 @@ TEST(TruncateTest, TruncateNonExist) { EXPECT_THAT(truncate("/foo/bar", 0), SyscallFailsWithErrno(ENOENT)); } -TEST(TruncateTest, FtruncateVirtualTmp_NoRandomSave) { +TEST(TruncateTest, FtruncateVirtualTmp) { auto temp_file = NewTempAbsPathInDir("/dev/shm"); const DisableSave ds; // Incompatible permissions. const FileDescriptor fd = diff --git a/test/syscalls/linux/tuntap.cc b/test/syscalls/linux/tuntap.cc index 13ed0d68a..6e3a00d2c 100644 --- a/test/syscalls/linux/tuntap.cc +++ b/test/syscalls/linux/tuntap.cc @@ -349,9 +349,8 @@ TEST_F(TuntapTest, PingKernel) { }; while (1) { inpkt r = {}; - int nread = read(fd.get(), &r, sizeof(r)); - EXPECT_THAT(nread, SyscallSucceeds()); - long unsigned int n = static_cast<long unsigned int>(nread); + size_t n; + EXPECT_THAT(n = read(fd.get(), &r, sizeof(r)), SyscallSucceeds()); if (n < sizeof(pihdr)) { std::cerr << "Ignored packet, protocol: " << r.pi.pi_protocol @@ -397,8 +396,7 @@ TEST_F(TuntapTest, SendUdpTriggersArpResolution) { .sin_port = htons(42), .sin_addr = {.s_addr = kTapPeerIPAddr}, }; - ASSERT_THAT(sendto(sock, "hello", 5, 0, reinterpret_cast<sockaddr*>(&remote), - sizeof(remote)), + ASSERT_THAT(sendto(sock, "hello", 5, 0, AsSockAddr(&remote), sizeof(remote)), SyscallSucceeds()); struct inpkt { @@ -409,9 +407,8 @@ TEST_F(TuntapTest, SendUdpTriggersArpResolution) { }; while (1) { inpkt r = {}; - int nread = read(fd.get(), &r, sizeof(r)); - EXPECT_THAT(nread, SyscallSucceeds()); - long unsigned int n = static_cast<long unsigned int>(nread); + size_t n; + EXPECT_THAT(n = read(fd.get(), &r, sizeof(r)), SyscallSucceeds()); if (n < sizeof(pihdr)) { std::cerr << "Ignored packet, protocol: " << r.pi.pi_protocol @@ -498,7 +495,7 @@ TEST_F(TuntapTest, WriteHangBug155928773) { .sin_addr = {.s_addr = kTapIPAddr}, }; // Return values do not matter in this test. - connect(sock, reinterpret_cast<struct sockaddr*>(&remote), sizeof(remote)); + connect(sock, AsSockAddr(&remote), sizeof(remote)); write(sock, "hello", 5); } diff --git a/test/syscalls/linux/udp_bind.cc b/test/syscalls/linux/udp_bind.cc index 6d92bdbeb..f68d78aa2 100644 --- a/test/syscalls/linux/udp_bind.cc +++ b/test/syscalls/linux/udp_bind.cc @@ -83,27 +83,24 @@ TEST_P(SendtoTest, Sendto) { ASSERT_NO_ERRNO_AND_VALUE(Socket(param.recv_domain, SOCK_DGRAM, 0)); if (param.send_addr_len > 0) { - ASSERT_THAT(bind(s1.get(), reinterpret_cast<sockaddr*>(¶m.send_addr), - param.send_addr_len), - SyscallSucceeds()); + ASSERT_THAT( + bind(s1.get(), AsSockAddr(¶m.send_addr), param.send_addr_len), + SyscallSucceeds()); } if (param.connect_addr_len > 0) { - ASSERT_THAT( - connect(s1.get(), reinterpret_cast<sockaddr*>(¶m.connect_addr), - param.connect_addr_len), - SyscallSucceeds()); + ASSERT_THAT(connect(s1.get(), AsSockAddr(¶m.connect_addr), + param.connect_addr_len), + SyscallSucceeds()); } - ASSERT_THAT(bind(s2.get(), reinterpret_cast<sockaddr*>(¶m.recv_addr), - param.recv_addr_len), + ASSERT_THAT(bind(s2.get(), AsSockAddr(¶m.recv_addr), param.recv_addr_len), SyscallSucceeds()); struct sockaddr_storage real_recv_addr = {}; socklen_t real_recv_addr_len = param.recv_addr_len; ASSERT_THAT( - getsockname(s2.get(), reinterpret_cast<sockaddr*>(&real_recv_addr), - &real_recv_addr_len), + getsockname(s2.get(), AsSockAddr(&real_recv_addr), &real_recv_addr_len), SyscallSucceeds()); ASSERT_EQ(real_recv_addr_len, param.recv_addr_len); @@ -116,23 +113,22 @@ TEST_P(SendtoTest, Sendto) { char buf[20] = {}; if (!param.sendto_errnos.empty()) { - ASSERT_THAT(RetryEINTR(sendto)(s1.get(), buf, sizeof(buf), 0, - reinterpret_cast<sockaddr*>(&sendto_addr), - param.sendto_addr_len), - SyscallFailsWithErrno(ElementOf(param.sendto_errnos))); + ASSERT_THAT( + RetryEINTR(sendto)(s1.get(), buf, sizeof(buf), 0, + AsSockAddr(&sendto_addr), param.sendto_addr_len), + SyscallFailsWithErrno(ElementOf(param.sendto_errnos))); return; } - ASSERT_THAT(RetryEINTR(sendto)(s1.get(), buf, sizeof(buf), 0, - reinterpret_cast<sockaddr*>(&sendto_addr), - param.sendto_addr_len), - SyscallSucceedsWithValue(sizeof(buf))); + ASSERT_THAT( + RetryEINTR(sendto)(s1.get(), buf, sizeof(buf), 0, + AsSockAddr(&sendto_addr), param.sendto_addr_len), + SyscallSucceedsWithValue(sizeof(buf))); struct sockaddr_storage got_addr = {}; socklen_t got_addr_len = sizeof(sockaddr_storage); ASSERT_THAT(RetryEINTR(recvfrom)(s2.get(), buf, sizeof(buf), 0, - reinterpret_cast<sockaddr*>(&got_addr), - &got_addr_len), + AsSockAddr(&got_addr), &got_addr_len), SyscallSucceedsWithValue(sizeof(buf))); ASSERT_GT(got_addr_len, sizeof(sockaddr_in_common)); @@ -140,8 +136,7 @@ TEST_P(SendtoTest, Sendto) { struct sockaddr_storage sender_addr = {}; socklen_t sender_addr_len = sizeof(sockaddr_storage); - ASSERT_THAT(getsockname(s1.get(), reinterpret_cast<sockaddr*>(&sender_addr), - &sender_addr_len), + ASSERT_THAT(getsockname(s1.get(), AsSockAddr(&sender_addr), &sender_addr_len), SyscallSucceeds()); ASSERT_GT(sender_addr_len, sizeof(sockaddr_in_common)); diff --git a/test/syscalls/linux/udp_socket.cc b/test/syscalls/linux/udp_socket.cc index 16eeeb5c6..18f566eec 100644 --- a/test/syscalls/linux/udp_socket.cc +++ b/test/syscalls/linux/udp_socket.cc @@ -138,7 +138,7 @@ void UdpSocketTest::SetUp() { bind_ = ASSERT_NO_ERRNO_AND_VALUE(Socket(GetFamily(), SOCK_DGRAM, IPPROTO_UDP)); memset(&bind_addr_storage_, 0, sizeof(bind_addr_storage_)); - bind_addr_ = reinterpret_cast<struct sockaddr*>(&bind_addr_storage_); + bind_addr_ = AsSockAddr(&bind_addr_storage_); sock_ = ASSERT_NO_ERRNO_AND_VALUE(Socket(GetFamily(), SOCK_DGRAM, IPPROTO_UDP)); @@ -153,15 +153,13 @@ int UdpSocketTest::GetFamily() { PosixError UdpSocketTest::BindLoopback() { bind_addr_storage_ = InetLoopbackAddr(); - struct sockaddr* bind_addr_ = - reinterpret_cast<struct sockaddr*>(&bind_addr_storage_); + struct sockaddr* bind_addr_ = AsSockAddr(&bind_addr_storage_); return BindSocket(bind_.get(), bind_addr_); } PosixError UdpSocketTest::BindAny() { bind_addr_storage_ = InetAnyAddr(); - struct sockaddr* bind_addr_ = - reinterpret_cast<struct sockaddr*>(&bind_addr_storage_); + struct sockaddr* bind_addr_ = AsSockAddr(&bind_addr_storage_); return BindSocket(bind_.get(), bind_addr_); } @@ -195,7 +193,7 @@ socklen_t UdpSocketTest::GetAddrLength() { sockaddr_storage UdpSocketTest::InetAnyAddr() { struct sockaddr_storage addr; memset(&addr, 0, sizeof(addr)); - reinterpret_cast<struct sockaddr*>(&addr)->sa_family = GetFamily(); + AsSockAddr(&addr)->sa_family = GetFamily(); if (GetFamily() == AF_INET) { auto sin = reinterpret_cast<struct sockaddr_in*>(&addr); @@ -213,7 +211,7 @@ sockaddr_storage UdpSocketTest::InetAnyAddr() { sockaddr_storage UdpSocketTest::InetLoopbackAddr() { struct sockaddr_storage addr; memset(&addr, 0, sizeof(addr)); - reinterpret_cast<struct sockaddr*>(&addr)->sa_family = GetFamily(); + AsSockAddr(&addr)->sa_family = GetFamily(); if (GetFamily() == AF_INET) { auto sin = reinterpret_cast<struct sockaddr_in*>(&addr); @@ -229,7 +227,7 @@ sockaddr_storage UdpSocketTest::InetLoopbackAddr() { void UdpSocketTest::Disconnect(int sockfd) { sockaddr_storage addr_storage = InetAnyAddr(); - sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); + sockaddr* addr = AsSockAddr(&addr_storage); socklen_t addrlen = sizeof(addr_storage); addr->sa_family = AF_UNSPEC; @@ -265,19 +263,16 @@ TEST_P(UdpSocketTest, Getsockname) { // Check that we're not bound. struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); - EXPECT_THAT( - getsockname(bind_.get(), reinterpret_cast<sockaddr*>(&addr), &addrlen), - SyscallSucceeds()); + EXPECT_THAT(getsockname(bind_.get(), AsSockAddr(&addr), &addrlen), + SyscallSucceeds()); EXPECT_EQ(addrlen, addrlen_); struct sockaddr_storage any = InetAnyAddr(); - EXPECT_EQ(memcmp(&addr, reinterpret_cast<struct sockaddr*>(&any), addrlen_), - 0); + EXPECT_EQ(memcmp(&addr, AsSockAddr(&any), addrlen_), 0); ASSERT_NO_ERRNO(BindLoopback()); - EXPECT_THAT( - getsockname(bind_.get(), reinterpret_cast<sockaddr*>(&addr), &addrlen), - SyscallSucceeds()); + EXPECT_THAT(getsockname(bind_.get(), AsSockAddr(&addr), &addrlen), + SyscallSucceeds()); EXPECT_EQ(addrlen, addrlen_); EXPECT_EQ(memcmp(&addr, bind_addr_, addrlen_), 0); @@ -289,17 +284,15 @@ TEST_P(UdpSocketTest, Getpeername) { // Check that we're not connected. struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); - EXPECT_THAT( - getpeername(sock_.get(), reinterpret_cast<sockaddr*>(&addr), &addrlen), - SyscallFailsWithErrno(ENOTCONN)); + EXPECT_THAT(getpeername(sock_.get(), AsSockAddr(&addr), &addrlen), + SyscallFailsWithErrno(ENOTCONN)); // Connect, then check that we get the right address. ASSERT_THAT(connect(sock_.get(), bind_addr_, addrlen_), SyscallSucceeds()); addrlen = sizeof(addr); - EXPECT_THAT( - getpeername(sock_.get(), reinterpret_cast<sockaddr*>(&addr), &addrlen), - SyscallSucceeds()); + EXPECT_THAT(getpeername(sock_.get(), AsSockAddr(&addr), &addrlen), + SyscallSucceeds()); EXPECT_EQ(addrlen, addrlen_); EXPECT_EQ(memcmp(&addr, bind_addr_, addrlen_), 0); } @@ -322,9 +315,8 @@ TEST_P(UdpSocketTest, SendNotConnected) { // Check that we're bound now. struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); - EXPECT_THAT( - getsockname(sock_.get(), reinterpret_cast<sockaddr*>(&addr), &addrlen), - SyscallSucceeds()); + EXPECT_THAT(getsockname(sock_.get(), AsSockAddr(&addr), &addrlen), + SyscallSucceeds()); EXPECT_EQ(addrlen, addrlen_); EXPECT_NE(*Port(&addr), 0); } @@ -338,9 +330,8 @@ TEST_P(UdpSocketTest, ConnectBinds) { // Check that we're bound now. struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); - EXPECT_THAT( - getsockname(sock_.get(), reinterpret_cast<sockaddr*>(&addr), &addrlen), - SyscallSucceeds()); + EXPECT_THAT(getsockname(sock_.get(), AsSockAddr(&addr), &addrlen), + SyscallSucceeds()); EXPECT_EQ(addrlen, addrlen_); EXPECT_NE(*Port(&addr), 0); } @@ -361,9 +352,8 @@ TEST_P(UdpSocketTest, Bind) { // Check that we're still bound to the original address. struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); - EXPECT_THAT( - getsockname(bind_.get(), reinterpret_cast<sockaddr*>(&addr), &addrlen), - SyscallSucceeds()); + EXPECT_THAT(getsockname(bind_.get(), AsSockAddr(&addr), &addrlen), + SyscallSucceeds()); EXPECT_EQ(addrlen, addrlen_); EXPECT_EQ(memcmp(&addr, bind_addr_, addrlen_), 0); } @@ -383,7 +373,7 @@ TEST_P(UdpSocketTest, ConnectWriteToInvalidPort) { // same time. struct sockaddr_storage addr_storage = InetLoopbackAddr(); socklen_t addrlen = sizeof(addr_storage); - struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); + struct sockaddr* addr = AsSockAddr(&addr_storage); FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(Socket(GetFamily(), SOCK_DGRAM, IPPROTO_UDP)); ASSERT_THAT(bind(s.get(), addr, addrlen), SyscallSucceeds()); @@ -417,7 +407,7 @@ TEST_P(UdpSocketTest, ConnectSimultaneousWriteToInvalidPort) { // same time. struct sockaddr_storage addr_storage = InetLoopbackAddr(); socklen_t addrlen = sizeof(addr_storage); - struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); + struct sockaddr* addr = AsSockAddr(&addr_storage); FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(Socket(GetFamily(), SOCK_DGRAM, IPPROTO_UDP)); ASSERT_THAT(bind(s.get(), addr, addrlen), SyscallSucceeds()); @@ -465,18 +455,17 @@ TEST_P(UdpSocketTest, ReceiveAfterDisconnect) { struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); - EXPECT_THAT( - getsockname(sock_.get(), reinterpret_cast<sockaddr*>(&addr), &addrlen), - SyscallSucceeds()); + EXPECT_THAT(getsockname(sock_.get(), AsSockAddr(&addr), &addrlen), + SyscallSucceeds()); EXPECT_EQ(addrlen, addrlen_); // Send from sock to bind_. char buf[512]; RandomizeBuffer(buf, sizeof(buf)); - ASSERT_THAT(sendto(bind_.get(), buf, sizeof(buf), 0, - reinterpret_cast<sockaddr*>(&addr), addrlen), - SyscallSucceedsWithValue(sizeof(buf))); + ASSERT_THAT( + sendto(bind_.get(), buf, sizeof(buf), 0, AsSockAddr(&addr), addrlen), + SyscallSucceedsWithValue(sizeof(buf))); // Receive the data. char received[sizeof(buf)]; @@ -499,21 +488,18 @@ TEST_P(UdpSocketTest, Connect) { // Check that we're connected to the right peer. struct sockaddr_storage peer; socklen_t peerlen = sizeof(peer); - EXPECT_THAT( - getpeername(sock_.get(), reinterpret_cast<sockaddr*>(&peer), &peerlen), - SyscallSucceeds()); + EXPECT_THAT(getpeername(sock_.get(), AsSockAddr(&peer), &peerlen), + SyscallSucceeds()); EXPECT_EQ(peerlen, addrlen_); EXPECT_EQ(memcmp(&peer, bind_addr_, addrlen_), 0); // Try to bind after connect. struct sockaddr_storage any = InetAnyAddr(); - EXPECT_THAT( - bind(sock_.get(), reinterpret_cast<struct sockaddr*>(&any), addrlen_), - SyscallFailsWithErrno(EINVAL)); + EXPECT_THAT(bind(sock_.get(), AsSockAddr(&any), addrlen_), + SyscallFailsWithErrno(EINVAL)); struct sockaddr_storage bind2_storage = InetLoopbackAddr(); - struct sockaddr* bind2_addr = - reinterpret_cast<struct sockaddr*>(&bind2_storage); + struct sockaddr* bind2_addr = AsSockAddr(&bind2_storage); FileDescriptor bind2 = ASSERT_NO_ERRNO_AND_VALUE(Socket(GetFamily(), SOCK_DGRAM, IPPROTO_UDP)); ASSERT_NO_ERRNO(BindSocket(bind2.get(), bind2_addr)); @@ -523,9 +509,8 @@ TEST_P(UdpSocketTest, Connect) { // Check that peer name changed. peerlen = sizeof(peer); - EXPECT_THAT( - getpeername(sock_.get(), reinterpret_cast<sockaddr*>(&peer), &peerlen), - SyscallSucceeds()); + EXPECT_THAT(getpeername(sock_.get(), AsSockAddr(&peer), &peerlen), + SyscallSucceeds()); EXPECT_EQ(peerlen, addrlen_); EXPECT_EQ(memcmp(&peer, bind2_addr, addrlen_), 0); } @@ -535,15 +520,13 @@ TEST_P(UdpSocketTest, ConnectAnyZero) { SKIP_IF(IsRunningOnGvisor()); struct sockaddr_storage any = InetAnyAddr(); - EXPECT_THAT( - connect(sock_.get(), reinterpret_cast<struct sockaddr*>(&any), addrlen_), - SyscallSucceeds()); + EXPECT_THAT(connect(sock_.get(), AsSockAddr(&any), addrlen_), + SyscallSucceeds()); struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); - EXPECT_THAT( - getpeername(sock_.get(), reinterpret_cast<sockaddr*>(&addr), &addrlen), - SyscallFailsWithErrno(ENOTCONN)); + EXPECT_THAT(getpeername(sock_.get(), AsSockAddr(&addr), &addrlen), + SyscallFailsWithErrno(ENOTCONN)); } TEST_P(UdpSocketTest, ConnectAnyWithPort) { @@ -552,24 +535,21 @@ TEST_P(UdpSocketTest, ConnectAnyWithPort) { struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); - EXPECT_THAT( - getpeername(sock_.get(), reinterpret_cast<sockaddr*>(&addr), &addrlen), - SyscallSucceeds()); + EXPECT_THAT(getpeername(sock_.get(), AsSockAddr(&addr), &addrlen), + SyscallSucceeds()); } TEST_P(UdpSocketTest, DisconnectAfterConnectAny) { // TODO(138658473): Enable when we can connect to port 0 with gVisor. SKIP_IF(IsRunningOnGvisor()); struct sockaddr_storage any = InetAnyAddr(); - EXPECT_THAT( - connect(sock_.get(), reinterpret_cast<struct sockaddr*>(&any), addrlen_), - SyscallSucceeds()); + EXPECT_THAT(connect(sock_.get(), AsSockAddr(&any), addrlen_), + SyscallSucceeds()); struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); - EXPECT_THAT( - getpeername(sock_.get(), reinterpret_cast<sockaddr*>(&addr), &addrlen), - SyscallFailsWithErrno(ENOTCONN)); + EXPECT_THAT(getpeername(sock_.get(), AsSockAddr(&addr), &addrlen), + SyscallFailsWithErrno(ENOTCONN)); Disconnect(sock_.get()); } @@ -580,9 +560,8 @@ TEST_P(UdpSocketTest, DisconnectAfterConnectAnyWithPort) { struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); - EXPECT_THAT( - getpeername(sock_.get(), reinterpret_cast<sockaddr*>(&addr), &addrlen), - SyscallSucceeds()); + EXPECT_THAT(getpeername(sock_.get(), AsSockAddr(&addr), &addrlen), + SyscallSucceeds()); EXPECT_EQ(addrlen, addrlen_); EXPECT_EQ(*Port(&bind_addr_storage_), *Port(&addr)); @@ -595,7 +574,7 @@ TEST_P(UdpSocketTest, DisconnectAfterBind) { // Bind to the next port above bind_. struct sockaddr_storage addr_storage = InetLoopbackAddr(); - struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); + struct sockaddr* addr = AsSockAddr(&addr_storage); SetPort(&addr_storage, *Port(&bind_addr_storage_) + 1); ASSERT_NO_ERRNO(BindSocket(sock_.get(), addr)); @@ -604,15 +583,14 @@ TEST_P(UdpSocketTest, DisconnectAfterBind) { struct sockaddr_storage unspec = {}; unspec.ss_family = AF_UNSPEC; - EXPECT_THAT(connect(sock_.get(), reinterpret_cast<sockaddr*>(&unspec), - sizeof(unspec.ss_family)), - SyscallSucceeds()); + EXPECT_THAT( + connect(sock_.get(), AsSockAddr(&unspec), sizeof(unspec.ss_family)), + SyscallSucceeds()); // Check that we're still bound. socklen_t addrlen = sizeof(unspec); - EXPECT_THAT( - getsockname(sock_.get(), reinterpret_cast<sockaddr*>(&unspec), &addrlen), - SyscallSucceeds()); + EXPECT_THAT(getsockname(sock_.get(), AsSockAddr(&unspec), &addrlen), + SyscallSucceeds()); EXPECT_EQ(addrlen, addrlen_); EXPECT_EQ(memcmp(addr, &unspec, addrlen_), 0); @@ -626,7 +604,7 @@ TEST_P(UdpSocketTest, BindToAnyConnnectToLocalhost) { ASSERT_NO_ERRNO(BindAny()); struct sockaddr_storage addr_storage = InetLoopbackAddr(); - struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); + struct sockaddr* addr = AsSockAddr(&addr_storage); SetPort(&addr_storage, *Port(&bind_addr_storage_) + 1); socklen_t addrlen = sizeof(addr); @@ -653,7 +631,7 @@ TEST_P(UdpSocketTest, DisconnectAfterBindToAny) { ASSERT_NO_ERRNO(BindLoopback()); struct sockaddr_storage any_storage = InetAnyAddr(); - struct sockaddr* any = reinterpret_cast<struct sockaddr*>(&any_storage); + struct sockaddr* any = AsSockAddr(&any_storage); SetPort(&any_storage, *Port(&bind_addr_storage_) + 1); ASSERT_NO_ERRNO(BindSocket(sock_.get(), any)); @@ -666,24 +644,22 @@ TEST_P(UdpSocketTest, DisconnectAfterBindToAny) { // Check that we're still bound. struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); - EXPECT_THAT( - getsockname(sock_.get(), reinterpret_cast<sockaddr*>(&addr), &addrlen), - SyscallSucceeds()); + EXPECT_THAT(getsockname(sock_.get(), AsSockAddr(&addr), &addrlen), + SyscallSucceeds()); EXPECT_EQ(addrlen, addrlen_); EXPECT_EQ(memcmp(&addr, any, addrlen), 0); addrlen = sizeof(addr); - EXPECT_THAT( - getpeername(sock_.get(), reinterpret_cast<sockaddr*>(&addr), &addrlen), - SyscallFailsWithErrno(ENOTCONN)); + EXPECT_THAT(getpeername(sock_.get(), AsSockAddr(&addr), &addrlen), + SyscallFailsWithErrno(ENOTCONN)); } TEST_P(UdpSocketTest, Disconnect) { ASSERT_NO_ERRNO(BindLoopback()); struct sockaddr_storage any_storage = InetAnyAddr(); - struct sockaddr* any = reinterpret_cast<struct sockaddr*>(&any_storage); + struct sockaddr* any = AsSockAddr(&any_storage); SetPort(&any_storage, *Port(&bind_addr_storage_) + 1); ASSERT_NO_ERRNO(BindSocket(sock_.get(), any)); @@ -694,29 +670,25 @@ TEST_P(UdpSocketTest, Disconnect) { // Check that we're connected to the right peer. struct sockaddr_storage peer; socklen_t peerlen = sizeof(peer); - EXPECT_THAT( - getpeername(sock_.get(), reinterpret_cast<sockaddr*>(&peer), &peerlen), - SyscallSucceeds()); + EXPECT_THAT(getpeername(sock_.get(), AsSockAddr(&peer), &peerlen), + SyscallSucceeds()); EXPECT_EQ(peerlen, addrlen_); EXPECT_EQ(memcmp(&peer, bind_addr_, addrlen_), 0); // Try to disconnect. struct sockaddr_storage addr = {}; addr.ss_family = AF_UNSPEC; - EXPECT_THAT(connect(sock_.get(), reinterpret_cast<sockaddr*>(&addr), - sizeof(addr.ss_family)), + EXPECT_THAT(connect(sock_.get(), AsSockAddr(&addr), sizeof(addr.ss_family)), SyscallSucceeds()); peerlen = sizeof(peer); - EXPECT_THAT( - getpeername(sock_.get(), reinterpret_cast<sockaddr*>(&peer), &peerlen), - SyscallFailsWithErrno(ENOTCONN)); + EXPECT_THAT(getpeername(sock_.get(), AsSockAddr(&peer), &peerlen), + SyscallFailsWithErrno(ENOTCONN)); // Check that we're still bound. socklen_t addrlen = sizeof(addr); - EXPECT_THAT( - getsockname(sock_.get(), reinterpret_cast<sockaddr*>(&addr), &addrlen), - SyscallSucceeds()); + EXPECT_THAT(getsockname(sock_.get(), AsSockAddr(&addr), &addrlen), + SyscallSucceeds()); EXPECT_EQ(addrlen, addrlen_); EXPECT_EQ(*Port(&addr), *Port(&any_storage)); } @@ -733,7 +705,7 @@ TEST_P(UdpSocketTest, SendToAddressOtherThanConnected) { ASSERT_NO_ERRNO(BindLoopback()); struct sockaddr_storage addr_storage = InetAnyAddr(); - struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); + struct sockaddr* addr = AsSockAddr(&addr_storage); SetPort(&addr_storage, *Port(&bind_addr_storage_) + 1); ASSERT_THAT(connect(sock_.get(), bind_addr_, addrlen_), SyscallSucceeds()); @@ -881,7 +853,7 @@ TEST_P(UdpSocketTest, ZerolengthWriteAllowed) { ASSERT_NO_ERRNO(BindLoopback()); // Connect to loopback:bind_addr_+1. struct sockaddr_storage addr_storage = InetLoopbackAddr(); - struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); + struct sockaddr* addr = AsSockAddr(&addr_storage); SetPort(&addr_storage, *Port(&bind_addr_storage_) + 1); ASSERT_THAT(connect(bind_.get(), addr, addrlen_), SyscallSucceeds()); @@ -910,7 +882,7 @@ TEST_P(UdpSocketTest, ZerolengthWriteAllowedNonBlockRead) { // Connect to loopback:bind_addr_port+1. struct sockaddr_storage addr_storage = InetLoopbackAddr(); - struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); + struct sockaddr* addr = AsSockAddr(&addr_storage); SetPort(&addr_storage, *Port(&bind_addr_storage_) + 1); ASSERT_THAT(connect(bind_.get(), addr, addrlen_), SyscallSucceeds()); @@ -961,7 +933,7 @@ TEST_P(UdpSocketTest, SendAndReceiveConnected) { // Connect to loopback:bind_addr_port+1. struct sockaddr_storage addr_storage = InetLoopbackAddr(); - struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); + struct sockaddr* addr = AsSockAddr(&addr_storage); SetPort(&addr_storage, *Port(&bind_addr_storage_) + 1); ASSERT_THAT(connect(bind_.get(), addr, addrlen_), SyscallSucceeds()); @@ -987,13 +959,13 @@ TEST_P(UdpSocketTest, ReceiveFromNotConnected) { // Connect to loopback:bind_addr_port+1. struct sockaddr_storage addr_storage = InetLoopbackAddr(); - struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); + struct sockaddr* addr = AsSockAddr(&addr_storage); SetPort(&addr_storage, *Port(&bind_addr_storage_) + 1); ASSERT_THAT(connect(bind_.get(), addr, addrlen_), SyscallSucceeds()); // Bind sock to loopback:bind_addr_port+2. struct sockaddr_storage addr2_storage = InetLoopbackAddr(); - struct sockaddr* addr2 = reinterpret_cast<struct sockaddr*>(&addr2_storage); + struct sockaddr* addr2 = AsSockAddr(&addr2_storage); SetPort(&addr2_storage, *Port(&bind_addr_storage_) + 2); ASSERT_THAT(bind(sock_.get(), addr2, addrlen_), SyscallSucceeds()); @@ -1013,7 +985,7 @@ TEST_P(UdpSocketTest, ReceiveBeforeConnect) { // Bind sock to loopback:bind_addr_port+2. struct sockaddr_storage addr2_storage = InetLoopbackAddr(); - struct sockaddr* addr2 = reinterpret_cast<struct sockaddr*>(&addr2_storage); + struct sockaddr* addr2 = AsSockAddr(&addr2_storage); SetPort(&addr2_storage, *Port(&bind_addr_storage_) + 2); ASSERT_THAT(bind(sock_.get(), addr2, addrlen_), SyscallSucceeds()); @@ -1026,7 +998,7 @@ TEST_P(UdpSocketTest, ReceiveBeforeConnect) { // Connect to loopback:bind_addr_port+1. struct sockaddr_storage addr_storage = InetLoopbackAddr(); - struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); + struct sockaddr* addr = AsSockAddr(&addr_storage); SetPort(&addr_storage, *Port(&bind_addr_storage_) + 1); ASSERT_THAT(connect(bind_.get(), addr, addrlen_), SyscallSucceeds()); @@ -1050,7 +1022,7 @@ TEST_P(UdpSocketTest, ReceiveFrom) { // Connect to loopback:bind_addr_port+1. struct sockaddr_storage addr_storage = InetLoopbackAddr(); - struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); + struct sockaddr* addr = AsSockAddr(&addr_storage); SetPort(&addr_storage, *Port(&bind_addr_storage_) + 1); ASSERT_THAT(connect(bind_.get(), addr, addrlen_), SyscallSucceeds()); @@ -1069,7 +1041,7 @@ TEST_P(UdpSocketTest, ReceiveFrom) { struct sockaddr_storage addr2; socklen_t addr2len = sizeof(addr2); EXPECT_THAT(recvfrom(bind_.get(), received, sizeof(received), 0, - reinterpret_cast<sockaddr*>(&addr2), &addr2len), + AsSockAddr(&addr2), &addr2len), SyscallSucceedsWithValue(sizeof(received))); EXPECT_EQ(memcmp(buf, received, sizeof(buf)), 0); EXPECT_EQ(addr2len, addrlen_); @@ -1093,7 +1065,7 @@ TEST_P(UdpSocketTest, ReadShutdownNonblockPendingData) { // Connect to loopback:bind_addr_port+1. struct sockaddr_storage addr_storage = InetLoopbackAddr(); - struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); + struct sockaddr* addr = AsSockAddr(&addr_storage); SetPort(&addr_storage, *Port(&bind_addr_storage_) + 1); ASSERT_THAT(connect(bind_.get(), addr, addrlen_), SyscallSucceeds()); @@ -1149,7 +1121,7 @@ TEST_P(UdpSocketTest, ReadShutdownSameSocketResetsShutdownState) { // Connect to loopback:bind_addr_port+1. struct sockaddr_storage addr_storage = InetLoopbackAddr(); - struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); + struct sockaddr* addr = AsSockAddr(&addr_storage); SetPort(&addr_storage, *Port(&bind_addr_storage_) + 1); ASSERT_THAT(connect(bind_.get(), addr, addrlen_), SyscallSucceeds()); @@ -1932,13 +1904,8 @@ TEST_P(UdpSocketTest, RecvBufLimits) { SyscallSucceeds()); } - // Now set the limit to min * 4. - int new_rcv_buf_sz = min * 4; - if (!IsRunningOnGvisor() || IsRunningWithHostinet()) { - // Linux doubles the value specified so just set to min * 2. - new_rcv_buf_sz = min * 2; - } - + // Now set the limit to min * 2. + int new_rcv_buf_sz = min * 2; ASSERT_THAT(setsockopt(bind_.get(), SOL_SOCKET, SO_RCVBUF, &new_rcv_buf_sz, sizeof(new_rcv_buf_sz)), SyscallSucceeds()); @@ -2051,68 +2018,57 @@ TEST_P(UdpSocketTest, SendToZeroPort) { // Sending to an invalid port should fail. SetPort(&addr, 0); - EXPECT_THAT(sendto(sock_.get(), buf, sizeof(buf), 0, - reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)), - SyscallFailsWithErrno(EINVAL)); + EXPECT_THAT( + sendto(sock_.get(), buf, sizeof(buf), 0, AsSockAddr(&addr), sizeof(addr)), + SyscallFailsWithErrno(EINVAL)); SetPort(&addr, 1234); - EXPECT_THAT(sendto(sock_.get(), buf, sizeof(buf), 0, - reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)), - SyscallSucceedsWithValue(sizeof(buf))); + EXPECT_THAT( + sendto(sock_.get(), buf, sizeof(buf), 0, AsSockAddr(&addr), sizeof(addr)), + SyscallSucceedsWithValue(sizeof(buf))); } TEST_P(UdpSocketTest, ConnectToZeroPortUnbound) { struct sockaddr_storage addr = InetLoopbackAddr(); SetPort(&addr, 0); - ASSERT_THAT( - connect(sock_.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen_), - SyscallSucceeds()); + ASSERT_THAT(connect(sock_.get(), AsSockAddr(&addr), addrlen_), + SyscallSucceeds()); } TEST_P(UdpSocketTest, ConnectToZeroPortBound) { struct sockaddr_storage addr = InetLoopbackAddr(); - ASSERT_NO_ERRNO( - BindSocket(sock_.get(), reinterpret_cast<struct sockaddr*>(&addr))); + ASSERT_NO_ERRNO(BindSocket(sock_.get(), AsSockAddr(&addr))); SetPort(&addr, 0); - ASSERT_THAT( - connect(sock_.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen_), - SyscallSucceeds()); + ASSERT_THAT(connect(sock_.get(), AsSockAddr(&addr), addrlen_), + SyscallSucceeds()); socklen_t len = sizeof(sockaddr_storage); - ASSERT_THAT( - getsockname(sock_.get(), reinterpret_cast<struct sockaddr*>(&addr), &len), - SyscallSucceeds()); + ASSERT_THAT(getsockname(sock_.get(), AsSockAddr(&addr), &len), + SyscallSucceeds()); ASSERT_EQ(len, addrlen_); } TEST_P(UdpSocketTest, ConnectToZeroPortConnected) { struct sockaddr_storage addr = InetLoopbackAddr(); - ASSERT_NO_ERRNO( - BindSocket(sock_.get(), reinterpret_cast<struct sockaddr*>(&addr))); + ASSERT_NO_ERRNO(BindSocket(sock_.get(), AsSockAddr(&addr))); // Connect to an address with non-zero port should succeed. - ASSERT_THAT( - connect(sock_.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen_), - SyscallSucceeds()); + ASSERT_THAT(connect(sock_.get(), AsSockAddr(&addr), addrlen_), + SyscallSucceeds()); sockaddr_storage peername; socklen_t peerlen = sizeof(peername); - ASSERT_THAT( - getpeername(sock_.get(), reinterpret_cast<struct sockaddr*>(&peername), - &peerlen), - SyscallSucceeds()); + ASSERT_THAT(getpeername(sock_.get(), AsSockAddr(&peername), &peerlen), + SyscallSucceeds()); ASSERT_EQ(peerlen, addrlen_); ASSERT_EQ(memcmp(&peername, &addr, addrlen_), 0); // However connect() to an address with port 0 will make the following // getpeername() fail. SetPort(&addr, 0); - ASSERT_THAT( - connect(sock_.get(), reinterpret_cast<struct sockaddr*>(&addr), addrlen_), - SyscallSucceeds()); - ASSERT_THAT( - getpeername(sock_.get(), reinterpret_cast<struct sockaddr*>(&peername), - &peerlen), - SyscallFailsWithErrno(ENOTCONN)); + ASSERT_THAT(connect(sock_.get(), AsSockAddr(&addr), addrlen_), + SyscallSucceeds()); + ASSERT_THAT(getpeername(sock_.get(), AsSockAddr(&peername), &peerlen), + SyscallFailsWithErrno(ENOTCONN)); } INSTANTIATE_TEST_SUITE_P(AllInetTests, UdpSocketTest, @@ -2133,8 +2089,7 @@ TEST(UdpInet6SocketTest, ConnectInet4Sockaddr) { SyscallSucceeds()); sockaddr_storage sockname; socklen_t len = sizeof(sockaddr_storage); - ASSERT_THAT(getsockname(sock_.get(), - reinterpret_cast<struct sockaddr*>(&sockname), &len), + ASSERT_THAT(getsockname(sock_.get(), AsSockAddr(&sockname), &len), SyscallSucceeds()); ASSERT_EQ(sockname.ss_family, AF_INET6); ASSERT_EQ(len, sizeof(sockaddr_in6)); diff --git a/test/syscalls/linux/unlink.cc b/test/syscalls/linux/unlink.cc index 061e2e0f1..7c301c305 100644 --- a/test/syscalls/linux/unlink.cc +++ b/test/syscalls/linux/unlink.cc @@ -64,7 +64,7 @@ TEST(UnlinkTest, AtDir) { ASSERT_THAT(close(dirfd), SyscallSucceeds()); } -TEST(UnlinkTest, AtDirDegradedPermissions_NoRandomSave) { +TEST(UnlinkTest, AtDirDegradedPermissions) { // Drop capabilities that allow us to override file and directory permissions. ASSERT_NO_ERRNO(SetCapability(CAP_DAC_OVERRIDE, false)); ASSERT_NO_ERRNO(SetCapability(CAP_DAC_READ_SEARCH, false)); @@ -162,7 +162,7 @@ TEST(UnlinkTest, AtFile) { EXPECT_THAT(unlinkat(dirfd, "UnlinkAtFile", 0), SyscallSucceeds()); } -TEST(UnlinkTest, OpenFile_NoRandomSave) { +TEST(UnlinkTest, OpenFile) { // We can't save unlinked file unless they are on tmpfs. const DisableSave ds; auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); diff --git a/test/syscalls/linux/verity_ioctl.cc b/test/syscalls/linux/verity_ioctl.cc new file mode 100644 index 000000000..a81fe5724 --- /dev/null +++ b/test/syscalls/linux/verity_ioctl.cc @@ -0,0 +1,188 @@ +// Copyright 2021 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <stdint.h> +#include <sys/mount.h> + +#include <iomanip> +#include <sstream> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "test/util/capability_util.h" +#include "test/util/fs_util.h" +#include "test/util/mount_util.h" +#include "test/util/temp_path.h" +#include "test/util/test_util.h" + +namespace gvisor { +namespace testing { + +namespace { + +#ifndef FS_IOC_ENABLE_VERITY +#define FS_IOC_ENABLE_VERITY 1082156677 +#endif + +#ifndef FS_IOC_MEASURE_VERITY +#define FS_IOC_MEASURE_VERITY 3221513862 +#endif + +#ifndef FS_VERITY_FL +#define FS_VERITY_FL 1048576 +#endif + +#ifndef FS_IOC_GETFLAGS +#define FS_IOC_GETFLAGS 2148034049 +#endif + +struct fsverity_digest { + __u16 digest_algorithm; + __u16 digest_size; /* input/output */ + __u8 digest[]; +}; + +constexpr int kMaxDigestSize = 64; +constexpr int kDefaultDigestSize = 32; +constexpr char kContents[] = "foobarbaz"; + +class IoctlTest : public ::testing::Test { + protected: + void SetUp() override { + // Verity is implemented in VFS2. + SKIP_IF(IsRunningWithVFS1()); + + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN))); + // Mount a tmpfs file system, to be wrapped by a verity fs. + tmpfs_dir_ = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); + ASSERT_THAT(mount("", tmpfs_dir_.path().c_str(), "tmpfs", 0, ""), + SyscallSucceeds()); + + // Create a new file in the tmpfs mount. + file_ = ASSERT_NO_ERRNO_AND_VALUE( + TempPath::CreateFileWith(tmpfs_dir_.path(), kContents, 0777)); + filename_ = Basename(file_.path()); + } + + TempPath tmpfs_dir_; + TempPath file_; + std::string filename_; +}; + +// Provide a function to convert bytes to hex string, since +// absl::BytesToHexString does not seem to be compatible with golang +// hex.DecodeString used in verity due to zero-padding. +std::string BytesToHexString(uint8_t bytes[], int size) { + std::stringstream ss; + ss << std::hex; + for (int i = 0; i < size; ++i) { + ss << std::setw(2) << std::setfill('0') << static_cast<int>(bytes[i]); + } + return ss.str(); +} + +TEST_F(IoctlTest, Enable) { + // Mount a verity fs on the existing tmpfs mount. + std::string mount_opts = "lower_path=" + tmpfs_dir_.path(); + auto const verity_dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); + ASSERT_THAT( + mount("", verity_dir.path().c_str(), "verity", 0, mount_opts.c_str()), + SyscallSucceeds()); + + // Confirm that the verity flag is absent. + int flag = 0; + auto const fd = ASSERT_NO_ERRNO_AND_VALUE( + Open(JoinPath(verity_dir.path(), filename_), O_RDONLY, 0777)); + ASSERT_THAT(ioctl(fd.get(), FS_IOC_GETFLAGS, &flag), SyscallSucceeds()); + EXPECT_EQ(flag & FS_VERITY_FL, 0); + + // Enable the file and confirm that the verity flag is present. + ASSERT_THAT(ioctl(fd.get(), FS_IOC_ENABLE_VERITY), SyscallSucceeds()); + ASSERT_THAT(ioctl(fd.get(), FS_IOC_GETFLAGS, &flag), SyscallSucceeds()); + EXPECT_EQ(flag & FS_VERITY_FL, FS_VERITY_FL); +} + +TEST_F(IoctlTest, Measure) { + // Mount a verity fs on the existing tmpfs mount. + std::string mount_opts = "lower_path=" + tmpfs_dir_.path(); + auto const verity_dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); + ASSERT_THAT( + mount("", verity_dir.path().c_str(), "verity", 0, mount_opts.c_str()), + SyscallSucceeds()); + + // Confirm that the file cannot be measured. + auto const fd = ASSERT_NO_ERRNO_AND_VALUE( + Open(JoinPath(verity_dir.path(), filename_), O_RDONLY, 0777)); + uint8_t digest_array[sizeof(struct fsverity_digest) + kMaxDigestSize] = {0}; + struct fsverity_digest* digest = + reinterpret_cast<struct fsverity_digest*>(digest_array); + digest->digest_size = kMaxDigestSize; + ASSERT_THAT(ioctl(fd.get(), FS_IOC_MEASURE_VERITY, digest), + SyscallFailsWithErrno(ENODATA)); + + // Enable the file and confirm that the file can be measured. + ASSERT_THAT(ioctl(fd.get(), FS_IOC_ENABLE_VERITY), SyscallSucceeds()); + ASSERT_THAT(ioctl(fd.get(), FS_IOC_MEASURE_VERITY, digest), + SyscallSucceeds()); + EXPECT_EQ(digest->digest_size, kDefaultDigestSize); +} + +TEST_F(IoctlTest, Mount) { + // Mount a verity fs on the existing tmpfs mount. + std::string mount_opts = "lower_path=" + tmpfs_dir_.path(); + auto verity_dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); + ASSERT_THAT( + mount("", verity_dir.path().c_str(), "verity", 0, mount_opts.c_str()), + SyscallSucceeds()); + + // Enable both the file and the directory. + auto const fd = ASSERT_NO_ERRNO_AND_VALUE( + Open(JoinPath(verity_dir.path(), filename_), O_RDONLY, 0777)); + ASSERT_THAT(ioctl(fd.get(), FS_IOC_ENABLE_VERITY), SyscallSucceeds()); + auto const dir_fd = + ASSERT_NO_ERRNO_AND_VALUE(Open(verity_dir.path(), O_RDONLY, 0777)); + ASSERT_THAT(ioctl(dir_fd.get(), FS_IOC_ENABLE_VERITY), SyscallSucceeds()); + + // Measure the root hash. + uint8_t digest_array[sizeof(struct fsverity_digest) + kMaxDigestSize] = {0}; + struct fsverity_digest* digest = + reinterpret_cast<struct fsverity_digest*>(digest_array); + digest->digest_size = kMaxDigestSize; + ASSERT_THAT(ioctl(dir_fd.get(), FS_IOC_MEASURE_VERITY, digest), + SyscallSucceeds()); + + // Mount a verity fs with specified root hash. + mount_opts += + ",root_hash=" + BytesToHexString(digest->digest, digest->digest_size); + auto verity_with_hash_dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); + ASSERT_THAT(mount("", verity_with_hash_dir.path().c_str(), "verity", 0, + mount_opts.c_str()), + SyscallSucceeds()); + + // Make sure the file can be open and read in the mounted verity fs. + auto const verity_fd = ASSERT_NO_ERRNO_AND_VALUE( + Open(JoinPath(verity_with_hash_dir.path(), filename_), O_RDONLY, 0777)); + char buf[16]; + EXPECT_THAT(ReadFd(fd.get(), buf, sizeof(kContents)), SyscallSucceeds()); + + // Verity directories should not be deleted. Release the TempPath objects to + // prevent those directories from being deleted by the destructor. + verity_dir.release(); + verity_with_hash_dir.release(); +} + +} // namespace + +} // namespace testing +} // namespace gvisor diff --git a/test/syscalls/linux/verity_mount.cc b/test/syscalls/linux/verity_mount.cc new file mode 100644 index 000000000..e73dd5599 --- /dev/null +++ b/test/syscalls/linux/verity_mount.cc @@ -0,0 +1,53 @@ +// Copyright 2021 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <sys/mount.h> + +#include <iomanip> +#include <sstream> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "test/util/capability_util.h" +#include "test/util/temp_path.h" +#include "test/util/test_util.h" + +namespace gvisor { +namespace testing { + +namespace { + +// Mount verity file system on an existing gofer mount. +TEST(MountTest, MountExisting) { + // Verity is implemented in VFS2. + SKIP_IF(IsRunningWithVFS1()); + + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN))); + + // Mount a new tmpfs file system. + auto const tmpfs_dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); + ASSERT_THAT(mount("", tmpfs_dir.path().c_str(), "tmpfs", 0, ""), + SyscallSucceeds()); + + // Mount a verity file system on the existing gofer mount. + auto const verity_dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); + std::string opts = "lower_path=" + tmpfs_dir.path(); + EXPECT_THAT(mount("", verity_dir.path().c_str(), "verity", 0, opts.c_str()), + SyscallSucceeds()); +} + +} // namespace + +} // namespace testing +} // namespace gvisor diff --git a/test/syscalls/linux/vfork.cc b/test/syscalls/linux/vfork.cc index 19d05998e..1a282e371 100644 --- a/test/syscalls/linux/vfork.cc +++ b/test/syscalls/linux/vfork.cc @@ -87,7 +87,7 @@ TEST(VforkTest, ParentStopsUntilChildExits) { EXPECT_THAT(InForkedProcess(test), IsPosixErrorOkAndHolds(0)); } -TEST(VforkTest, ParentStopsUntilChildExecves_NoRandomSave) { +TEST(VforkTest, ParentStopsUntilChildExecves) { ExecveArray const owned_child_argv = {"/proc/self/exe", "--vfork_test_child"}; char* const* const child_argv = owned_child_argv.get(); @@ -127,7 +127,7 @@ TEST(VforkTest, ParentStopsUntilChildExecves_NoRandomSave) { // A vfork child does not unstop the parent a second time when it exits after // exec. -TEST(VforkTest, ExecedChildExitDoesntUnstopParent_NoRandomSave) { +TEST(VforkTest, ExecedChildExitDoesntUnstopParent) { ExecveArray const owned_child_argv = {"/proc/self/exe", "--vfork_test_child"}; char* const* const child_argv = owned_child_argv.get(); diff --git a/test/syscalls/linux/xattr.cc b/test/syscalls/linux/xattr.cc index a953a55fe..dd8067807 100644 --- a/test/syscalls/linux/xattr.cc +++ b/test/syscalls/linux/xattr.cc @@ -107,7 +107,7 @@ TEST_F(XattrTest, XattrInvalidPrefix) { // Do not allow save/restore cycles after making the test file read-only, as // the restore will fail to open it with r/w permissions. -TEST_F(XattrTest, XattrReadOnly_NoRandomSave) { +TEST_F(XattrTest, XattrReadOnly) { // Drop capabilities that allow us to override file and directory permissions. ASSERT_NO_ERRNO(SetCapability(CAP_DAC_OVERRIDE, false)); ASSERT_NO_ERRNO(SetCapability(CAP_DAC_READ_SEARCH, false)); @@ -138,7 +138,7 @@ TEST_F(XattrTest, XattrReadOnly_NoRandomSave) { // Do not allow save/restore cycles after making the test file write-only, as // the restore will fail to open it with r/w permissions. -TEST_F(XattrTest, XattrWriteOnly_NoRandomSave) { +TEST_F(XattrTest, XattrWriteOnly) { // Drop capabilities that allow us to override file and directory permissions. ASSERT_NO_ERRNO(SetCapability(CAP_DAC_OVERRIDE, false)); ASSERT_NO_ERRNO(SetCapability(CAP_DAC_READ_SEARCH, false)); diff --git a/test/util/BUILD b/test/util/BUILD index e561f3daa..383de00ed 100644 --- a/test/util/BUILD +++ b/test/util/BUILD @@ -94,6 +94,7 @@ cc_library( ":file_descriptor", ":posix_error", "@com_google_absl//absl/strings", + "@com_google_absl//absl/time", gtest, ], ) @@ -368,3 +369,20 @@ cc_library( testonly = 1, hdrs = ["temp_umask.h"], ) + +cc_library( + name = "cgroup_util", + testonly = 1, + srcs = ["cgroup_util.cc"], + hdrs = ["cgroup_util.h"], + deps = [ + ":cleanup", + ":fs_util", + ":mount_util", + ":posix_error", + ":temp_path", + "@com_google_absl//absl/container:flat_hash_map", + "@com_google_absl//absl/container:flat_hash_set", + "@com_google_absl//absl/strings", + ], +) diff --git a/test/util/cgroup_util.cc b/test/util/cgroup_util.cc new file mode 100644 index 000000000..65d9c4986 --- /dev/null +++ b/test/util/cgroup_util.cc @@ -0,0 +1,223 @@ +// Copyright 2021 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "test/util/cgroup_util.h" + +#include <sys/syscall.h> +#include <unistd.h> + +#include "absl/strings/str_split.h" +#include "test/util/fs_util.h" +#include "test/util/mount_util.h" + +namespace gvisor { +namespace testing { + +Cgroup::Cgroup(std::string path) : cgroup_path_(path) { + id_ = ++Cgroup::next_id_; + std::cerr << absl::StreamFormat("[cg#%d] <= %s", id_, cgroup_path_) + << std::endl; +} + +PosixErrorOr<std::string> Cgroup::ReadControlFile( + absl::string_view name) const { + std::string buf; + RETURN_IF_ERRNO(GetContents(Relpath(name), &buf)); + + const std::string alias_path = absl::StrFormat("[cg#%d]/%s", id_, name); + std::cerr << absl::StreamFormat("<contents of %s>", alias_path) << std::endl; + std::cerr << buf; + std::cerr << absl::StreamFormat("<end of %s>", alias_path) << std::endl; + + return buf; +} + +PosixErrorOr<int64_t> Cgroup::ReadIntegerControlFile( + absl::string_view name) const { + ASSIGN_OR_RETURN_ERRNO(const std::string buf, ReadControlFile(name)); + ASSIGN_OR_RETURN_ERRNO(const int64_t val, Atoi<int64_t>(buf)); + return val; +} + +PosixErrorOr<absl::flat_hash_set<pid_t>> Cgroup::Procs() const { + ASSIGN_OR_RETURN_ERRNO(std::string buf, ReadControlFile("cgroup.procs")); + return ParsePIDList(buf); +} + +PosixErrorOr<absl::flat_hash_set<pid_t>> Cgroup::Tasks() const { + ASSIGN_OR_RETURN_ERRNO(std::string buf, ReadControlFile("tasks")); + return ParsePIDList(buf); +} + +PosixError Cgroup::ContainsCallingProcess() const { + ASSIGN_OR_RETURN_ERRNO(const absl::flat_hash_set<pid_t> procs, Procs()); + ASSIGN_OR_RETURN_ERRNO(const absl::flat_hash_set<pid_t> tasks, Tasks()); + const pid_t pid = getpid(); + const pid_t tid = syscall(SYS_gettid); + if (!procs.contains(pid)) { + return PosixError( + ENOENT, absl::StrFormat("Cgroup doesn't contain process %d", pid)); + } + if (!tasks.contains(tid)) { + return PosixError(ENOENT, + absl::StrFormat("Cgroup doesn't contain task %d", tid)); + } + return NoError(); +} + +PosixErrorOr<absl::flat_hash_set<pid_t>> Cgroup::ParsePIDList( + absl::string_view data) const { + absl::flat_hash_set<pid_t> res; + std::vector<absl::string_view> lines = absl::StrSplit(data, '\n'); + for (const std::string_view& line : lines) { + if (line.empty()) { + continue; + } + ASSIGN_OR_RETURN_ERRNO(const int32_t pid, Atoi<int32_t>(line)); + res.insert(static_cast<pid_t>(pid)); + } + return res; +} + +int64_t Cgroup::next_id_ = 0; + +PosixErrorOr<Cgroup> Mounter::MountCgroupfs(std::string mopts) { + ASSIGN_OR_RETURN_ERRNO(TempPath mountpoint, + TempPath::CreateDirIn(root_.path())); + ASSIGN_OR_RETURN_ERRNO( + Cleanup mount, Mount("none", mountpoint.path(), "cgroup", 0, mopts, 0)); + const std::string mountpath = mountpoint.path(); + std::cerr << absl::StreamFormat( + "Mount(\"none\", \"%s\", \"cgroup\", 0, \"%s\", 0) => OK", + mountpath, mopts) + << std::endl; + Cgroup cg = Cgroup(mountpath); + mountpoints_[cg.id()] = std::move(mountpoint); + mounts_[cg.id()] = std::move(mount); + return cg; +} + +PosixError Mounter::Unmount(const Cgroup& c) { + auto mount = mounts_.find(c.id()); + auto mountpoint = mountpoints_.find(c.id()); + + if (mount == mounts_.end() || mountpoint == mountpoints_.end()) { + return PosixError( + ESRCH, absl::StrFormat("No mount found for cgroupfs containing cg#%d", + c.id())); + } + + std::cerr << absl::StreamFormat("Unmount([cg#%d])", c.id()) << std::endl; + + // Simply delete the entries, their destructors will unmount and delete the + // mountpoint. Note the order is important to avoid errors: mount then + // mountpoint. + mounts_.erase(mount); + mountpoints_.erase(mountpoint); + + return NoError(); +} + +constexpr char kProcCgroupsHeader[] = + "#subsys_name\thierarchy\tnum_cgroups\tenabled"; + +PosixErrorOr<absl::flat_hash_map<std::string, CgroupsEntry>> +ProcCgroupsEntries() { + std::string content; + RETURN_IF_ERRNO(GetContents("/proc/cgroups", &content)); + + bool found_header = false; + absl::flat_hash_map<std::string, CgroupsEntry> entries; + std::vector<std::string> lines = absl::StrSplit(content, '\n'); + std::cerr << "<contents of /proc/cgroups>" << std::endl; + for (const std::string& line : lines) { + std::cerr << line << std::endl; + + if (!found_header) { + EXPECT_EQ(line, kProcCgroupsHeader); + found_header = true; + continue; + } + if (line.empty()) { + continue; + } + + // Parse a single entry from /proc/cgroups. + // + // Example entries, fields are tab separated in the real file: + // + // #subsys_name hierarchy num_cgroups enabled + // cpuset 12 35 1 + // cpu 3 222 1 + // ^ ^ ^ ^ + // 0 1 2 3 + + CgroupsEntry entry; + std::vector<std::string> fields = + StrSplit(line, absl::ByAnyChar(": \t"), absl::SkipEmpty()); + + entry.subsys_name = fields[0]; + ASSIGN_OR_RETURN_ERRNO(entry.hierarchy, Atoi<uint32_t>(fields[1])); + ASSIGN_OR_RETURN_ERRNO(entry.num_cgroups, Atoi<uint64_t>(fields[2])); + ASSIGN_OR_RETURN_ERRNO(const int enabled, Atoi<int>(fields[3])); + entry.enabled = enabled != 0; + + entries[entry.subsys_name] = entry; + } + std::cerr << "<end of /proc/cgroups>" << std::endl; + + return entries; +} + +PosixErrorOr<absl::flat_hash_map<std::string, PIDCgroupEntry>> +ProcPIDCgroupEntries(pid_t pid) { + const std::string path = absl::StrFormat("/proc/%d/cgroup", pid); + std::string content; + RETURN_IF_ERRNO(GetContents(path, &content)); + + absl::flat_hash_map<std::string, PIDCgroupEntry> entries; + std::vector<std::string> lines = absl::StrSplit(content, '\n'); + + std::cerr << absl::StreamFormat("<contents of %s>", path) << std::endl; + for (const std::string& line : lines) { + std::cerr << line << std::endl; + + if (line.empty()) { + continue; + } + + // Parse a single entry from /proc/<pid>/cgroup. + // + // Example entries: + // + // 2:cpu:/path/to/cgroup + // 1:memory:/ + + PIDCgroupEntry entry; + std::vector<std::string> fields = + absl::StrSplit(line, absl::ByChar(':'), absl::SkipEmpty()); + + ASSIGN_OR_RETURN_ERRNO(entry.hierarchy, Atoi<uint32_t>(fields[0])); + entry.controllers = fields[1]; + entry.path = fields[2]; + + entries[entry.controllers] = entry; + } + std::cerr << absl::StreamFormat("<end of %s>", path) << std::endl; + + return entries; +} + +} // namespace testing +} // namespace gvisor diff --git a/test/util/cgroup_util.h b/test/util/cgroup_util.h new file mode 100644 index 000000000..b049559df --- /dev/null +++ b/test/util/cgroup_util.h @@ -0,0 +1,111 @@ +// Copyright 2021 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef GVISOR_TEST_UTIL_CGROUP_UTIL_H_ +#define GVISOR_TEST_UTIL_CGROUP_UTIL_H_ + +#include <unistd.h> + +#include "absl/container/flat_hash_map.h" +#include "absl/container/flat_hash_set.h" +#include "absl/strings/string_view.h" +#include "test/util/cleanup.h" +#include "test/util/fs_util.h" +#include "test/util/temp_path.h" + +namespace gvisor { +namespace testing { + +// Cgroup represents a cgroup directory on a mounted cgroupfs. +class Cgroup { + public: + Cgroup(std::string path); + + uint64_t id() const { return id_; } + + std::string Relpath(absl::string_view leaf) const { + return JoinPath(cgroup_path_, leaf); + } + + // Returns the contents of a cgroup control file with the given name. + PosixErrorOr<std::string> ReadControlFile(absl::string_view name) const; + + // Reads the contents of a cgroup control with the given name, and attempts + // to parse it as an integer. + PosixErrorOr<int64_t> ReadIntegerControlFile(absl::string_view name) const; + + // Returns the thread ids of the leaders of thread groups managed by this + // cgroup. + PosixErrorOr<absl::flat_hash_set<pid_t>> Procs() const; + + PosixErrorOr<absl::flat_hash_set<pid_t>> Tasks() const; + + // ContainsCallingProcess checks whether the calling process is part of the + PosixError ContainsCallingProcess() const; + + private: + PosixErrorOr<absl::flat_hash_set<pid_t>> ParsePIDList( + absl::string_view data) const; + + static int64_t next_id_; + int64_t id_; + const std::string cgroup_path_; +}; + +// Mounter is a utility for creating cgroupfs mounts. It automatically manages +// the lifetime of created mounts. +class Mounter { + public: + Mounter(TempPath root) : root_(std::move(root)) {} + + PosixErrorOr<Cgroup> MountCgroupfs(std::string mopts); + + PosixError Unmount(const Cgroup& c); + + private: + // The destruction order of these members avoids errors during cleanup. We + // first unmount (by executing the mounts_ cleanups), then delete the + // mountpoint subdirs, then delete the root. + TempPath root_; + absl::flat_hash_map<int64_t, TempPath> mountpoints_; + absl::flat_hash_map<int64_t, Cleanup> mounts_; +}; + +// Represents a line from /proc/cgroups. +struct CgroupsEntry { + std::string subsys_name; + uint32_t hierarchy; + uint64_t num_cgroups; + bool enabled; +}; + +// Returns a parsed representation of /proc/cgroups. +PosixErrorOr<absl::flat_hash_map<std::string, CgroupsEntry>> +ProcCgroupsEntries(); + +// Represents a line from /proc/<pid>/cgroup. +struct PIDCgroupEntry { + uint32_t hierarchy; + std::string controllers; + std::string path; +}; + +// Returns a parsed representation of /proc/<pid>/cgroup. +PosixErrorOr<absl::flat_hash_map<std::string, PIDCgroupEntry>> +ProcPIDCgroupEntries(pid_t pid); + +} // namespace testing +} // namespace gvisor + +#endif // GVISOR_TEST_UTIL_CGROUP_UTIL_H_ diff --git a/test/util/fs_util.cc b/test/util/fs_util.cc index 5f1ce0d8a..483ae848d 100644 --- a/test/util/fs_util.cc +++ b/test/util/fs_util.cc @@ -28,6 +28,8 @@ #include "absl/strings/str_cat.h" #include "absl/strings/str_split.h" #include "absl/strings/string_view.h" +#include "absl/time/clock.h" +#include "absl/time/time.h" #include "test/util/cleanup.h" #include "test/util/file_descriptor.h" #include "test/util/posix_error.h" @@ -366,6 +368,48 @@ PosixErrorOr<std::vector<std::string>> ListDir(absl::string_view abspath, return files; } +PosixError DirContains(absl::string_view path, + const std::vector<std::string>& expect, + const std::vector<std::string>& exclude) { + ASSIGN_OR_RETURN_ERRNO(auto listing, ListDir(path, false)); + + for (auto& expected_entry : expect) { + auto cursor = std::find(listing.begin(), listing.end(), expected_entry); + if (cursor == listing.end()) { + return PosixError(ENOENT, absl::StrFormat("Failed to find '%s' in '%s'", + expected_entry, path)); + } + } + for (auto& excluded_entry : exclude) { + auto cursor = std::find(listing.begin(), listing.end(), excluded_entry); + if (cursor != listing.end()) { + return PosixError(ENOENT, absl::StrCat("File '", excluded_entry, + "' found in path '", path, "'")); + } + } + return NoError(); +} + +PosixError EventuallyDirContains(absl::string_view path, + const std::vector<std::string>& expect, + const std::vector<std::string>& exclude) { + constexpr int kRetryCount = 100; + const absl::Duration kRetryDelay = absl::Milliseconds(100); + + for (int i = 0; i < kRetryCount; ++i) { + auto res = DirContains(path, expect, exclude); + if (res.ok()) { + return res; + } + if (i < kRetryCount - 1) { + // Sleep if this isn't the final iteration. + absl::SleepFor(kRetryDelay); + } + } + return PosixError(ETIMEDOUT, + "Timed out while waiting for directory to contain files "); +} + PosixError RecursivelyDelete(absl::string_view path, int* undeleted_dirs, int* undeleted_files) { ASSIGN_OR_RETURN_ERRNO(bool exists, Exists(path)); diff --git a/test/util/fs_util.h b/test/util/fs_util.h index 2190c3bca..bb2d1d3c8 100644 --- a/test/util/fs_util.h +++ b/test/util/fs_util.h @@ -129,6 +129,18 @@ PosixError WalkTree( PosixErrorOr<std::vector<std::string>> ListDir(absl::string_view abspath, bool skipdots); +// Check that a directory contains children nodes named in expect, and does not +// contain any children nodes named in exclude. +PosixError DirContains(absl::string_view path, + const std::vector<std::string>& expect, + const std::vector<std::string>& exclude); + +// Same as DirContains, but adds a retry. Suitable for checking a directory +// being modified asynchronously. +PosixError EventuallyDirContains(absl::string_view path, + const std::vector<std::string>& expect, + const std::vector<std::string>& exclude); + // Attempt to recursively delete a directory or file. Returns an error and // the number of undeleted directories and files. If either // undeleted_dirs or undeleted_files is nullptr then it will not be used. diff --git a/test/util/save_util.cc b/test/util/save_util.cc index 59d47e06e..3e724d99b 100644 --- a/test/util/save_util.cc +++ b/test/util/save_util.cc @@ -27,23 +27,13 @@ namespace gvisor { namespace testing { namespace { -std::atomic<absl::optional<bool>> cooperative_save_present; -std::atomic<absl::optional<bool>> random_save_present; +std::atomic<absl::optional<bool>> save_present; -bool CooperativeSavePresent() { - auto present = cooperative_save_present.load(); +bool SavePresent() { + auto present = save_present.load(); if (!present.has_value()) { - present = getenv("GVISOR_COOPERATIVE_SAVE_TEST") != nullptr; - cooperative_save_present.store(present); - } - return present.value(); -} - -bool RandomSavePresent() { - auto present = random_save_present.load(); - if (!present.has_value()) { - present = getenv("GVISOR_RANDOM_SAVE_TEST") != nullptr; - random_save_present.store(present); + present = getenv("GVISOR_SAVE_TEST") != nullptr; + save_present.store(present); } return present.value(); } @@ -52,12 +42,10 @@ std::atomic<int> save_disable; } // namespace -bool IsRunningWithSaveRestore() { - return CooperativeSavePresent() || RandomSavePresent(); -} +bool IsRunningWithSaveRestore() { return SavePresent(); } void MaybeSave() { - if (CooperativeSavePresent() && save_disable.load() == 0) { + if (SavePresent() && save_disable.load() == 0) { internal::DoCooperativeSave(); } } |