github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/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/syscalls/linux/socket_test_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    constexpr int kClients = 65536;
    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    constexpr int kClients = 65536;
    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