Add test for SO_REUSEPORT and SO_BINDTODEVICE together

Check that when two sockets are bound to the same device and have SO_REUSEPORT
set, they can both be bound to the same address. This test provides missing
coverage for when the two socket options are set together.

Bug: https://fxbug.dev/97822
PiperOrigin-RevId: 450053747
This commit is contained in:
gVisor bot
2022-05-20 13:41:35 -07:00
parent ad8960f604
commit 35ea47c6fc
@@ -2471,6 +2471,45 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, PortReuseTwoSockets) {
}
}
TEST_P(SocketMultiProtocolInetLoopbackTest, BindToDeviceReusePort) {
ProtocolTestParam const& param = GetParam();
TestAddress const& test_addr = V4Loopback();
auto socket1 =
ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr.family(), param.type, 0));
auto socket2 =
ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr.family(), param.type, 0));
const char kLoopbackDeviceName[] = "lo";
// Bind socket1 with REUSEPORT and BINDTODEVICE.
ASSERT_THAT(setsockopt(socket1.get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn,
sizeof(kSockOptOn)),
SyscallSucceeds());
ASSERT_THAT(setsockopt(socket1.get(), SOL_SOCKET, SO_BINDTODEVICE,
kLoopbackDeviceName, strlen(kLoopbackDeviceName)),
SyscallSucceeds());
// Bind the first socket to the loopback and take note of the selected port.
auto addr = V4Loopback();
ASSERT_THAT(bind(socket1.get(), AsSockAddr(&addr.addr), addr.addr_len),
SyscallSucceeds());
socklen_t addr_len = addr.addr_len;
ASSERT_THAT(getsockname(socket1.get(), AsSockAddr(&addr.addr), &addr_len),
SyscallSucceeds());
EXPECT_EQ(addr_len, addr.addr_len);
// Bind socket2 to the same device and address as socket1.
ASSERT_THAT(setsockopt(socket2.get(), SOL_SOCKET, SO_BINDTODEVICE,
kLoopbackDeviceName, strlen(kLoopbackDeviceName)),
SyscallSucceeds());
ASSERT_THAT(setsockopt(socket2.get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn,
sizeof(kSockOptOn)),
SyscallSucceeds());
ASSERT_THAT(bind(socket2.get(), AsSockAddr(&addr.addr), addr.addr_len),
SyscallSucceeds());
}
// Check that when a socket was bound to an address with REUSEPORT and then
// closed, we can bind a different socket to the same address without needing
// REUSEPORT.