diff options
author | Ian Gudger <igudger@google.com> | 2019-12-09 20:07:14 -0800 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2019-12-09 20:09:23 -0800 |
commit | 98aafb1334b816596b462ad12fa3e96784703061 (patch) | |
tree | 87aba86cf05b36915aad5c437d66025a3e10fcd7 /test/syscalls | |
parent | 18af75db9de5244bd3e180a86886a4b3cadd7547 (diff) |
Add test for SO_BINDTODEVICE state bug.
This was accidentally dropped from the change which fixed the bug.
Updates #1217
PiperOrigin-RevId: 284689362
Diffstat (limited to 'test/syscalls')
-rw-r--r-- | test/syscalls/linux/socket_bind_to_device_sequence.cc | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/test/syscalls/linux/socket_bind_to_device_sequence.cc b/test/syscalls/linux/socket_bind_to_device_sequence.cc index 033fd80a5..34b1058a9 100644 --- a/test/syscalls/linux/socket_bind_to_device_sequence.cc +++ b/test/syscalls/linux/socket_bind_to_device_sequence.cc @@ -97,6 +97,16 @@ class BindToDeviceSequenceTest : public ::testing::TestWithParam<SocketKind> { sockets_to_close_.erase(socket_id); } + // SetDevice changes the bind_to_device option. It does not bind or re-bind. + void SetDevice(int socket_id, int device_id) { + auto socket_fd = sockets_to_close_[socket_id]->get(); + string device_name; + ASSERT_NO_FATAL_FAILURE(GetDevice(device_id, &device_name)); + EXPECT_THAT(setsockopt(socket_fd, SOL_SOCKET, SO_BINDTODEVICE, + device_name.c_str(), device_name.size() + 1), + SyscallSucceedsWithValue(0)); + } + // Bind a socket with the reuse options and bind_to_device options. Checks // that all steps succeed and that the bind command's error matches want. // Sets the socket_id to uniquely identify the socket bound if it is not @@ -474,6 +484,25 @@ TEST_P(BindToDeviceSequenceTest, /* bind_to_device */ 0)); } +// Repro test for gvisor.dev/issue/1217. Not replicated in ports_test.go as this +// test is different from the others and wouldn't fit well there. +TEST_P(BindToDeviceSequenceTest, BindAndReleaseDifferentDevice) { + int to_release; + ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false, + /* reuse_addr */ false, + /* bind_to_device */ 3, 0, &to_release)); + ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false, + /* reuse_addr */ false, + /* bind_to_device */ 3, EADDRINUSE)); + // Change the device. Since the socket was already bound, this should have no + // effect. + SetDevice(to_release, 2); + // Release the bind to device 3 and try again. + ASSERT_NO_FATAL_FAILURE(ReleaseSocket(to_release)); + ASSERT_NO_FATAL_FAILURE(BindSocket( + /* reuse_port */ false, /* reuse_addr */ false, /* bind_to_device */ 3)); +} + INSTANTIATE_TEST_SUITE_P(BindToDeviceTest, BindToDeviceSequenceTest, ::testing::Values(IPv4UDPUnboundSocket(0), IPv4TCPUnboundSocket(0))); |