github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/syscalls/linux/socket_test_util.h (about)

     1  // Copyright 2018 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  #ifndef GVISOR_TEST_SYSCALLS_SOCKET_TEST_UTIL_H_
    16  #define GVISOR_TEST_SYSCALLS_SOCKET_TEST_UTIL_H_
    17  
    18  #include <errno.h>
    19  #include <netinet/ip.h>
    20  #include <netinet/ip_icmp.h>
    21  #include <netinet/udp.h>
    22  #include <sys/socket.h>
    23  #include <sys/types.h>
    24  #include <sys/un.h>
    25  
    26  #include <functional>
    27  #include <memory>
    28  #include <string>
    29  #include <utility>
    30  #include <vector>
    31  
    32  #include "gtest/gtest.h"
    33  #include "absl/strings/str_format.h"
    34  #include "test/util/file_descriptor.h"
    35  #include "test/util/posix_error.h"
    36  #include "test/util/test_util.h"
    37  
    38  namespace gvisor {
    39  namespace testing {
    40  
    41  // Wrapper for socket(2) that returns a FileDescriptor.
    42  inline PosixErrorOr<FileDescriptor> Socket(int family, int type, int protocol) {
    43    int fd = socket(family, type, protocol);
    44    MaybeSave();
    45    if (fd < 0) {
    46      return PosixError(
    47          errno, absl::StrFormat("socket(%d, %d, %d)", family, type, protocol));
    48    }
    49    return FileDescriptor(fd);
    50  }
    51  
    52  // Wrapper for accept(2) that returns a FileDescriptor.
    53  inline PosixErrorOr<FileDescriptor> Accept(int sockfd, sockaddr* addr,
    54                                             socklen_t* addrlen) {
    55    int fd = RetryEINTR(accept)(sockfd, addr, addrlen);
    56    MaybeSave();
    57    if (fd < 0) {
    58      return PosixError(
    59          errno, absl::StrFormat("accept(%d, %p, %p)", sockfd, addr, addrlen));
    60    }
    61    return FileDescriptor(fd);
    62  }
    63  
    64  // Wrapper for accept4(2) that returns a FileDescriptor.
    65  inline PosixErrorOr<FileDescriptor> Accept4(int sockfd, sockaddr* addr,
    66                                              socklen_t* addrlen, int flags) {
    67    int fd = RetryEINTR(accept4)(sockfd, addr, addrlen, flags);
    68    MaybeSave();
    69    if (fd < 0) {
    70      return PosixError(errno, absl::StrFormat("accept4(%d, %p, %p, %#x)", sockfd,
    71                                               addr, addrlen, flags));
    72    }
    73    return FileDescriptor(fd);
    74  }
    75  
    76  inline ssize_t SendFd(int fd, void* buf, size_t count, int flags) {
    77    return internal::ApplyFileIoSyscall(
    78        [&](size_t completed) {
    79          return sendto(fd, static_cast<char*>(buf) + completed,
    80                        count - completed, flags, nullptr, 0);
    81        },
    82        count);
    83  }
    84  
    85  PosixErrorOr<struct sockaddr_un> UniqueUnixAddr(bool abstract, int domain);
    86  
    87  // A Creator<T> is a function that attempts to create and return a new T. (This
    88  // is copy/pasted from cloud/gvisor/api/sandbox_util.h and is just duplicated
    89  // here for clarity.)
    90  template <typename T>
    91  using Creator = std::function<PosixErrorOr<std::unique_ptr<T>>()>;
    92  
    93  // A SocketPair represents a pair of socket file descriptors owned by the
    94  // SocketPair.
    95  class SocketPair {
    96   public:
    97    virtual ~SocketPair() = default;
    98  
    99    virtual int first_fd() const = 0;
   100    virtual int second_fd() const = 0;
   101    virtual int release_first_fd() = 0;
   102    virtual int release_second_fd() = 0;
   103    virtual const struct sockaddr* first_addr() const = 0;
   104    virtual const struct sockaddr* second_addr() const = 0;
   105    virtual size_t first_addr_size() const = 0;
   106    virtual size_t second_addr_size() const = 0;
   107    virtual size_t first_addr_len() const = 0;
   108    virtual size_t second_addr_len() const = 0;
   109  };
   110  
   111  // A FDSocketPair is a SocketPair that consists of only a pair of file
   112  // descriptors.
   113  class FDSocketPair : public SocketPair {
   114   public:
   115    FDSocketPair(int first_fd, int second_fd)
   116        : first_(first_fd), second_(second_fd) {}
   117    FDSocketPair(std::unique_ptr<FileDescriptor> first_fd,
   118                 std::unique_ptr<FileDescriptor> second_fd)
   119        : first_(first_fd->release()), second_(second_fd->release()) {}
   120  
   121    int first_fd() const override { return first_.get(); }
   122    int second_fd() const override { return second_.get(); }
   123    int release_first_fd() override { return first_.release(); }
   124    int release_second_fd() override { return second_.release(); }
   125    const struct sockaddr* first_addr() const override { return nullptr; }
   126    const struct sockaddr* second_addr() const override { return nullptr; }
   127    size_t first_addr_size() const override { return 0; }
   128    size_t second_addr_size() const override { return 0; }
   129    size_t first_addr_len() const override { return 0; }
   130    size_t second_addr_len() const override { return 0; }
   131  
   132   private:
   133    FileDescriptor first_;
   134    FileDescriptor second_;
   135  };
   136  
   137  // CalculateUnixSockAddrLen calculates the length returned by recvfrom(2) and
   138  // recvmsg(2) for Unix sockets.
   139  size_t CalculateUnixSockAddrLen(const char* sun_path);
   140  
   141  // A AddrFDSocketPair is a SocketPair that consists of a pair of file
   142  // descriptors in addition to a pair of socket addresses.
   143  class AddrFDSocketPair : public SocketPair {
   144   public:
   145    AddrFDSocketPair(int first_fd, int second_fd,
   146                     const struct sockaddr_un& first_address,
   147                     const struct sockaddr_un& second_address)
   148        : first_(first_fd),
   149          second_(second_fd),
   150          first_addr_(to_storage(first_address)),
   151          second_addr_(to_storage(second_address)),
   152          first_len_(CalculateUnixSockAddrLen(first_address.sun_path)),
   153          second_len_(CalculateUnixSockAddrLen(second_address.sun_path)),
   154          first_size_(sizeof(first_address)),
   155          second_size_(sizeof(second_address)) {}
   156  
   157    AddrFDSocketPair(int first_fd, int second_fd,
   158                     const struct sockaddr_in& first_address,
   159                     const struct sockaddr_in& second_address)
   160        : first_(first_fd),
   161          second_(second_fd),
   162          first_addr_(to_storage(first_address)),
   163          second_addr_(to_storage(second_address)),
   164          first_len_(sizeof(first_address)),
   165          second_len_(sizeof(second_address)),
   166          first_size_(sizeof(first_address)),
   167          second_size_(sizeof(second_address)) {}
   168  
   169    AddrFDSocketPair(int first_fd, int second_fd,
   170                     const struct sockaddr_in6& first_address,
   171                     const struct sockaddr_in6& second_address)
   172        : first_(first_fd),
   173          second_(second_fd),
   174          first_addr_(to_storage(first_address)),
   175          second_addr_(to_storage(second_address)),
   176          first_len_(sizeof(first_address)),
   177          second_len_(sizeof(second_address)),
   178          first_size_(sizeof(first_address)),
   179          second_size_(sizeof(second_address)) {}
   180  
   181    int first_fd() const override { return first_.get(); }
   182    int second_fd() const override { return second_.get(); }
   183    int release_first_fd() override { return first_.release(); }
   184    int release_second_fd() override { return second_.release(); }
   185    const struct sockaddr* first_addr() const override {
   186      return reinterpret_cast<const struct sockaddr*>(&first_addr_);
   187    }
   188    const struct sockaddr* second_addr() const override {
   189      return reinterpret_cast<const struct sockaddr*>(&second_addr_);
   190    }
   191    size_t first_addr_size() const override { return first_size_; }
   192    size_t second_addr_size() const override { return second_size_; }
   193    size_t first_addr_len() const override { return first_len_; }
   194    size_t second_addr_len() const override { return second_len_; }
   195  
   196   private:
   197    // to_storage coverts a sockaddr_* to a sockaddr_storage.
   198    static struct sockaddr_storage to_storage(const sockaddr_un& addr);
   199    static struct sockaddr_storage to_storage(const sockaddr_in& addr);
   200    static struct sockaddr_storage to_storage(const sockaddr_in6& addr);
   201  
   202    FileDescriptor first_;
   203    FileDescriptor second_;
   204    const struct sockaddr_storage first_addr_;
   205    const struct sockaddr_storage second_addr_;
   206    const size_t first_len_;
   207    const size_t second_len_;
   208    const size_t first_size_;
   209    const size_t second_size_;
   210  };
   211  
   212  // SyscallSocketPairCreator returns a Creator<SocketPair> that obtains file
   213  // descriptors by invoking the socketpair() syscall.
   214  Creator<SocketPair> SyscallSocketPairCreator(int domain, int type,
   215                                               int protocol);
   216  
   217  // SyscallSocketCreator returns a Creator<FileDescriptor> that obtains a file
   218  // descriptor by invoking the socket() syscall.
   219  Creator<FileDescriptor> SyscallSocketCreator(int domain, int type,
   220                                               int protocol);
   221  
   222  // FilesystemBidirectionalBindSocketPairCreator returns a Creator<SocketPair>
   223  // that obtains file descriptors by invoking the bind() and connect() syscalls
   224  // on filesystem paths. Only works for DGRAM sockets.
   225  Creator<SocketPair> FilesystemBidirectionalBindSocketPairCreator(int domain,
   226                                                                   int type,
   227                                                                   int protocol);
   228  
   229  // AbstractBidirectionalBindSocketPairCreator returns a Creator<SocketPair> that
   230  // obtains file descriptors by invoking the bind() and connect() syscalls on
   231  // abstract namespace paths. Only works for DGRAM sockets.
   232  Creator<SocketPair> AbstractBidirectionalBindSocketPairCreator(int domain,
   233                                                                 int type,
   234                                                                 int protocol);
   235  
   236  // SocketpairGoferSocketPairCreator returns a Creator<SocketPair> that
   237  // obtains file descriptors by connect() syscalls on two sockets with socketpair
   238  // gofer paths.
   239  Creator<SocketPair> SocketpairGoferSocketPairCreator(int domain, int type,
   240                                                       int protocol);
   241  
   242  // SocketpairGoferFileSocketPairCreator returns a Creator<SocketPair> that
   243  // obtains file descriptors by open() syscalls on socketpair gofer paths.
   244  Creator<SocketPair> SocketpairGoferFileSocketPairCreator(int flags);
   245  
   246  // FilesystemAcceptBindSocketPairCreator returns a Creator<SocketPair> that
   247  // obtains file descriptors by invoking the accept() and bind() syscalls on
   248  // a filesystem path. Only works for STREAM and SEQPACKET sockets.
   249  Creator<SocketPair> FilesystemAcceptBindSocketPairCreator(int domain, int type,
   250                                                            int protocol);
   251  
   252  // AbstractAcceptBindSocketPairCreator returns a Creator<SocketPair> that
   253  // obtains file descriptors by invoking the accept() and bind() syscalls on a
   254  // abstract namespace path. Only works for STREAM and SEQPACKET sockets.
   255  Creator<SocketPair> AbstractAcceptBindSocketPairCreator(int domain, int type,
   256                                                          int protocol);
   257  
   258  // FilesystemUnboundSocketPairCreator returns a Creator<SocketPair> that obtains
   259  // file descriptors by invoking the socket() syscall and generates a filesystem
   260  // path for binding.
   261  Creator<SocketPair> FilesystemUnboundSocketPairCreator(int domain, int type,
   262                                                         int protocol);
   263  
   264  // AbstractUnboundSocketPairCreator returns a Creator<SocketPair> that obtains
   265  // file descriptors by invoking the socket() syscall and generates an abstract
   266  // path for binding.
   267  Creator<SocketPair> AbstractUnboundSocketPairCreator(int domain, int type,
   268                                                       int protocol);
   269  
   270  // TCPAcceptBindSocketPairCreator returns a Creator<SocketPair> that obtains
   271  // file descriptors by invoking the accept() and bind() syscalls on TCP sockets.
   272  Creator<SocketPair> TCPAcceptBindSocketPairCreator(int domain, int type,
   273                                                     int protocol,
   274                                                     bool dual_stack);
   275  
   276  // TCPAcceptBindPersistentListenerSocketPairCreator is like
   277  // TCPAcceptBindSocketPairCreator, except it uses the same listening socket to
   278  // create all SocketPairs.
   279  Creator<SocketPair> TCPAcceptBindPersistentListenerSocketPairCreator(
   280      int domain, int type, int protocol, bool dual_stack);
   281  
   282  // UDPBidirectionalBindSocketPairCreator returns a Creator<SocketPair> that
   283  // obtains file descriptors by invoking the bind() and connect() syscalls on UDP
   284  // sockets.
   285  Creator<SocketPair> UDPBidirectionalBindSocketPairCreator(int domain, int type,
   286                                                            int protocol,
   287                                                            bool dual_stack);
   288  
   289  // UDPUnboundSocketPairCreator returns a Creator<SocketPair> that obtains file
   290  // descriptors by creating UDP sockets.
   291  Creator<SocketPair> UDPUnboundSocketPairCreator(int domain, int type,
   292                                                  int protocol, bool dual_stack);
   293  
   294  // UnboundSocketCreator returns a Creator<FileDescriptor> that obtains a file
   295  // descriptor by creating a socket.
   296  Creator<FileDescriptor> UnboundSocketCreator(int domain, int type,
   297                                               int protocol);
   298  
   299  // A SocketPairKind couples a human-readable description of a socket pair with
   300  // a function that creates such a socket pair.
   301  struct SocketPairKind {
   302    std::string description;
   303    int domain;
   304    int type;
   305    int protocol;
   306    Creator<SocketPair> creator;
   307  
   308    // Create creates a socket pair of this kind.
   309    PosixErrorOr<std::unique_ptr<SocketPair>> Create() const { return creator(); }
   310  };
   311  
   312  // A SocketKind couples a human-readable description of a socket with
   313  // a function that creates such a socket.
   314  struct SocketKind {
   315    std::string description;
   316    int domain;
   317    int type;
   318    int protocol;
   319    Creator<FileDescriptor> creator;
   320  
   321    // Create creates a socket pair of this kind.
   322    PosixErrorOr<std::unique_ptr<FileDescriptor>> Create() const {
   323      return creator();
   324    }
   325  };
   326  
   327  // A ReversedSocketPair wraps another SocketPair but flips the first and second
   328  // file descriptors. ReversedSocketPair is used to test socket pairs that
   329  // should be symmetric.
   330  class ReversedSocketPair : public SocketPair {
   331   public:
   332    explicit ReversedSocketPair(std::unique_ptr<SocketPair> base)
   333        : base_(std::move(base)) {}
   334  
   335    int first_fd() const override { return base_->second_fd(); }
   336    int second_fd() const override { return base_->first_fd(); }
   337    int release_first_fd() override { return base_->release_second_fd(); }
   338    int release_second_fd() override { return base_->release_first_fd(); }
   339    const struct sockaddr* first_addr() const override {
   340      return base_->second_addr();
   341    }
   342    const struct sockaddr* second_addr() const override {
   343      return base_->first_addr();
   344    }
   345    size_t first_addr_size() const override { return base_->second_addr_size(); }
   346    size_t second_addr_size() const override { return base_->first_addr_size(); }
   347    size_t first_addr_len() const override { return base_->second_addr_len(); }
   348    size_t second_addr_len() const override { return base_->first_addr_len(); }
   349  
   350   private:
   351    std::unique_ptr<SocketPair> base_;
   352  };
   353  
   354  // Reversed returns a SocketPairKind that represents SocketPairs created by
   355  // flipping the file descriptors provided by another SocketPair.
   356  SocketPairKind Reversed(SocketPairKind const& base);
   357  
   358  // IncludeReversals returns a vector<SocketPairKind> that returns all
   359  // SocketPairKinds in `vec` as well as all SocketPairKinds obtained by flipping
   360  // the file descriptors provided by the kinds in `vec`.
   361  std::vector<SocketPairKind> IncludeReversals(std::vector<SocketPairKind> vec);
   362  
   363  // A Middleware is a function wraps a SocketPairKind.
   364  using Middleware = std::function<SocketPairKind(SocketPairKind)>;
   365  
   366  // Reversed returns a SocketPairKind that represents SocketPairs created by
   367  // flipping the file descriptors provided by another SocketPair.
   368  template <typename T>
   369  Middleware SetSockOpt(int level, int optname, T* value) {
   370    return [=](SocketPairKind const& base) {
   371      auto const& creator = base.creator;
   372      return SocketPairKind{
   373          absl::StrCat("setsockopt(", level, ", ", optname, ", ", *value, ") ",
   374                       base.description),
   375          base.domain, base.type, base.protocol,
   376          [creator, level, optname,
   377           value]() -> PosixErrorOr<std::unique_ptr<SocketPair>> {
   378            ASSIGN_OR_RETURN_ERRNO(auto creator_value, creator());
   379            if (creator_value->first_fd() >= 0) {
   380              RETURN_ERROR_IF_SYSCALL_FAIL(setsockopt(
   381                  creator_value->first_fd(), level, optname, value, sizeof(T)));
   382            }
   383            if (creator_value->second_fd() >= 0) {
   384              RETURN_ERROR_IF_SYSCALL_FAIL(setsockopt(
   385                  creator_value->second_fd(), level, optname, value, sizeof(T)));
   386            }
   387            return creator_value;
   388          }};
   389    };
   390  }
   391  
   392  constexpr int kSockOptOn = 1;
   393  constexpr int kSockOptOff = 0;
   394  
   395  // NoOp returns the same SocketPairKind that it is passed.
   396  SocketPairKind NoOp(SocketPairKind const& base);
   397  
   398  // TransferTest tests that data can be send back and fourth between two
   399  // specified FDs. Note that calls to this function should be wrapped in
   400  // ASSERT_NO_FATAL_FAILURE().
   401  void TransferTest(int fd1, int fd2);
   402  
   403  // Fills [buf, buf+len) with random bytes.
   404  void RandomizeBuffer(char* buf, size_t len);
   405  
   406  // Base test fixture for tests that operate on pairs of connected sockets.
   407  class SocketPairTest : public ::testing::TestWithParam<SocketPairKind> {
   408   protected:
   409    SocketPairTest() {
   410      // gUnit uses printf, so so will we.
   411      printf("Testing with %s\n", GetParam().description.c_str());
   412      fflush(stdout);
   413    }
   414  
   415    PosixErrorOr<std::unique_ptr<SocketPair>> NewSocketPair() const {
   416      return GetParam().Create();
   417    }
   418  };
   419  
   420  // Base test fixture for tests that operate on simple Sockets.
   421  class SimpleSocketTest : public ::testing::TestWithParam<SocketKind> {
   422   protected:
   423    SimpleSocketTest() {
   424      // gUnit uses printf, so so will we.
   425      printf("Testing with %s\n", GetParam().description.c_str());
   426    }
   427  
   428    PosixErrorOr<std::unique_ptr<FileDescriptor>> NewSocket() const {
   429      return GetParam().Create();
   430    }
   431  };
   432  
   433  SocketKind SimpleSocket(int fam, int type, int proto);
   434  
   435  // Send a buffer of size 'size' to sockets->first_fd(), returning the result of
   436  // sendmsg.
   437  //
   438  // If reader, read from second_fd() until size bytes have been read.
   439  ssize_t SendLargeSendMsg(const std::unique_ptr<SocketPair>& sockets,
   440                           size_t size, bool reader);
   441  
   442  // Initializes the given buffer with random data.
   443  void RandomizeBuffer(char* ptr, size_t len);
   444  
   445  enum class AddressFamily { kIpv4 = 1, kIpv6 = 2, kDualStack = 3 };
   446  enum class SocketType { kUdp = 1, kTcp = 2 };
   447  
   448  // Returns a PosixError or a port that is available. If 0 is specified as the
   449  // port it will bind port 0 (and allow the kernel to select any free port).
   450  // Otherwise, it will try to bind the specified port and validate that it can be
   451  // used for the requested family and socket type. The final option is
   452  // reuse_addr. This specifies whether SO_REUSEADDR should be applied before a
   453  // bind(2) attempt. SO_REUSEADDR means that sockets in TIME_WAIT states or other
   454  // bound UDP sockets would not cause an error on bind(2). This option should be
   455  // set if subsequent calls to bind on the returned port will also use
   456  // SO_REUSEADDR.
   457  //
   458  // Note: That this test will attempt to bind the ANY address for the respective
   459  // protocol.
   460  PosixErrorOr<int> PortAvailable(int port, AddressFamily family, SocketType type,
   461                                  bool reuse_addr);
   462  
   463  // FreeAvailablePort is used to return a port that was obtained by using
   464  // the PortAvailable helper with port 0.
   465  PosixError FreeAvailablePort(int port);
   466  
   467  // SendMsg converts a buffer to an iovec and adds it to msg before sending it.
   468  PosixErrorOr<int> SendMsg(int sock, msghdr* msg, char buf[], int buf_size);
   469  
   470  // RecvTimeout calls select on sock with timeout and then calls recv on sock.
   471  PosixErrorOr<int> RecvTimeout(int sock, char buf[], int buf_size, int timeout);
   472  
   473  // RecvMsgTimeout calls select on sock with timeout and then calls recvmsg on
   474  // sock.
   475  PosixErrorOr<int> RecvMsgTimeout(int sock, msghdr* msg, int timeout);
   476  
   477  // RecvNoData checks that no data is receivable on sock.
   478  void RecvNoData(int sock);
   479  
   480  // Base test fixture for tests that apply to all kinds of pairs of connected
   481  // sockets.
   482  using AllSocketPairTest = SocketPairTest;
   483  
   484  struct TestAddress {
   485    std::string description;
   486    sockaddr_storage addr;
   487    socklen_t addr_len;
   488  
   489    explicit TestAddress(std::string description = "")
   490        : description(std::move(description)), addr(), addr_len() {}
   491  
   492    int family() const { return addr.ss_family; }
   493  
   494    // Returns a new TestAddress with specified port. If port is not supported,
   495    // the same TestAddress is returned.
   496    TestAddress WithPort(uint16_t port) const;
   497  };
   498  
   499  constexpr char kMulticastAddress[] = "224.0.2.1";
   500  constexpr char kBroadcastAddress[] = "255.255.255.255";
   501  
   502  // Returns a TestAddress with `addr` parsed as an IPv4 address described by
   503  // `description`.
   504  TestAddress V4AddrStr(std::string description, const char* addr);
   505  // Returns a TestAddress with `addr` parsed as an IPv6 address described by
   506  // `description`.
   507  TestAddress V6AddrStr(std::string description, const char* addr);
   508  
   509  // Returns a TestAddress for the IPv4 any address.
   510  TestAddress V4Any();
   511  // Returns a TestAddress for the IPv4 limited broadcast address.
   512  TestAddress V4Broadcast();
   513  // Returns a TestAddress for the IPv4 loopback address.
   514  TestAddress V4Loopback();
   515  // Returns a TestAddress for the subnet broadcast of the IPv4 loopback address.
   516  TestAddress V4LoopbackSubnetBroadcast();
   517  // Returns a TestAddress for the IPv4-mapped IPv6 any address.
   518  TestAddress V4MappedAny();
   519  // Returns a TestAddress for the IPv4-mapped IPv6 loopback address.
   520  TestAddress V4MappedLoopback();
   521  // Returns a TestAddress for a IPv4 multicast address.
   522  TestAddress V4Multicast();
   523  // Returns a TestAddress for the IPv4 all-hosts multicast group address.
   524  TestAddress V4MulticastAllHosts();
   525  
   526  // Returns a TestAddress for the IPv6 any address.
   527  TestAddress V6Any();
   528  // Returns a TestAddress for the IPv6 loopback address.
   529  TestAddress V6Loopback();
   530  // Returns a TestAddress for a IPv6 multicast address.
   531  TestAddress V6Multicast();
   532  // Returns a TestAddress for the IPv6 interface-local all-nodes multicast group
   533  // address.
   534  TestAddress V6MulticastInterfaceLocalAllNodes();
   535  // Returns a TestAddress for the IPv6 link-local all-nodes multicast group
   536  // address.
   537  TestAddress V6MulticastLinkLocalAllNodes();
   538  // Returns a TestAddress for the IPv6 link-local all-routers multicast group
   539  // address.
   540  TestAddress V6MulticastLinkLocalAllRouters();
   541  
   542  // Compute the internet checksum of an IP header.
   543  uint16_t IPChecksum(struct iphdr ip);
   544  
   545  // Compute the internet checksum of a UDP header.
   546  uint16_t UDPChecksum(struct iphdr iphdr, struct udphdr udphdr,
   547                       const char* payload, ssize_t payload_len);
   548  
   549  // Compute the internet checksum of an ICMP header.
   550  uint16_t ICMPChecksum(struct icmphdr icmphdr, const char* payload,
   551                        ssize_t payload_len);
   552  
   553  // Convenient functions for reinterpreting common types to sockaddr pointer.
   554  inline sockaddr* AsSockAddr(sockaddr_storage* s) {
   555    return reinterpret_cast<sockaddr*>(s);
   556  }
   557  inline sockaddr* AsSockAddr(sockaddr_in* s) {
   558    return reinterpret_cast<sockaddr*>(s);
   559  }
   560  inline sockaddr* AsSockAddr(sockaddr_in6* s) {
   561    return reinterpret_cast<sockaddr*>(s);
   562  }
   563  inline sockaddr* AsSockAddr(sockaddr_un* s) {
   564    return reinterpret_cast<sockaddr*>(s);
   565  }
   566  
   567  PosixErrorOr<uint16_t> AddrPort(int family, sockaddr_storage const& addr);
   568  
   569  PosixError SetAddrPort(int family, sockaddr_storage* addr, uint16_t port);
   570  
   571  // setupTimeWaitClose sets up a socket endpoint in TIME_WAIT state.
   572  // Callers can choose to perform active close on either ends of the connection
   573  // and also specify if they want to enabled SO_REUSEADDR.
   574  void SetupTimeWaitClose(const TestAddress* listener,
   575                          const TestAddress* connector, bool reuse,
   576                          bool accept_close, sockaddr_storage* listen_addr,
   577                          sockaddr_storage* conn_bound_addr);
   578  
   579  // MaybeLimitEphemeralPorts attempts to reduce the number of ephemeral ports and
   580  // returns the number of ephemeral ports.
   581  PosixErrorOr<int> MaybeLimitEphemeralPorts();
   582  
   583  namespace internal {
   584  PosixErrorOr<int> TryPortAvailable(int port, AddressFamily family,
   585                                     SocketType type, bool reuse_addr);
   586  }  // namespace internal
   587  
   588  }  // namespace testing
   589  }  // namespace gvisor
   590  
   591  #endif  // GVISOR_TEST_SYSCALLS_SOCKET_TEST_UTIL_H_