gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/syscalls/linux/socket_ipv4_udp_unbound_loopback_nogotsan.cc (about) 1 // Copyright 2020 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include <sys/socket.h> 16 #include <sys/types.h> 17 18 #include "gtest/gtest.h" 19 #include "absl/memory/memory.h" 20 #include "test/syscalls/linux/ip_socket_test_util.h" 21 #include "test/util/socket_util.h" 22 #include "test/util/test_util.h" 23 24 namespace gvisor { 25 namespace testing { 26 27 // Test fixture for tests that apply to IPv4 UDP sockets. 28 using IPv4UDPUnboundSocketNogotsanTest = SimpleSocketTest; 29 30 // Check that connect returns EAGAIN when out of local ephemeral ports. 31 // We disable S/R because this test creates a large number of sockets. 32 TEST_P(IPv4UDPUnboundSocketNogotsanTest, UDPConnectPortExhaustion) { 33 auto receiver1 = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 34 const int kClients = ASSERT_NO_ERRNO_AND_VALUE(MaybeLimitEphemeralPorts()); 35 // Bind the first socket to the loopback and take note of the selected port. 36 auto addr = V4Loopback(); 37 ASSERT_THAT(bind(receiver1->get(), AsSockAddr(&addr.addr), addr.addr_len), 38 SyscallSucceeds()); 39 socklen_t addr_len = addr.addr_len; 40 ASSERT_THAT(getsockname(receiver1->get(), AsSockAddr(&addr.addr), &addr_len), 41 SyscallSucceeds()); 42 EXPECT_EQ(addr_len, addr.addr_len); 43 44 // Disable cooperative S/R as we are making too many syscalls. 45 DisableSave ds; 46 std::vector<std::unique_ptr<FileDescriptor>> sockets; 47 for (int i = 0; i < kClients; i++) { 48 auto s = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 49 50 int ret = connect(s->get(), AsSockAddr(&addr.addr), addr.addr_len); 51 if (ret == 0) { 52 sockets.push_back(std::move(s)); 53 continue; 54 } 55 ASSERT_THAT(ret, SyscallFailsWithErrno(EAGAIN)); 56 break; 57 } 58 } 59 60 // Check that bind returns EADDRINUSE when out of local ephemeral ports. 61 // We disable S/R because this test creates a large number of sockets. 62 TEST_P(IPv4UDPUnboundSocketNogotsanTest, UDPBindPortExhaustion) { 63 auto receiver1 = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 64 const int kClients = ASSERT_NO_ERRNO_AND_VALUE(MaybeLimitEphemeralPorts()); 65 auto addr = V4Loopback(); 66 // Disable cooperative S/R as we are making too many syscalls. 67 DisableSave ds; 68 std::vector<std::unique_ptr<FileDescriptor>> sockets; 69 for (int i = 0; i < kClients; i++) { 70 auto s = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 71 72 int ret = bind(s->get(), AsSockAddr(&addr.addr), addr.addr_len); 73 if (ret == 0) { 74 sockets.push_back(std::move(s)); 75 continue; 76 } 77 ASSERT_THAT(ret, SyscallFailsWithErrno(EADDRINUSE)); 78 break; 79 } 80 } 81 82 INSTANTIATE_TEST_SUITE_P( 83 IPv4UDPSockets, IPv4UDPUnboundSocketNogotsanTest, 84 ::testing::ValuesIn(ApplyVec<SocketKind>(IPv4UDPUnboundSocket, 85 AllBitwiseCombinations(List<int>{ 86 0, SOCK_NONBLOCK})))); 87 88 } // namespace testing 89 } // namespace gvisor