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