diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index 58c9e6f3d2..0d20c4143e 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -2960,6 +2960,7 @@ cc_library( "socket_ipv4_udp_unbound_external_networking.h", ], deps = select_gtest() + [ + ":ip_socket_test_util", ":socket_ip_udp_unbound_external_networking", "//test/util:capability_util", "//test/util:socket_util", 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 6c67ec51e9..28342c4ea5 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc +++ b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc @@ -16,14 +16,19 @@ #include +#include +#include +#include + #include "absl/cleanup/cleanup.h" +#include "test/syscalls/linux/ip_socket_test_util.h" #include "test/util/socket_util.h" #include "test/util/test_util.h" namespace gvisor { namespace testing { -void IPv4UDPUnboundExternalNetworkingSocketTest::SetUp() { +void IPv4UDPUnboundExternalNetworkingSocketTestBase::SetUpNetworkInterfaces() { #ifdef ANDROID GTEST_SKIP() << "Android does not support getifaddrs in r22"; #endif @@ -70,6 +75,16 @@ void IPv4UDPUnboundExternalNetworkingSocketTest::SetUp() { } } +void IPv4UDPUnboundExternalNetworkingSocketTest::SetUp() { + SetUpNetworkInterfaces(); +} + +std::vector IPv4UDPUnboundExternalNetworkingSocketKinds() { + return ApplyVec( + IPv4UDPUnboundSocket, + AllBitwiseCombinations(List{0, SOCK_NONBLOCK})); +} + TestAddress V4EmptyAddress() { TestAddress t("V4Empty"); t.addr.ss_family = AF_INET; @@ -77,6 +92,43 @@ TestAddress V4EmptyAddress() { return t; } +namespace { + +struct BroadcastSendRecvBindParam { + SocketKind socket_kind; + TestAddress (*src_addr)(); + std::string src_addr_name; +}; + +class IPv4UDPUnboundExternalNetworkingSocketBoundToAddressTest + : public ::testing::TestWithParam, + protected IPv4UDPUnboundExternalNetworkingSocketTestBase { + protected: + void SetUp() override { + SetUpNetworkInterfaces(); + printf("Testing with %s bound to %s\n", + GetParam().socket_kind.description.c_str(), + GetParam().src_addr_name.c_str()); + fflush(stdout); + } + + PosixErrorOr> NewSocket() const { + return GetParam().socket_kind.Create(); + } +}; + +std::vector BroadcastSendRecvBindParams() { + std::vector params; + for (const SocketKind& socket_kind : + IPv4UDPUnboundExternalNetworkingSocketKinds()) { + params.push_back({socket_kind, V4Broadcast, "broadcast"}); + params.push_back({socket_kind, V4Any, "any"}); + } + return params; +} + +} // namespace + // Verifies that a broadcast UDP packet will arrive at all UDP sockets with // the destination port number. TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, @@ -229,11 +281,10 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, } // Verifies that a UDP broadcast can be sent and then received back on the same -// socket that is bound to the broadcast address (255.255.255.255). -// FIXME(b/141938460): This can be combined with the next test -// (UDPBroadcastSendRecvOnSocketBoundToAny). -TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, - UDPBroadcastSendRecvOnSocketBoundToBroadcast) { +// socket when it is bound to either the broadcast address (255.255.255.255) or +// the ANY address (0.0.0.0). +TEST_P(IPv4UDPUnboundExternalNetworkingSocketBoundToAddressTest, + UDPBroadcastSendRecvOnSocketBoundToAddress) { auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); // Enable SO_BROADCAST. @@ -241,8 +292,7 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, sizeof(kSockOptOn)), SyscallSucceedsWithValue(0)); - // Bind the sender to the broadcast address. - auto src_addr = V4Broadcast(); + auto src_addr = GetParam().src_addr(); ASSERT_THAT( bind(sender->get(), AsSockAddr(&src_addr.addr), src_addr.addr_len), SyscallSucceedsWithValue(0)); @@ -267,44 +317,9 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, EXPECT_EQ(0, memcmp(buf, kTestMsg, sizeof(kTestMsg))); } -// Verifies that a UDP broadcast can be sent and then received back on the same -// socket that is bound to the ANY address (0.0.0.0). -// FIXME(b/141938460): This can be combined with the previous test -// (UDPBroadcastSendRecvOnSocketBoundToBroadcast). -TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, - UDPBroadcastSendRecvOnSocketBoundToAny) { - auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); - - // Enable SO_BROADCAST. - ASSERT_THAT(setsockopt(sender->get(), SOL_SOCKET, SO_BROADCAST, &kSockOptOn, - sizeof(kSockOptOn)), - SyscallSucceedsWithValue(0)); - - // Bind the sender to the ANY address. - auto src_addr = V4Any(); - 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(), AsSockAddr(&src_addr.addr), &src_sz), - SyscallSucceedsWithValue(0)); - EXPECT_EQ(src_sz, src_addr.addr_len); - - // Send the message. - auto dst_addr = V4Broadcast(); - reinterpret_cast(&dst_addr.addr)->sin_port = - reinterpret_cast(&src_addr.addr)->sin_port; - constexpr char kTestMsg[] = "hello, world"; - 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)] = {}; - EXPECT_THAT(RetryEINTR(recv)(sender->get(), buf, sizeof(buf), 0), - SyscallSucceedsWithValue(sizeof(kTestMsg))); - EXPECT_EQ(0, memcmp(buf, kTestMsg, sizeof(kTestMsg))); -} +INSTANTIATE_TEST_SUITE_P(IPv4UDPUnboundSockets, + IPv4UDPUnboundExternalNetworkingSocketBoundToAddressTest, + ::testing::ValuesIn(BroadcastSendRecvBindParams())); // Verifies that a UDP broadcast fails to send on a socket with SO_BROADCAST // disabled. diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h index ac917b32c3..fa36c44547 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h +++ b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h @@ -15,17 +15,18 @@ #ifndef GVISOR_TEST_SYSCALLS_LINUX_SOCKET_IPV4_UDP_UNBOUND_EXTERNAL_NETWORKING_H_ #define GVISOR_TEST_SYSCALLS_LINUX_SOCKET_IPV4_UDP_UNBOUND_EXTERNAL_NETWORKING_H_ +#include +#include +#include + #include "test/syscalls/linux/socket_ip_udp_unbound_external_networking.h" namespace gvisor { namespace testing { -// Test fixture for tests that apply to unbound IPv4 UDP sockets in a sandbox -// with external networking support. -class IPv4UDPUnboundExternalNetworkingSocketTest - : public IPUDPUnboundExternalNetworkingSocketTest { +class IPv4UDPUnboundExternalNetworkingSocketTestBase { protected: - void SetUp() override; + void SetUpNetworkInterfaces(); int lo_if_idx() const { return std::get<0>(lo_if_.value()); } int eth_if_idx() const { return std::get<0>(eth_if_.value()); } @@ -39,6 +40,17 @@ class IPv4UDPUnboundExternalNetworkingSocketTest std::optional> lo_if_, eth_if_; }; +// Test fixture for tests that apply to unbound IPv4 UDP sockets in a sandbox +// with external networking support. +class IPv4UDPUnboundExternalNetworkingSocketTest + : public IPUDPUnboundExternalNetworkingSocketTest, + protected IPv4UDPUnboundExternalNetworkingSocketTestBase { + protected: + void SetUp() override; +}; + +std::vector IPv4UDPUnboundExternalNetworkingSocketKinds(); + } // namespace testing } // namespace gvisor diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking_test.cc b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking_test.cc index ebf2185f22..edd363dde6 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking_test.cc +++ b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking_test.cc @@ -14,9 +14,6 @@ #include "test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h" -#include - -#include "test/syscalls/linux/ip_socket_test_util.h" #include "test/util/socket_util.h" #include "test/util/test_util.h" @@ -24,15 +21,10 @@ namespace gvisor { namespace testing { namespace { -std::vector GetSockets() { - return ApplyVec( - IPv4UDPUnboundSocket, - AllBitwiseCombinations(List{0, SOCK_NONBLOCK})); -} - INSTANTIATE_TEST_SUITE_P(IPv4UDPUnboundSockets, IPv4UDPUnboundExternalNetworkingSocketTest, - ::testing::ValuesIn(GetSockets())); + ::testing::ValuesIn( + IPv4UDPUnboundExternalNetworkingSocketKinds())); } // namespace } // namespace testing