gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/syscalls/linux/socket_ip_udp_generic.cc (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  #include "test/syscalls/linux/socket_ip_udp_generic.h"
    16  
    17  #include <errno.h>
    18  #ifdef __linux__
    19  #include <linux/errqueue.h>
    20  #include <linux/in6.h>
    21  #endif  // __linux__
    22  #include <netinet/in.h>
    23  #include <netinet/tcp.h>
    24  #include <poll.h>
    25  #include <stdio.h>
    26  #include <sys/ioctl.h>
    27  #include <sys/socket.h>
    28  #include <sys/types.h>
    29  #include <sys/un.h>
    30  
    31  #include "gtest/gtest.h"
    32  #include "test/util/socket_util.h"
    33  #include "test/util/test_util.h"
    34  
    35  namespace gvisor {
    36  namespace testing {
    37  
    38  TEST_P(UDPSocketPairTest, MulticastTTLDefault) {
    39    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    40  
    41    int get = -1;
    42    socklen_t get_len = sizeof(get);
    43    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
    44                           &get, &get_len),
    45                SyscallSucceedsWithValue(0));
    46    EXPECT_EQ(get_len, sizeof(get));
    47    EXPECT_EQ(get, 1);
    48  }
    49  
    50  TEST_P(UDPSocketPairTest, SetUDPMulticastTTLMin) {
    51    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    52  
    53    constexpr int kMin = 0;
    54    EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
    55                           &kMin, sizeof(kMin)),
    56                SyscallSucceeds());
    57  
    58    int get = -1;
    59    socklen_t get_len = sizeof(get);
    60    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
    61                           &get, &get_len),
    62                SyscallSucceedsWithValue(0));
    63    EXPECT_EQ(get_len, sizeof(get));
    64    EXPECT_EQ(get, kMin);
    65  }
    66  
    67  TEST_P(UDPSocketPairTest, SetUDPMulticastTTLMax) {
    68    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    69  
    70    constexpr int kMax = 255;
    71    EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
    72                           &kMax, sizeof(kMax)),
    73                SyscallSucceeds());
    74  
    75    int get = -1;
    76    socklen_t get_len = sizeof(get);
    77    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
    78                           &get, &get_len),
    79                SyscallSucceedsWithValue(0));
    80    EXPECT_EQ(get_len, sizeof(get));
    81    EXPECT_EQ(get, kMax);
    82  }
    83  
    84  TEST_P(UDPSocketPairTest, SetUDPMulticastTTLNegativeOne) {
    85    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    86  
    87    constexpr int kArbitrary = 6;
    88    EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
    89                           &kArbitrary, sizeof(kArbitrary)),
    90                SyscallSucceeds());
    91  
    92    constexpr int kNegOne = -1;
    93    EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
    94                           &kNegOne, sizeof(kNegOne)),
    95                SyscallSucceeds());
    96  
    97    int get = -1;
    98    socklen_t get_len = sizeof(get);
    99    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
   100                           &get, &get_len),
   101                SyscallSucceedsWithValue(0));
   102    EXPECT_EQ(get_len, sizeof(get));
   103    EXPECT_EQ(get, 1);
   104  }
   105  
   106  TEST_P(UDPSocketPairTest, SetUDPMulticastTTLBelowMin) {
   107    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   108  
   109    constexpr int kBelowMin = -2;
   110    EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
   111                           &kBelowMin, sizeof(kBelowMin)),
   112                SyscallFailsWithErrno(EINVAL));
   113  }
   114  
   115  TEST_P(UDPSocketPairTest, SetUDPMulticastTTLAboveMax) {
   116    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   117  
   118    constexpr int kAboveMax = 256;
   119    EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
   120                           &kAboveMax, sizeof(kAboveMax)),
   121                SyscallFailsWithErrno(EINVAL));
   122  }
   123  
   124  TEST_P(UDPSocketPairTest, SetUDPMulticastTTLChar) {
   125    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   126  
   127    constexpr char kArbitrary = 6;
   128    EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
   129                           &kArbitrary, sizeof(kArbitrary)),
   130                SyscallSucceeds());
   131  
   132    int get = -1;
   133    socklen_t get_len = sizeof(get);
   134    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
   135                           &get, &get_len),
   136                SyscallSucceedsWithValue(0));
   137    EXPECT_EQ(get_len, sizeof(get));
   138    EXPECT_EQ(get, kArbitrary);
   139  }
   140  
   141  TEST_P(UDPSocketPairTest, SetEmptyIPAddMembership) {
   142    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   143  
   144    struct ip_mreqn req = {};
   145    EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP,
   146                           &req, sizeof(req)),
   147                SyscallFailsWithErrno(EINVAL));
   148  }
   149  
   150  TEST_P(UDPSocketPairTest, MulticastLoopDefault) {
   151    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   152  
   153    int get = -1;
   154    socklen_t get_len = sizeof(get);
   155    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP,
   156                           &get, &get_len),
   157                SyscallSucceedsWithValue(0));
   158    EXPECT_EQ(get_len, sizeof(get));
   159    EXPECT_EQ(get, kSockOptOn);
   160  }
   161  
   162  TEST_P(UDPSocketPairTest, SetMulticastLoop) {
   163    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   164  
   165    ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP,
   166                           &kSockOptOff, sizeof(kSockOptOff)),
   167                SyscallSucceeds());
   168  
   169    int get = -1;
   170    socklen_t get_len = sizeof(get);
   171    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP,
   172                           &get, &get_len),
   173                SyscallSucceedsWithValue(0));
   174    EXPECT_EQ(get_len, sizeof(get));
   175    EXPECT_EQ(get, kSockOptOff);
   176  
   177    ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP,
   178                           &kSockOptOn, sizeof(kSockOptOn)),
   179                SyscallSucceeds());
   180  
   181    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP,
   182                           &get, &get_len),
   183                SyscallSucceedsWithValue(0));
   184    EXPECT_EQ(get_len, sizeof(get));
   185    EXPECT_EQ(get, kSockOptOn);
   186  }
   187  
   188  TEST_P(UDPSocketPairTest, SetMulticastLoopChar) {
   189    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   190  
   191    constexpr char kSockOptOnChar = kSockOptOn;
   192    constexpr char kSockOptOffChar = kSockOptOff;
   193  
   194    ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP,
   195                           &kSockOptOffChar, sizeof(kSockOptOffChar)),
   196                SyscallSucceeds());
   197  
   198    int get = -1;
   199    socklen_t get_len = sizeof(get);
   200    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP,
   201                           &get, &get_len),
   202                SyscallSucceedsWithValue(0));
   203    EXPECT_EQ(get_len, sizeof(get));
   204    EXPECT_EQ(get, kSockOptOff);
   205  
   206    ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP,
   207                           &kSockOptOnChar, sizeof(kSockOptOnChar)),
   208                SyscallSucceeds());
   209  
   210    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP,
   211                           &get, &get_len),
   212                SyscallSucceedsWithValue(0));
   213    EXPECT_EQ(get_len, sizeof(get));
   214    EXPECT_EQ(get, kSockOptOn);
   215  }
   216  
   217  TEST_P(UDPSocketPairTest, ReuseAddrDefault) {
   218    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   219  
   220    int get = -1;
   221    socklen_t get_len = sizeof(get);
   222    ASSERT_THAT(
   223        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, &get, &get_len),
   224        SyscallSucceedsWithValue(0));
   225    EXPECT_EQ(get_len, sizeof(get));
   226    EXPECT_EQ(get, kSockOptOff);
   227  }
   228  
   229  TEST_P(UDPSocketPairTest, SetReuseAddr) {
   230    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   231  
   232    ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR,
   233                           &kSockOptOn, sizeof(kSockOptOn)),
   234                SyscallSucceeds());
   235  
   236    int get = -1;
   237    socklen_t get_len = sizeof(get);
   238    ASSERT_THAT(
   239        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, &get, &get_len),
   240        SyscallSucceedsWithValue(0));
   241    EXPECT_EQ(get_len, sizeof(get));
   242    EXPECT_EQ(get, kSockOptOn);
   243  
   244    ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR,
   245                           &kSockOptOff, sizeof(kSockOptOff)),
   246                SyscallSucceeds());
   247  
   248    ASSERT_THAT(
   249        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, &get, &get_len),
   250        SyscallSucceedsWithValue(0));
   251    EXPECT_EQ(get_len, sizeof(get));
   252    EXPECT_EQ(get, kSockOptOff);
   253  }
   254  
   255  TEST_P(UDPSocketPairTest, ReusePortDefault) {
   256    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   257  
   258    int get = -1;
   259    socklen_t get_len = sizeof(get);
   260    ASSERT_THAT(
   261        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, &get, &get_len),
   262        SyscallSucceedsWithValue(0));
   263    EXPECT_EQ(get_len, sizeof(get));
   264    EXPECT_EQ(get, kSockOptOff);
   265  }
   266  
   267  TEST_P(UDPSocketPairTest, SetReusePort) {
   268    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   269  
   270    ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT,
   271                           &kSockOptOn, sizeof(kSockOptOn)),
   272                SyscallSucceeds());
   273  
   274    int get = -1;
   275    socklen_t get_len = sizeof(get);
   276    ASSERT_THAT(
   277        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, &get, &get_len),
   278        SyscallSucceedsWithValue(0));
   279    EXPECT_EQ(get_len, sizeof(get));
   280    EXPECT_EQ(get, kSockOptOn);
   281  
   282    ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT,
   283                           &kSockOptOff, sizeof(kSockOptOff)),
   284                SyscallSucceeds());
   285  
   286    ASSERT_THAT(
   287        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, &get, &get_len),
   288        SyscallSucceedsWithValue(0));
   289    EXPECT_EQ(get_len, sizeof(get));
   290    EXPECT_EQ(get, kSockOptOff);
   291  }
   292  
   293  TEST_P(UDPSocketPairTest, SetReuseAddrReusePort) {
   294    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   295  
   296    ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR,
   297                           &kSockOptOn, sizeof(kSockOptOn)),
   298                SyscallSucceeds());
   299  
   300    ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT,
   301                           &kSockOptOn, sizeof(kSockOptOn)),
   302                SyscallSucceeds());
   303  
   304    int get = -1;
   305    socklen_t get_len = sizeof(get);
   306    ASSERT_THAT(
   307        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, &get, &get_len),
   308        SyscallSucceedsWithValue(0));
   309    EXPECT_EQ(get_len, sizeof(get));
   310    EXPECT_EQ(get, kSockOptOn);
   311  
   312    ASSERT_THAT(
   313        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, &get, &get_len),
   314        SyscallSucceedsWithValue(0));
   315    EXPECT_EQ(get_len, sizeof(get));
   316    EXPECT_EQ(get, kSockOptOn);
   317  }
   318  
   319  // Test getsockopt for a socket which is not set with IP_PKTINFO option.
   320  TEST_P(UDPSocketPairTest, IPPKTINFODefault) {
   321    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   322  
   323    int get = -1;
   324    socklen_t get_len = sizeof(get);
   325  
   326    ASSERT_THAT(
   327        getsockopt(sockets->first_fd(), SOL_IP, IP_PKTINFO, &get, &get_len),
   328        SyscallSucceedsWithValue(0));
   329    EXPECT_EQ(get_len, sizeof(get));
   330    EXPECT_EQ(get, kSockOptOff);
   331  }
   332  
   333  // Test setsockopt and getsockopt for a socket with IP_PKTINFO option.
   334  TEST_P(UDPSocketPairTest, SetAndGetIPPKTINFO) {
   335    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   336  
   337    int level = SOL_IP;
   338    int type = IP_PKTINFO;
   339  
   340    // Check getsockopt before IP_PKTINFO is set.
   341    int get = -1;
   342    socklen_t get_len = sizeof(get);
   343  
   344    ASSERT_THAT(setsockopt(sockets->first_fd(), level, type, &kSockOptOn,
   345                           sizeof(kSockOptOn)),
   346                SyscallSucceedsWithValue(0));
   347  
   348    ASSERT_THAT(getsockopt(sockets->first_fd(), level, type, &get, &get_len),
   349                SyscallSucceedsWithValue(0));
   350    EXPECT_EQ(get, kSockOptOn);
   351    EXPECT_EQ(get_len, sizeof(get));
   352  
   353    ASSERT_THAT(setsockopt(sockets->first_fd(), level, type, &kSockOptOff,
   354                           sizeof(kSockOptOff)),
   355                SyscallSucceedsWithValue(0));
   356  
   357    ASSERT_THAT(getsockopt(sockets->first_fd(), level, type, &get, &get_len),
   358                SyscallSucceedsWithValue(0));
   359    EXPECT_EQ(get, kSockOptOff);
   360    EXPECT_EQ(get_len, sizeof(get));
   361  }
   362  
   363  // Test getsockopt for a socket which is not set with IP_RECVORIGDSTADDR option.
   364  TEST_P(UDPSocketPairTest, ReceiveOrigDstAddrDefault) {
   365    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   366  
   367    int get = -1;
   368    socklen_t get_len = sizeof(get);
   369    int level = SOL_IP;
   370    int type = IP_RECVORIGDSTADDR;
   371    if (sockets->first_addr()->sa_family == AF_INET6) {
   372      level = SOL_IPV6;
   373      type = IPV6_RECVORIGDSTADDR;
   374    }
   375    ASSERT_THAT(getsockopt(sockets->first_fd(), level, type, &get, &get_len),
   376                SyscallSucceedsWithValue(0));
   377    EXPECT_EQ(get_len, sizeof(get));
   378    EXPECT_EQ(get, kSockOptOff);
   379  }
   380  
   381  // Test setsockopt and getsockopt for a socket with IP_RECVORIGDSTADDR option.
   382  TEST_P(UDPSocketPairTest, SetAndGetReceiveOrigDstAddr) {
   383    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   384  
   385    int level = SOL_IP;
   386    int type = IP_RECVORIGDSTADDR;
   387    if (sockets->first_addr()->sa_family == AF_INET6) {
   388      level = SOL_IPV6;
   389      type = IPV6_RECVORIGDSTADDR;
   390    }
   391  
   392    // Check getsockopt before IP_PKTINFO is set.
   393    int get = -1;
   394    socklen_t get_len = sizeof(get);
   395  
   396    ASSERT_THAT(setsockopt(sockets->first_fd(), level, type, &kSockOptOn,
   397                           sizeof(kSockOptOn)),
   398                SyscallSucceedsWithValue(0));
   399  
   400    ASSERT_THAT(getsockopt(sockets->first_fd(), level, type, &get, &get_len),
   401                SyscallSucceedsWithValue(0));
   402    EXPECT_EQ(get, kSockOptOn);
   403    EXPECT_EQ(get_len, sizeof(get));
   404  
   405    ASSERT_THAT(setsockopt(sockets->first_fd(), level, type, &kSockOptOff,
   406                           sizeof(kSockOptOff)),
   407                SyscallSucceedsWithValue(0));
   408  
   409    ASSERT_THAT(getsockopt(sockets->first_fd(), level, type, &get, &get_len),
   410                SyscallSucceedsWithValue(0));
   411    EXPECT_EQ(get, kSockOptOff);
   412    EXPECT_EQ(get_len, sizeof(get));
   413  }
   414  
   415  // Holds TOS or TClass information for IPv4 or IPv6 respectively.
   416  struct RecvTosOption {
   417    int level;
   418    int option;
   419  };
   420  
   421  RecvTosOption GetRecvTosOption(int domain) {
   422    TEST_CHECK(domain == AF_INET || domain == AF_INET6);
   423    RecvTosOption opt;
   424    switch (domain) {
   425      case AF_INET:
   426        opt.level = IPPROTO_IP;
   427        opt.option = IP_RECVTOS;
   428        break;
   429      case AF_INET6:
   430        opt.level = IPPROTO_IPV6;
   431        opt.option = IPV6_RECVTCLASS;
   432        break;
   433    }
   434    return opt;
   435  }
   436  
   437  // Ensure that Receiving TOS or TCLASS is off by default.
   438  TEST_P(UDPSocketPairTest, RecvTosDefault) {
   439    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   440    RecvTosOption t = GetRecvTosOption(GetParam().domain);
   441    int get = -1;
   442    socklen_t get_len = sizeof(get);
   443    ASSERT_THAT(
   444        getsockopt(sockets->first_fd(), t.level, t.option, &get, &get_len),
   445        SyscallSucceedsWithValue(0));
   446    EXPECT_EQ(get_len, sizeof(get));
   447    EXPECT_EQ(get, kSockOptOff);
   448  }
   449  
   450  // Test that setting and getting IP_RECVTOS or IPV6_RECVTCLASS works as
   451  // expected.
   452  TEST_P(UDPSocketPairTest, SetRecvTos) {
   453    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   454    RecvTosOption t = GetRecvTosOption(GetParam().domain);
   455  
   456    ASSERT_THAT(setsockopt(sockets->first_fd(), t.level, t.option, &kSockOptOff,
   457                           sizeof(kSockOptOff)),
   458                SyscallSucceeds());
   459  
   460    int get = -1;
   461    socklen_t get_len = sizeof(get);
   462    ASSERT_THAT(
   463        getsockopt(sockets->first_fd(), t.level, t.option, &get, &get_len),
   464        SyscallSucceedsWithValue(0));
   465    EXPECT_EQ(get_len, sizeof(get));
   466    EXPECT_EQ(get, kSockOptOff);
   467  
   468    ASSERT_THAT(setsockopt(sockets->first_fd(), t.level, t.option, &kSockOptOn,
   469                           sizeof(kSockOptOn)),
   470                SyscallSucceeds());
   471  
   472    ASSERT_THAT(
   473        getsockopt(sockets->first_fd(), t.level, t.option, &get, &get_len),
   474        SyscallSucceedsWithValue(0));
   475    EXPECT_EQ(get_len, sizeof(get));
   476    EXPECT_EQ(get, kSockOptOn);
   477  }
   478  
   479  // Test that any socket (including IPv6 only) accepts the IPv4 TOS option: this
   480  // mirrors behavior in linux.
   481  TEST_P(UDPSocketPairTest, TOSRecvMismatch) {
   482    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   483    RecvTosOption t = GetRecvTosOption(AF_INET);
   484    int get = -1;
   485    socklen_t get_len = sizeof(get);
   486  
   487    ASSERT_THAT(
   488        getsockopt(sockets->first_fd(), t.level, t.option, &get, &get_len),
   489        SyscallSucceedsWithValue(0));
   490  }
   491  
   492  // Test that an IPv4 socket does not support the IPv6 TClass option.
   493  TEST_P(UDPSocketPairTest, TClassRecvMismatch) {
   494    // This should only test AF_INET6 sockets for the mismatch behavior.
   495    SKIP_IF(GetParam().domain != AF_INET6);
   496    // IPV6_RECVTCLASS is only valid for SOCK_DGRAM and SOCK_RAW.
   497    SKIP_IF((GetParam().type != SOCK_DGRAM) || (GetParam().type != SOCK_RAW));
   498  
   499    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   500  
   501    int get = -1;
   502    socklen_t get_len = sizeof(get);
   503  
   504    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IPV6, IPV6_RECVTCLASS,
   505                           &get, &get_len),
   506                SyscallFailsWithErrno(EOPNOTSUPP));
   507  }
   508  
   509  // Test the SO_LINGER option can be set/get on udp socket.
   510  TEST_P(UDPSocketPairTest, SetAndGetSocketLinger) {
   511    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   512    int level = SOL_SOCKET;
   513    int type = SO_LINGER;
   514  
   515    struct linger sl;
   516    sl.l_onoff = 1;
   517    sl.l_linger = 5;
   518    ASSERT_THAT(setsockopt(sockets->first_fd(), level, type, &sl, sizeof(sl)),
   519                SyscallSucceedsWithValue(0));
   520  
   521    struct linger got_linger = {};
   522    socklen_t length = sizeof(sl);
   523    ASSERT_THAT(
   524        getsockopt(sockets->first_fd(), level, type, &got_linger, &length),
   525        SyscallSucceedsWithValue(0));
   526  
   527    ASSERT_EQ(length, sizeof(got_linger));
   528    EXPECT_EQ(0, memcmp(&sl, &got_linger, length));
   529  }
   530  
   531  // Test getsockopt for SO_ACCEPTCONN on udp socket.
   532  TEST_P(UDPSocketPairTest, GetSocketAcceptConn) {
   533    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   534  
   535    int got = -1;
   536    socklen_t length = sizeof(got);
   537    ASSERT_THAT(
   538        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_ACCEPTCONN, &got, &length),
   539        SyscallSucceedsWithValue(0));
   540  
   541    ASSERT_EQ(length, sizeof(got));
   542    EXPECT_EQ(got, 0);
   543  }
   544  
   545  #ifdef __linux__
   546  TEST_P(UDPSocketPairTest, PayloadTooBig) {
   547    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   548  
   549    // Set IP_RECVERR socket option to enable error queueing.
   550    int v = kSockOptOn;
   551    socklen_t optlen = sizeof(v);
   552    int opt_level = SOL_IP;
   553    int opt_type = IP_RECVERR;
   554    if (sockets->first_addr()->sa_family == AF_INET6) {
   555      opt_level = SOL_IPV6;
   556      opt_type = IPV6_RECVERR;
   557    }
   558    ASSERT_THAT(setsockopt(sockets->first_fd(), opt_level, opt_type, &v, optlen),
   559                SyscallSucceeds());
   560  
   561    // Buffers bigger than 0xffff should receive an error.
   562    const int kBufLen = 0x10000;
   563    char buf[kBufLen];
   564    RandomizeBuffer(buf, sizeof(buf));
   565  
   566    EXPECT_THAT(send(sockets->first_fd(), buf, sizeof(buf), 0),
   567                SyscallFailsWithErrno(EMSGSIZE));
   568  
   569    // Dequeue error using recvmsg(MSG_ERRQUEUE). Give a buffer big-enough for
   570    // the original message just in case.
   571    char got[kBufLen];
   572    struct iovec iov;
   573    iov.iov_base = reinterpret_cast<void*>(got);
   574    iov.iov_len = kBufLen;
   575  
   576    const int addrlen_ = sockets->second_addr_size();
   577    size_t control_buf_len = CMSG_SPACE(sizeof(sock_extended_err) + addrlen_);
   578    std::vector<char> control_buf(control_buf_len);
   579    struct sockaddr_storage remote;
   580    memset(&remote, 0, sizeof(remote));
   581    struct msghdr msg = {};
   582    msg.msg_iov = &iov;
   583    msg.msg_iovlen = 1;
   584    msg.msg_flags = 0;
   585    msg.msg_control = control_buf.data();
   586    msg.msg_controllen = control_buf_len;
   587    msg.msg_name = reinterpret_cast<void*>(&remote);
   588    msg.msg_namelen = addrlen_;
   589  
   590    struct sockaddr_storage addr;
   591    optlen = sizeof(addr);
   592    EXPECT_THAT(getpeername(sockets->first_fd(), AsSockAddr(&addr), &optlen),
   593                SyscallSucceeds());
   594    bool ipv6 = false;
   595    if (addr.ss_family == AF_INET6) {
   596      auto ipv6addr = reinterpret_cast<struct sockaddr_in6*>(&addr);
   597  
   598      // Exclude IPv4-mapped addresses.
   599      uint8_t v4MappedPrefix[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   600                                    0x00, 0x00, 0x00, 0x00, 0xff, 0xff};
   601      ipv6 = memcmp(&ipv6addr->sin6_addr.s6_addr[0], v4MappedPrefix,
   602                    sizeof(v4MappedPrefix)) != 0;
   603    }
   604    // Native behaviour for IPv4 packets is to not report to ERRQUEUE.
   605    if (!ipv6) {
   606      EXPECT_THAT(recvmsg(sockets->first_fd(), &msg, MSG_ERRQUEUE),
   607                  SyscallFailsWithErrno(EAGAIN));
   608      return;
   609    }
   610  
   611    ASSERT_THAT(recvmsg(sockets->first_fd(), &msg, MSG_ERRQUEUE),
   612                SyscallSucceedsWithValue(0));
   613  
   614    EXPECT_NE(msg.msg_flags & MSG_ERRQUEUE, 0);
   615    EXPECT_EQ(memcmp(&remote, sockets->second_addr(), addrlen_), 0);
   616  
   617    // Check the contents of the control message.
   618    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
   619    ASSERT_NE(cmsg, nullptr);
   620    EXPECT_EQ(CMSG_NXTHDR(&msg, cmsg), nullptr);
   621    EXPECT_EQ(cmsg->cmsg_level, opt_level);
   622    EXPECT_EQ(cmsg->cmsg_type, opt_type);
   623    EXPECT_EQ(cmsg->cmsg_len,
   624              sizeof(sock_extended_err) + addrlen_ + sizeof(cmsghdr));
   625  
   626    // Check the contents of socket error.
   627    struct sock_extended_err* sock_err =
   628        reinterpret_cast<sock_extended_err*>(CMSG_DATA(cmsg));
   629    EXPECT_EQ(sock_err->ee_errno, EMSGSIZE);
   630    EXPECT_EQ(sock_err->ee_origin, SO_EE_ORIGIN_LOCAL);
   631    EXPECT_EQ(sock_err->ee_type, ICMP_ECHOREPLY);
   632    EXPECT_EQ(sock_err->ee_code, ICMP_NET_UNREACH);
   633    EXPECT_EQ(sock_err->ee_info, kBufLen);
   634    EXPECT_EQ(sock_err->ee_data, 0);
   635  
   636    // Verify that no socket error was put on the queue.
   637    int err;
   638    optlen = sizeof(err);
   639    ASSERT_THAT(
   640        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_ERROR, &err, &optlen),
   641        SyscallSucceeds());
   642    ASSERT_EQ(err, 0);
   643    ASSERT_EQ(optlen, sizeof(err));
   644  }
   645  #endif  // __linux__
   646  
   647  }  // namespace testing
   648  }  // namespace gvisor