github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/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/in6.h>
    20  #endif  // __linux__
    21  #include <netinet/in.h>
    22  #include <netinet/tcp.h>
    23  #include <poll.h>
    24  #include <stdio.h>
    25  #include <sys/ioctl.h>
    26  #include <sys/socket.h>
    27  #include <sys/types.h>
    28  #include <sys/un.h>
    29  
    30  #include "gtest/gtest.h"
    31  #include "test/syscalls/linux/socket_test_util.h"
    32  #include "test/util/test_util.h"
    33  
    34  namespace gvisor {
    35  namespace testing {
    36  
    37  TEST_P(UDPSocketPairTest, MulticastTTLDefault) {
    38    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    39  
    40    int get = -1;
    41    socklen_t get_len = sizeof(get);
    42    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
    43                           &get, &get_len),
    44                SyscallSucceedsWithValue(0));
    45    EXPECT_EQ(get_len, sizeof(get));
    46    EXPECT_EQ(get, 1);
    47  }
    48  
    49  TEST_P(UDPSocketPairTest, SetUDPMulticastTTLMin) {
    50    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    51  
    52    constexpr int kMin = 0;
    53    EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
    54                           &kMin, sizeof(kMin)),
    55                SyscallSucceeds());
    56  
    57    int get = -1;
    58    socklen_t get_len = sizeof(get);
    59    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
    60                           &get, &get_len),
    61                SyscallSucceedsWithValue(0));
    62    EXPECT_EQ(get_len, sizeof(get));
    63    EXPECT_EQ(get, kMin);
    64  }
    65  
    66  TEST_P(UDPSocketPairTest, SetUDPMulticastTTLMax) {
    67    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    68  
    69    constexpr int kMax = 255;
    70    EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
    71                           &kMax, sizeof(kMax)),
    72                SyscallSucceeds());
    73  
    74    int get = -1;
    75    socklen_t get_len = sizeof(get);
    76    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
    77                           &get, &get_len),
    78                SyscallSucceedsWithValue(0));
    79    EXPECT_EQ(get_len, sizeof(get));
    80    EXPECT_EQ(get, kMax);
    81  }
    82  
    83  TEST_P(UDPSocketPairTest, SetUDPMulticastTTLNegativeOne) {
    84    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    85  
    86    constexpr int kArbitrary = 6;
    87    EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
    88                           &kArbitrary, sizeof(kArbitrary)),
    89                SyscallSucceeds());
    90  
    91    constexpr int kNegOne = -1;
    92    EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
    93                           &kNegOne, sizeof(kNegOne)),
    94                SyscallSucceeds());
    95  
    96    int get = -1;
    97    socklen_t get_len = sizeof(get);
    98    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
    99                           &get, &get_len),
   100                SyscallSucceedsWithValue(0));
   101    EXPECT_EQ(get_len, sizeof(get));
   102    EXPECT_EQ(get, 1);
   103  }
   104  
   105  TEST_P(UDPSocketPairTest, SetUDPMulticastTTLBelowMin) {
   106    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   107  
   108    constexpr int kBelowMin = -2;
   109    EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
   110                           &kBelowMin, sizeof(kBelowMin)),
   111                SyscallFailsWithErrno(EINVAL));
   112  }
   113  
   114  TEST_P(UDPSocketPairTest, SetUDPMulticastTTLAboveMax) {
   115    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   116  
   117    constexpr int kAboveMax = 256;
   118    EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
   119                           &kAboveMax, sizeof(kAboveMax)),
   120                SyscallFailsWithErrno(EINVAL));
   121  }
   122  
   123  TEST_P(UDPSocketPairTest, SetUDPMulticastTTLChar) {
   124    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   125  
   126    constexpr char kArbitrary = 6;
   127    EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
   128                           &kArbitrary, sizeof(kArbitrary)),
   129                SyscallSucceeds());
   130  
   131    int get = -1;
   132    socklen_t get_len = sizeof(get);
   133    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL,
   134                           &get, &get_len),
   135                SyscallSucceedsWithValue(0));
   136    EXPECT_EQ(get_len, sizeof(get));
   137    EXPECT_EQ(get, kArbitrary);
   138  }
   139  
   140  TEST_P(UDPSocketPairTest, SetEmptyIPAddMembership) {
   141    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   142  
   143    struct ip_mreqn req = {};
   144    EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP,
   145                           &req, sizeof(req)),
   146                SyscallFailsWithErrno(EINVAL));
   147  }
   148  
   149  TEST_P(UDPSocketPairTest, MulticastLoopDefault) {
   150    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   151  
   152    int get = -1;
   153    socklen_t get_len = sizeof(get);
   154    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP,
   155                           &get, &get_len),
   156                SyscallSucceedsWithValue(0));
   157    EXPECT_EQ(get_len, sizeof(get));
   158    EXPECT_EQ(get, kSockOptOn);
   159  }
   160  
   161  TEST_P(UDPSocketPairTest, SetMulticastLoop) {
   162    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   163  
   164    ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP,
   165                           &kSockOptOff, sizeof(kSockOptOff)),
   166                SyscallSucceeds());
   167  
   168    int get = -1;
   169    socklen_t get_len = sizeof(get);
   170    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP,
   171                           &get, &get_len),
   172                SyscallSucceedsWithValue(0));
   173    EXPECT_EQ(get_len, sizeof(get));
   174    EXPECT_EQ(get, kSockOptOff);
   175  
   176    ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP,
   177                           &kSockOptOn, sizeof(kSockOptOn)),
   178                SyscallSucceeds());
   179  
   180    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP,
   181                           &get, &get_len),
   182                SyscallSucceedsWithValue(0));
   183    EXPECT_EQ(get_len, sizeof(get));
   184    EXPECT_EQ(get, kSockOptOn);
   185  }
   186  
   187  TEST_P(UDPSocketPairTest, SetMulticastLoopChar) {
   188    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   189  
   190    constexpr char kSockOptOnChar = kSockOptOn;
   191    constexpr char kSockOptOffChar = kSockOptOff;
   192  
   193    ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP,
   194                           &kSockOptOffChar, sizeof(kSockOptOffChar)),
   195                SyscallSucceeds());
   196  
   197    int get = -1;
   198    socklen_t get_len = sizeof(get);
   199    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP,
   200                           &get, &get_len),
   201                SyscallSucceedsWithValue(0));
   202    EXPECT_EQ(get_len, sizeof(get));
   203    EXPECT_EQ(get, kSockOptOff);
   204  
   205    ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP,
   206                           &kSockOptOnChar, sizeof(kSockOptOnChar)),
   207                SyscallSucceeds());
   208  
   209    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP,
   210                           &get, &get_len),
   211                SyscallSucceedsWithValue(0));
   212    EXPECT_EQ(get_len, sizeof(get));
   213    EXPECT_EQ(get, kSockOptOn);
   214  }
   215  
   216  TEST_P(UDPSocketPairTest, ReuseAddrDefault) {
   217    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   218  
   219    int get = -1;
   220    socklen_t get_len = sizeof(get);
   221    ASSERT_THAT(
   222        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, &get, &get_len),
   223        SyscallSucceedsWithValue(0));
   224    EXPECT_EQ(get_len, sizeof(get));
   225    EXPECT_EQ(get, kSockOptOff);
   226  }
   227  
   228  TEST_P(UDPSocketPairTest, SetReuseAddr) {
   229    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   230  
   231    ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR,
   232                           &kSockOptOn, sizeof(kSockOptOn)),
   233                SyscallSucceeds());
   234  
   235    int get = -1;
   236    socklen_t get_len = sizeof(get);
   237    ASSERT_THAT(
   238        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, &get, &get_len),
   239        SyscallSucceedsWithValue(0));
   240    EXPECT_EQ(get_len, sizeof(get));
   241    EXPECT_EQ(get, kSockOptOn);
   242  
   243    ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR,
   244                           &kSockOptOff, sizeof(kSockOptOff)),
   245                SyscallSucceeds());
   246  
   247    ASSERT_THAT(
   248        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, &get, &get_len),
   249        SyscallSucceedsWithValue(0));
   250    EXPECT_EQ(get_len, sizeof(get));
   251    EXPECT_EQ(get, kSockOptOff);
   252  }
   253  
   254  TEST_P(UDPSocketPairTest, ReusePortDefault) {
   255    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   256  
   257    int get = -1;
   258    socklen_t get_len = sizeof(get);
   259    ASSERT_THAT(
   260        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, &get, &get_len),
   261        SyscallSucceedsWithValue(0));
   262    EXPECT_EQ(get_len, sizeof(get));
   263    EXPECT_EQ(get, kSockOptOff);
   264  }
   265  
   266  TEST_P(UDPSocketPairTest, SetReusePort) {
   267    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   268  
   269    ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT,
   270                           &kSockOptOn, sizeof(kSockOptOn)),
   271                SyscallSucceeds());
   272  
   273    int get = -1;
   274    socklen_t get_len = sizeof(get);
   275    ASSERT_THAT(
   276        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, &get, &get_len),
   277        SyscallSucceedsWithValue(0));
   278    EXPECT_EQ(get_len, sizeof(get));
   279    EXPECT_EQ(get, kSockOptOn);
   280  
   281    ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT,
   282                           &kSockOptOff, sizeof(kSockOptOff)),
   283                SyscallSucceeds());
   284  
   285    ASSERT_THAT(
   286        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, &get, &get_len),
   287        SyscallSucceedsWithValue(0));
   288    EXPECT_EQ(get_len, sizeof(get));
   289    EXPECT_EQ(get, kSockOptOff);
   290  }
   291  
   292  TEST_P(UDPSocketPairTest, SetReuseAddrReusePort) {
   293    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   294  
   295    ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR,
   296                           &kSockOptOn, sizeof(kSockOptOn)),
   297                SyscallSucceeds());
   298  
   299    ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT,
   300                           &kSockOptOn, sizeof(kSockOptOn)),
   301                SyscallSucceeds());
   302  
   303    int get = -1;
   304    socklen_t get_len = sizeof(get);
   305    ASSERT_THAT(
   306        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, &get, &get_len),
   307        SyscallSucceedsWithValue(0));
   308    EXPECT_EQ(get_len, sizeof(get));
   309    EXPECT_EQ(get, kSockOptOn);
   310  
   311    ASSERT_THAT(
   312        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, &get, &get_len),
   313        SyscallSucceedsWithValue(0));
   314    EXPECT_EQ(get_len, sizeof(get));
   315    EXPECT_EQ(get, kSockOptOn);
   316  }
   317  
   318  // Test getsockopt for a socket which is not set with IP_PKTINFO option.
   319  TEST_P(UDPSocketPairTest, IPPKTINFODefault) {
   320    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   321  
   322    int get = -1;
   323    socklen_t get_len = sizeof(get);
   324  
   325    ASSERT_THAT(
   326        getsockopt(sockets->first_fd(), SOL_IP, IP_PKTINFO, &get, &get_len),
   327        SyscallSucceedsWithValue(0));
   328    EXPECT_EQ(get_len, sizeof(get));
   329    EXPECT_EQ(get, kSockOptOff);
   330  }
   331  
   332  // Test setsockopt and getsockopt for a socket with IP_PKTINFO option.
   333  TEST_P(UDPSocketPairTest, SetAndGetIPPKTINFO) {
   334    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   335  
   336    int level = SOL_IP;
   337    int type = IP_PKTINFO;
   338  
   339    // Check getsockopt before IP_PKTINFO is set.
   340    int get = -1;
   341    socklen_t get_len = sizeof(get);
   342  
   343    ASSERT_THAT(setsockopt(sockets->first_fd(), level, type, &kSockOptOn,
   344                           sizeof(kSockOptOn)),
   345                SyscallSucceedsWithValue(0));
   346  
   347    ASSERT_THAT(getsockopt(sockets->first_fd(), level, type, &get, &get_len),
   348                SyscallSucceedsWithValue(0));
   349    EXPECT_EQ(get, kSockOptOn);
   350    EXPECT_EQ(get_len, sizeof(get));
   351  
   352    ASSERT_THAT(setsockopt(sockets->first_fd(), level, type, &kSockOptOff,
   353                           sizeof(kSockOptOff)),
   354                SyscallSucceedsWithValue(0));
   355  
   356    ASSERT_THAT(getsockopt(sockets->first_fd(), level, type, &get, &get_len),
   357                SyscallSucceedsWithValue(0));
   358    EXPECT_EQ(get, kSockOptOff);
   359    EXPECT_EQ(get_len, sizeof(get));
   360  }
   361  
   362  // Test getsockopt for a socket which is not set with IP_RECVORIGDSTADDR option.
   363  TEST_P(UDPSocketPairTest, ReceiveOrigDstAddrDefault) {
   364    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   365  
   366    int get = -1;
   367    socklen_t get_len = sizeof(get);
   368    int level = SOL_IP;
   369    int type = IP_RECVORIGDSTADDR;
   370    if (sockets->first_addr()->sa_family == AF_INET6) {
   371      level = SOL_IPV6;
   372      type = IPV6_RECVORIGDSTADDR;
   373    }
   374    ASSERT_THAT(getsockopt(sockets->first_fd(), level, type, &get, &get_len),
   375                SyscallSucceedsWithValue(0));
   376    EXPECT_EQ(get_len, sizeof(get));
   377    EXPECT_EQ(get, kSockOptOff);
   378  }
   379  
   380  // Test setsockopt and getsockopt for a socket with IP_RECVORIGDSTADDR option.
   381  TEST_P(UDPSocketPairTest, SetAndGetReceiveOrigDstAddr) {
   382    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   383  
   384    int level = SOL_IP;
   385    int type = IP_RECVORIGDSTADDR;
   386    if (sockets->first_addr()->sa_family == AF_INET6) {
   387      level = SOL_IPV6;
   388      type = IPV6_RECVORIGDSTADDR;
   389    }
   390  
   391    // Check getsockopt before IP_PKTINFO is set.
   392    int get = -1;
   393    socklen_t get_len = sizeof(get);
   394  
   395    ASSERT_THAT(setsockopt(sockets->first_fd(), level, type, &kSockOptOn,
   396                           sizeof(kSockOptOn)),
   397                SyscallSucceedsWithValue(0));
   398  
   399    ASSERT_THAT(getsockopt(sockets->first_fd(), level, type, &get, &get_len),
   400                SyscallSucceedsWithValue(0));
   401    EXPECT_EQ(get, kSockOptOn);
   402    EXPECT_EQ(get_len, sizeof(get));
   403  
   404    ASSERT_THAT(setsockopt(sockets->first_fd(), level, type, &kSockOptOff,
   405                           sizeof(kSockOptOff)),
   406                SyscallSucceedsWithValue(0));
   407  
   408    ASSERT_THAT(getsockopt(sockets->first_fd(), level, type, &get, &get_len),
   409                SyscallSucceedsWithValue(0));
   410    EXPECT_EQ(get, kSockOptOff);
   411    EXPECT_EQ(get_len, sizeof(get));
   412  }
   413  
   414  // Holds TOS or TClass information for IPv4 or IPv6 respectively.
   415  struct RecvTosOption {
   416    int level;
   417    int option;
   418  };
   419  
   420  RecvTosOption GetRecvTosOption(int domain) {
   421    TEST_CHECK(domain == AF_INET || domain == AF_INET6);
   422    RecvTosOption opt;
   423    switch (domain) {
   424      case AF_INET:
   425        opt.level = IPPROTO_IP;
   426        opt.option = IP_RECVTOS;
   427        break;
   428      case AF_INET6:
   429        opt.level = IPPROTO_IPV6;
   430        opt.option = IPV6_RECVTCLASS;
   431        break;
   432    }
   433    return opt;
   434  }
   435  
   436  // Ensure that Receiving TOS or TCLASS is off by default.
   437  TEST_P(UDPSocketPairTest, RecvTosDefault) {
   438    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   439    RecvTosOption t = GetRecvTosOption(GetParam().domain);
   440    int get = -1;
   441    socklen_t get_len = sizeof(get);
   442    ASSERT_THAT(
   443        getsockopt(sockets->first_fd(), t.level, t.option, &get, &get_len),
   444        SyscallSucceedsWithValue(0));
   445    EXPECT_EQ(get_len, sizeof(get));
   446    EXPECT_EQ(get, kSockOptOff);
   447  }
   448  
   449  // Test that setting and getting IP_RECVTOS or IPV6_RECVTCLASS works as
   450  // expected.
   451  TEST_P(UDPSocketPairTest, SetRecvTos) {
   452    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   453    RecvTosOption t = GetRecvTosOption(GetParam().domain);
   454  
   455    ASSERT_THAT(setsockopt(sockets->first_fd(), t.level, t.option, &kSockOptOff,
   456                           sizeof(kSockOptOff)),
   457                SyscallSucceeds());
   458  
   459    int get = -1;
   460    socklen_t get_len = sizeof(get);
   461    ASSERT_THAT(
   462        getsockopt(sockets->first_fd(), t.level, t.option, &get, &get_len),
   463        SyscallSucceedsWithValue(0));
   464    EXPECT_EQ(get_len, sizeof(get));
   465    EXPECT_EQ(get, kSockOptOff);
   466  
   467    ASSERT_THAT(setsockopt(sockets->first_fd(), t.level, t.option, &kSockOptOn,
   468                           sizeof(kSockOptOn)),
   469                SyscallSucceeds());
   470  
   471    ASSERT_THAT(
   472        getsockopt(sockets->first_fd(), t.level, t.option, &get, &get_len),
   473        SyscallSucceedsWithValue(0));
   474    EXPECT_EQ(get_len, sizeof(get));
   475    EXPECT_EQ(get, kSockOptOn);
   476  }
   477  
   478  // Test that any socket (including IPv6 only) accepts the IPv4 TOS option: this
   479  // mirrors behavior in linux.
   480  TEST_P(UDPSocketPairTest, TOSRecvMismatch) {
   481    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   482    RecvTosOption t = GetRecvTosOption(AF_INET);
   483    int get = -1;
   484    socklen_t get_len = sizeof(get);
   485  
   486    ASSERT_THAT(
   487        getsockopt(sockets->first_fd(), t.level, t.option, &get, &get_len),
   488        SyscallSucceedsWithValue(0));
   489  }
   490  
   491  // Test that an IPv4 socket does not support the IPv6 TClass option.
   492  TEST_P(UDPSocketPairTest, TClassRecvMismatch) {
   493    // This should only test AF_INET6 sockets for the mismatch behavior.
   494    SKIP_IF(GetParam().domain != AF_INET6);
   495    // IPV6_RECVTCLASS is only valid for SOCK_DGRAM and SOCK_RAW.
   496    SKIP_IF((GetParam().type != SOCK_DGRAM) | (GetParam().type != SOCK_RAW));
   497  
   498    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   499  
   500    int get = -1;
   501    socklen_t get_len = sizeof(get);
   502  
   503    ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IPV6, IPV6_RECVTCLASS,
   504                           &get, &get_len),
   505                SyscallFailsWithErrno(EOPNOTSUPP));
   506  }
   507  
   508  // Test the SO_LINGER option can be set/get on udp socket.
   509  TEST_P(UDPSocketPairTest, SetAndGetSocketLinger) {
   510    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   511    int level = SOL_SOCKET;
   512    int type = SO_LINGER;
   513  
   514    struct linger sl;
   515    sl.l_onoff = 1;
   516    sl.l_linger = 5;
   517    ASSERT_THAT(setsockopt(sockets->first_fd(), level, type, &sl, sizeof(sl)),
   518                SyscallSucceedsWithValue(0));
   519  
   520    struct linger got_linger = {};
   521    socklen_t length = sizeof(sl);
   522    ASSERT_THAT(
   523        getsockopt(sockets->first_fd(), level, type, &got_linger, &length),
   524        SyscallSucceedsWithValue(0));
   525  
   526    ASSERT_EQ(length, sizeof(got_linger));
   527    EXPECT_EQ(0, memcmp(&sl, &got_linger, length));
   528  }
   529  
   530  // Test getsockopt for SO_ACCEPTCONN on udp socket.
   531  TEST_P(UDPSocketPairTest, GetSocketAcceptConn) {
   532    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   533  
   534    int got = -1;
   535    socklen_t length = sizeof(got);
   536    ASSERT_THAT(
   537        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_ACCEPTCONN, &got, &length),
   538        SyscallSucceedsWithValue(0));
   539  
   540    ASSERT_EQ(length, sizeof(got));
   541    EXPECT_EQ(got, 0);
   542  }
   543  
   544  }  // namespace testing
   545  }  // namespace gvisor