gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/syscalls/linux/socket_generic_test_cases.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_generic.h"
    16  
    17  #ifdef __linux__
    18  #include <linux/capability.h>
    19  #endif  // __linux__
    20  #include <stdio.h>
    21  #include <sys/ioctl.h>
    22  #include <sys/socket.h>
    23  #include <sys/un.h>
    24  
    25  #include "gtest/gtest.h"
    26  #include "absl/strings/str_format.h"
    27  #include "absl/strings/string_view.h"
    28  #include "test/syscalls/linux/unix_domain_socket_test_util.h"
    29  #include "test/util/capability_util.h"
    30  #include "test/util/save_util.h"
    31  #include "test/util/socket_util.h"
    32  #include "test/util/test_util.h"
    33  
    34  // This file is a generic socket test file. It must be built with another file
    35  // that provides the test types.
    36  
    37  namespace gvisor {
    38  namespace testing {
    39  
    40  TEST_P(AllSocketPairTest, BasicReadWrite) {
    41    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    42    char buf[20];
    43    const std::string data = "abc";
    44    ASSERT_THAT(WriteFd(sockets->first_fd(), data.c_str(), 3),
    45                SyscallSucceedsWithValue(3));
    46    ASSERT_THAT(ReadFd(sockets->second_fd(), buf, 3),
    47                SyscallSucceedsWithValue(3));
    48    EXPECT_EQ(data, absl::string_view(buf, 3));
    49  }
    50  
    51  TEST_P(AllSocketPairTest, BasicReadWriteBadBuffer) {
    52    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    53    const std::string data = "abc";
    54    ASSERT_THAT(WriteFd(sockets->first_fd(), data.c_str(), 3),
    55                SyscallSucceedsWithValue(3));
    56    ASSERT_THAT(ReadFd(sockets->second_fd(), nullptr, 3),
    57                SyscallFailsWithErrno(EFAULT));
    58  }
    59  
    60  TEST_P(AllSocketPairTest, BasicSendRecv) {
    61    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    62    char sent_data[512];
    63    RandomizeBuffer(sent_data, sizeof(sent_data));
    64    ASSERT_THAT(
    65        RetryEINTR(send)(sockets->first_fd(), sent_data, sizeof(sent_data), 0),
    66        SyscallSucceedsWithValue(sizeof(sent_data)));
    67    char received_data[sizeof(sent_data)];
    68    ASSERT_THAT(RetryEINTR(recv)(sockets->second_fd(), received_data,
    69                                 sizeof(received_data), 0),
    70                SyscallSucceedsWithValue(sizeof(received_data)));
    71    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
    72  }
    73  
    74  TEST_P(AllSocketPairTest, BasicSendmmsg) {
    75    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    76    char sent_data[200];
    77    RandomizeBuffer(sent_data, sizeof(sent_data));
    78  
    79    // TODO(b/323000153): Flaky with S/R.
    80    gvisor::testing::DisableSave ds;
    81    std::vector<struct mmsghdr> msgs(10);
    82    std::vector<struct iovec> iovs(msgs.size());
    83    const int chunk_size = sizeof(sent_data) / msgs.size();
    84    for (size_t i = 0; i < msgs.size(); i++) {
    85      iovs[i].iov_len = chunk_size;
    86      iovs[i].iov_base = &sent_data[i * chunk_size];
    87      msgs[i].msg_hdr.msg_iov = &iovs[i];
    88      msgs[i].msg_hdr.msg_iovlen = 1;
    89    }
    90  
    91    ASSERT_THAT(
    92        RetryEINTR(sendmmsg)(sockets->first_fd(), &msgs[0], msgs.size(), 0),
    93        SyscallSucceedsWithValue(msgs.size()));
    94  
    95    for (const struct mmsghdr& msg : msgs) {
    96      EXPECT_EQ(chunk_size, msg.msg_len);
    97    }
    98  
    99    char received_data[sizeof(sent_data)];
   100    for (size_t i = 0; i < msgs.size(); i++) {
   101      ASSERT_THAT(ReadFd(sockets->second_fd(), &received_data[i * chunk_size],
   102                         chunk_size),
   103                  SyscallSucceedsWithValue(chunk_size));
   104    }
   105    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   106  }
   107  
   108  TEST_P(AllSocketPairTest, SendmmsgIsLimitedByMAXIOV) {
   109    std::unique_ptr<SocketPair> sockets =
   110        ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   111    char c = 0;
   112  
   113    std::vector<struct mmsghdr> msgs(UIO_MAXIOV + 1);
   114    std::vector<struct iovec> iovs(msgs.size());
   115    for (size_t i = 0; i < msgs.size(); i++) {
   116      iovs[i].iov_len = 1;
   117      iovs[i].iov_base = &c;
   118      msgs[i].msg_hdr.msg_iov = &iovs[i];
   119      msgs[i].msg_hdr.msg_iovlen = 1;
   120    }
   121  
   122    int n;
   123    ASSERT_THAT(n = RetryEINTR(sendmmsg)(sockets->first_fd(), msgs.data(),
   124                                         msgs.size(), MSG_DONTWAIT),
   125                SyscallSucceeds());
   126    EXPECT_LE(n, UIO_MAXIOV);
   127  }
   128  
   129  TEST_P(AllSocketPairTest, BasicRecvmmsg) {
   130    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   131    char sent_data[200];
   132    RandomizeBuffer(sent_data, sizeof(sent_data));
   133  
   134    char received_data[sizeof(sent_data)];
   135    std::vector<struct mmsghdr> msgs(10);
   136    std::vector<struct iovec> iovs(msgs.size());
   137    const int chunk_size = sizeof(sent_data) / msgs.size();
   138    for (size_t i = 0; i < msgs.size(); i++) {
   139      iovs[i].iov_len = chunk_size;
   140      iovs[i].iov_base = &received_data[i * chunk_size];
   141      msgs[i].msg_hdr.msg_iov = &iovs[i];
   142      msgs[i].msg_hdr.msg_iovlen = 1;
   143    }
   144  
   145    for (size_t i = 0; i < msgs.size(); i++) {
   146      ASSERT_THAT(
   147          WriteFd(sockets->first_fd(), &sent_data[i * chunk_size], chunk_size),
   148          SyscallSucceedsWithValue(chunk_size));
   149    }
   150  
   151    ASSERT_THAT(RetryEINTR(recvmmsg)(sockets->second_fd(), &msgs[0], msgs.size(),
   152                                     0, nullptr),
   153                SyscallSucceedsWithValue(msgs.size()));
   154  
   155    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   156  
   157    for (const struct mmsghdr& msg : msgs) {
   158      EXPECT_EQ(chunk_size, msg.msg_len);
   159    }
   160  }
   161  
   162  TEST_P(AllSocketPairTest, SendmsgRecvmsg10KB) {
   163    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   164    std::vector<char> sent_data(10 * 1024);
   165    RandomizeBuffer(sent_data.data(), sent_data.size());
   166    ASSERT_NO_FATAL_FAILURE(
   167        SendNullCmsg(sockets->first_fd(), sent_data.data(), sent_data.size()));
   168  
   169    std::vector<char> received_data(sent_data.size());
   170    ASSERT_NO_FATAL_FAILURE(RecvNoCmsg(sockets->second_fd(), received_data.data(),
   171                                       received_data.size()));
   172  
   173    EXPECT_EQ(0,
   174              memcmp(sent_data.data(), received_data.data(), sent_data.size()));
   175  }
   176  
   177  // This test validates that a sendmsg/recvmsg w/ MSG_CTRUNC is a no-op on
   178  // input flags.
   179  TEST_P(AllSocketPairTest, SendmsgRecvmsgMsgCtruncNoop) {
   180    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   181    std::vector<char> sent_data(10 * 1024);
   182    RandomizeBuffer(sent_data.data(), sent_data.size());
   183    ASSERT_NO_FATAL_FAILURE(
   184        SendNullCmsg(sockets->first_fd(), sent_data.data(), sent_data.size()));
   185  
   186    std::vector<char> received_data(sent_data.size());
   187    struct msghdr msg = {};
   188    char control[CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(struct ucred))];
   189    msg.msg_control = control;
   190    msg.msg_controllen = sizeof(control);
   191  
   192    struct iovec iov;
   193    iov.iov_base = &received_data[0];
   194    iov.iov_len = received_data.size();
   195    msg.msg_iov = &iov;
   196    msg.msg_iovlen = 1;
   197  
   198    // MSG_CTRUNC should be a no-op.
   199    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, MSG_CTRUNC),
   200                SyscallSucceedsWithValue(received_data.size()));
   201    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
   202    EXPECT_EQ(cmsg, nullptr);
   203    EXPECT_EQ(msg.msg_controllen, 0);
   204    EXPECT_EQ(0,
   205              memcmp(sent_data.data(), received_data.data(), sent_data.size()));
   206  }
   207  
   208  TEST_P(AllSocketPairTest, SendmsgRecvmsg16KB) {
   209    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   210    std::vector<char> sent_data(16 * 1024);
   211    RandomizeBuffer(sent_data.data(), sent_data.size());
   212    ASSERT_NO_FATAL_FAILURE(
   213        SendNullCmsg(sockets->first_fd(), sent_data.data(), sent_data.size()));
   214  
   215    std::vector<char> received_data(sent_data.size());
   216    ASSERT_NO_FATAL_FAILURE(RecvNoCmsg(sockets->second_fd(), received_data.data(),
   217                                       received_data.size()));
   218  
   219    EXPECT_EQ(0,
   220              memcmp(sent_data.data(), received_data.data(), sent_data.size()));
   221  }
   222  
   223  TEST_P(AllSocketPairTest, RecvmsgMsghdrFlagsNotClearedOnFailure) {
   224    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   225  
   226    char received_data[10] = {};
   227  
   228    struct iovec iov;
   229    iov.iov_base = received_data;
   230    iov.iov_len = sizeof(received_data);
   231    struct msghdr msg = {};
   232    msg.msg_flags = -1;
   233    msg.msg_iov = &iov;
   234    msg.msg_iovlen = 1;
   235  
   236    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, MSG_DONTWAIT),
   237                SyscallFailsWithErrno(EAGAIN));
   238  
   239    // Check that msghdr flags were not changed.
   240    EXPECT_EQ(msg.msg_flags, -1);
   241  }
   242  
   243  TEST_P(AllSocketPairTest, RecvmsgMsghdrFlagsCleared) {
   244    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   245  
   246    char sent_data[10];
   247    RandomizeBuffer(sent_data, sizeof(sent_data));
   248    ASSERT_THAT(
   249        RetryEINTR(send)(sockets->first_fd(), sent_data, sizeof(sent_data), 0),
   250        SyscallSucceedsWithValue(sizeof(sent_data)));
   251  
   252    char received_data[sizeof(sent_data)] = {};
   253  
   254    struct iovec iov;
   255    iov.iov_base = received_data;
   256    iov.iov_len = sizeof(received_data);
   257    struct msghdr msg = {};
   258    msg.msg_flags = -1;
   259    msg.msg_iov = &iov;
   260    msg.msg_iovlen = 1;
   261  
   262    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
   263                SyscallSucceedsWithValue(sizeof(sent_data)));
   264    EXPECT_EQ(0, memcmp(received_data, sent_data, sizeof(sent_data)));
   265  
   266    // Check that msghdr flags were cleared.
   267    EXPECT_EQ(msg.msg_flags, 0);
   268  }
   269  
   270  TEST_P(AllSocketPairTest, RecvmsgPeekMsghdrFlagsCleared) {
   271    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   272  
   273    char sent_data[10];
   274    RandomizeBuffer(sent_data, sizeof(sent_data));
   275    ASSERT_THAT(
   276        RetryEINTR(send)(sockets->first_fd(), sent_data, sizeof(sent_data), 0),
   277        SyscallSucceedsWithValue(sizeof(sent_data)));
   278  
   279    char received_data[sizeof(sent_data)] = {};
   280  
   281    struct iovec iov;
   282    iov.iov_base = received_data;
   283    iov.iov_len = sizeof(received_data);
   284    struct msghdr msg = {};
   285    msg.msg_flags = -1;
   286    msg.msg_iov = &iov;
   287    msg.msg_iovlen = 1;
   288  
   289    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, MSG_PEEK),
   290                SyscallSucceedsWithValue(sizeof(sent_data)));
   291    EXPECT_EQ(0, memcmp(received_data, sent_data, sizeof(sent_data)));
   292  
   293    // Check that msghdr flags were cleared.
   294    EXPECT_EQ(msg.msg_flags, 0);
   295  }
   296  
   297  TEST_P(AllSocketPairTest, RecvmsgIovNotUpdated) {
   298    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   299  
   300    char sent_data[10];
   301    RandomizeBuffer(sent_data, sizeof(sent_data));
   302    ASSERT_THAT(
   303        RetryEINTR(send)(sockets->first_fd(), sent_data, sizeof(sent_data), 0),
   304        SyscallSucceedsWithValue(sizeof(sent_data)));
   305  
   306    char received_data[sizeof(sent_data) * 2] = {};
   307  
   308    struct iovec iov;
   309    iov.iov_base = received_data;
   310    iov.iov_len = sizeof(received_data);
   311    struct msghdr msg = {};
   312    msg.msg_iov = &iov;
   313    msg.msg_iovlen = 1;
   314  
   315    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
   316                SyscallSucceedsWithValue(sizeof(sent_data)));
   317    EXPECT_EQ(0, memcmp(received_data, sent_data, sizeof(sent_data)));
   318  
   319    // Check that the iovec length was not updated.
   320    EXPECT_EQ(msg.msg_iov->iov_len, sizeof(received_data));
   321  }
   322  
   323  TEST_P(AllSocketPairTest, RecvmmsgInvalidTimeout) {
   324    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   325    char buf[10];
   326    struct mmsghdr msg = {};
   327    struct iovec iov = {};
   328    iov.iov_len = sizeof(buf);
   329    iov.iov_base = buf;
   330    msg.msg_hdr.msg_iov = &iov;
   331    msg.msg_hdr.msg_iovlen = 1;
   332    struct timespec timeout = {-1, -1};
   333    ASSERT_THAT(RetryEINTR(recvmmsg)(sockets->first_fd(), &msg, 1, 0, &timeout),
   334                SyscallFailsWithErrno(EINVAL));
   335  }
   336  
   337  TEST_P(AllSocketPairTest, RecvmmsgTimeoutBeforeRecv) {
   338    // There is a known bug in the Linux recvmmsg(2) causing it to block forever
   339    // if the timeout expires while blocking for the first message.
   340    SKIP_IF(!IsRunningOnGvisor() || IsRunningWithHostinet());
   341  
   342    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   343    char buf[10];
   344    struct mmsghdr msg = {};
   345    struct iovec iov = {};
   346    iov.iov_len = sizeof(buf);
   347    iov.iov_base = buf;
   348    msg.msg_hdr.msg_iov = &iov;
   349    msg.msg_hdr.msg_iovlen = 1;
   350    struct timespec timeout = {};
   351    ASSERT_THAT(RetryEINTR(recvmmsg)(sockets->first_fd(), &msg, 1, 0, &timeout),
   352                SyscallFailsWithErrno(EAGAIN));
   353  }
   354  
   355  TEST_P(AllSocketPairTest, MsgPeek) {
   356    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   357    char sent_data[50];
   358    memset(&sent_data, 0, sizeof(sent_data));
   359    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data, sizeof(sent_data)),
   360                SyscallSucceedsWithValue(sizeof(sent_data)));
   361  
   362    char received_data[sizeof(sent_data)];
   363    for (int i = 0; i < 3; i++) {
   364      memset(received_data, 0, sizeof(received_data));
   365      EXPECT_THAT(RetryEINTR(recv)(sockets->second_fd(), received_data,
   366                                   sizeof(received_data), MSG_PEEK),
   367                  SyscallSucceedsWithValue(sizeof(received_data)));
   368      EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(received_data)));
   369    }
   370  
   371    ASSERT_THAT(RetryEINTR(recv)(sockets->second_fd(), received_data,
   372                                 sizeof(received_data), 0),
   373                SyscallSucceedsWithValue(sizeof(received_data)));
   374    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(received_data)));
   375  }
   376  
   377  TEST_P(AllSocketPairTest, LingerSocketOption) {
   378    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   379    struct linger got_linger = {-1, -1};
   380    socklen_t length = sizeof(struct linger);
   381    EXPECT_THAT(getsockopt(sockets->first_fd(), SOL_SOCKET, SO_LINGER,
   382                           &got_linger, &length),
   383                SyscallSucceedsWithValue(0));
   384    struct linger want_linger = {};
   385    EXPECT_EQ(0, memcmp(&want_linger, &got_linger, sizeof(struct linger)));
   386    EXPECT_EQ(sizeof(struct linger), length);
   387  }
   388  
   389  TEST_P(AllSocketPairTest, KeepAliveSocketOption) {
   390    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   391    int keepalive = -1;
   392    socklen_t length = sizeof(int);
   393    EXPECT_THAT(getsockopt(sockets->first_fd(), SOL_SOCKET, SO_KEEPALIVE,
   394                           &keepalive, &length),
   395                SyscallSucceedsWithValue(0));
   396    EXPECT_EQ(0, keepalive);
   397    EXPECT_EQ(sizeof(int), length);
   398  }
   399  
   400  TEST_P(AllSocketPairTest, RcvBufSucceeds) {
   401    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   402    int size = 0;
   403    socklen_t size_size = sizeof(size);
   404    EXPECT_THAT(
   405        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVBUF, &size, &size_size),
   406        SyscallSucceeds());
   407    EXPECT_GT(size, 0);
   408  }
   409  
   410  #ifdef __linux__
   411  
   412  // Check that setting SO_RCVBUFFORCE above max is not clamped to the maximum
   413  // receive buffer size.
   414  TEST_P(AllSocketPairTest, SetSocketRecvBufForceAboveMax) {
   415    // TODO(b/267210840): This test requires CAP_NET_ADMIN on the host to run,
   416    // which we do not have in some test environments.
   417    SKIP_IF(IsRunningWithHostinet());
   418  
   419    std::unique_ptr<SocketPair> sockets =
   420        ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   421  
   422    // Discover maxmimum buffer size by setting to a really large value.
   423    constexpr int kRcvBufSz = 0xffffffff;
   424    ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVBUF, &kRcvBufSz,
   425                           sizeof(kRcvBufSz)),
   426                SyscallSucceeds());
   427  
   428    int max = 0;
   429    socklen_t max_len = sizeof(max);
   430    ASSERT_THAT(
   431        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVBUF, &max, &max_len),
   432        SyscallSucceeds());
   433  
   434    int above_max = max + 1;
   435    int sso = setsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVBUFFORCE,
   436                         &above_max, sizeof(above_max));
   437    if (!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN))) {
   438      ASSERT_THAT(sso, SyscallFailsWithErrno(EPERM));
   439      return;
   440    }
   441    ASSERT_THAT(sso, SyscallSucceeds());
   442  
   443    int val = 0;
   444    socklen_t val_len = sizeof(val);
   445    ASSERT_THAT(
   446        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVBUF, &val, &val_len),
   447        SyscallSucceeds());
   448    // The system doubles the passed-in maximum.
   449    ASSERT_EQ(above_max * 2, val);
   450  }
   451  
   452  #endif  // __linux__
   453  
   454  TEST_P(AllSocketPairTest, GetSndBufSucceeds) {
   455    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   456    int size = 0;
   457    socklen_t size_size = sizeof(size);
   458    EXPECT_THAT(
   459        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_SNDBUF, &size, &size_size),
   460        SyscallSucceeds());
   461    EXPECT_GT(size, 0);
   462  }
   463  
   464  TEST_P(AllSocketPairTest, RecvTimeoutReadSucceeds) {
   465    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   466  
   467    struct timeval tv {
   468      .tv_sec = 0, .tv_usec = 10
   469    };
   470    EXPECT_THAT(
   471        setsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)),
   472        SyscallSucceeds());
   473  
   474    char buf[20] = {};
   475    EXPECT_THAT(RetryEINTR(read)(sockets->first_fd(), buf, sizeof(buf)),
   476                SyscallFailsWithErrno(EAGAIN));
   477  }
   478  
   479  TEST_P(AllSocketPairTest, RecvTimeoutRecvSucceeds) {
   480    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   481  
   482    struct timeval tv {
   483      .tv_sec = 0, .tv_usec = 10
   484    };
   485    EXPECT_THAT(
   486        setsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)),
   487        SyscallSucceeds());
   488  
   489    char buf[20] = {};
   490    EXPECT_THAT(RetryEINTR(recv)(sockets->first_fd(), buf, sizeof(buf), 0),
   491                SyscallFailsWithErrno(EAGAIN));
   492  }
   493  
   494  TEST_P(AllSocketPairTest, RecvTimeoutRecvOneSecondSucceeds) {
   495    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   496  
   497    struct timeval tv {
   498      .tv_sec = 1, .tv_usec = 0
   499    };
   500    EXPECT_THAT(
   501        setsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)),
   502        SyscallSucceeds());
   503  
   504    char buf[20] = {};
   505    EXPECT_THAT(RetryEINTR(recv)(sockets->first_fd(), buf, sizeof(buf), 0),
   506                SyscallFailsWithErrno(EAGAIN));
   507  }
   508  
   509  TEST_P(AllSocketPairTest, RecvTimeoutRecvmsgSucceeds) {
   510    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   511  
   512    struct timeval tv {
   513      .tv_sec = 0, .tv_usec = 10
   514    };
   515    EXPECT_THAT(
   516        setsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)),
   517        SyscallSucceeds());
   518  
   519    struct msghdr msg = {};
   520    char buf[20] = {};
   521    struct iovec iov;
   522    iov.iov_base = buf;
   523    iov.iov_len = sizeof(buf);
   524    msg.msg_iov = &iov;
   525    msg.msg_iovlen = 1;
   526  
   527    EXPECT_THAT(RetryEINTR(recvmsg)(sockets->first_fd(), &msg, 0),
   528                SyscallFailsWithErrno(EAGAIN));
   529  }
   530  
   531  TEST_P(AllSocketPairTest, SendTimeoutDefault) {
   532    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   533  
   534    timeval actual_tv = {.tv_sec = -1, .tv_usec = -1};
   535    socklen_t len = sizeof(actual_tv);
   536    EXPECT_THAT(getsockopt(sockets->first_fd(), SOL_SOCKET, SO_SNDTIMEO,
   537                           &actual_tv, &len),
   538                SyscallSucceeds());
   539    EXPECT_EQ(actual_tv.tv_sec, 0);
   540    EXPECT_EQ(actual_tv.tv_usec, 0);
   541  }
   542  
   543  TEST_P(AllSocketPairTest, SetGetSendTimeout) {
   544    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   545  
   546    // tv_usec should be a multiple of 4000 to work on most systems.
   547    timeval tv = {.tv_sec = 89, .tv_usec = 44000};
   548    EXPECT_THAT(
   549        setsockopt(sockets->first_fd(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)),
   550        SyscallSucceeds());
   551  
   552    timeval actual_tv = {};
   553    socklen_t len = sizeof(actual_tv);
   554    EXPECT_THAT(getsockopt(sockets->first_fd(), SOL_SOCKET, SO_SNDTIMEO,
   555                           &actual_tv, &len),
   556                SyscallSucceeds());
   557    EXPECT_EQ(actual_tv.tv_sec, tv.tv_sec);
   558    EXPECT_EQ(actual_tv.tv_usec, tv.tv_usec);
   559  }
   560  
   561  TEST_P(AllSocketPairTest, SetGetSendTimeoutLargerArg) {
   562    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   563  
   564    struct timeval_with_extra {
   565      struct timeval tv;
   566      int64_t extra_data;
   567    } ABSL_ATTRIBUTE_PACKED;
   568  
   569    // tv_usec should be a multiple of 4000 to work on most systems.
   570    timeval_with_extra tv_extra = {
   571        .tv = {.tv_sec = 0, .tv_usec = 124000},
   572    };
   573  
   574    EXPECT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_SNDTIMEO,
   575                           &tv_extra, sizeof(tv_extra)),
   576                SyscallSucceeds());
   577  
   578    timeval_with_extra actual_tv = {};
   579    socklen_t len = sizeof(actual_tv);
   580    EXPECT_THAT(getsockopt(sockets->first_fd(), SOL_SOCKET, SO_SNDTIMEO,
   581                           &actual_tv, &len),
   582                SyscallSucceeds());
   583    EXPECT_EQ(actual_tv.tv.tv_sec, tv_extra.tv.tv_sec);
   584    EXPECT_EQ(actual_tv.tv.tv_usec, tv_extra.tv.tv_usec);
   585  }
   586  
   587  TEST_P(AllSocketPairTest, SendTimeoutAllowsWrite) {
   588    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   589  
   590    struct timeval tv {
   591      .tv_sec = 0, .tv_usec = 10
   592    };
   593    EXPECT_THAT(
   594        setsockopt(sockets->first_fd(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)),
   595        SyscallSucceeds());
   596  
   597    char buf[20] = {};
   598    ASSERT_THAT(RetryEINTR(write)(sockets->first_fd(), buf, sizeof(buf)),
   599                SyscallSucceedsWithValue(sizeof(buf)));
   600  }
   601  
   602  TEST_P(AllSocketPairTest, SendTimeoutAllowsSend) {
   603    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   604  
   605    struct timeval tv {
   606      .tv_sec = 0, .tv_usec = 10
   607    };
   608    EXPECT_THAT(
   609        setsockopt(sockets->first_fd(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)),
   610        SyscallSucceeds());
   611  
   612    char buf[20] = {};
   613    ASSERT_THAT(RetryEINTR(send)(sockets->first_fd(), buf, sizeof(buf), 0),
   614                SyscallSucceedsWithValue(sizeof(buf)));
   615  }
   616  
   617  TEST_P(AllSocketPairTest, SendTimeoutAllowsSendmsg) {
   618    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   619  
   620    struct timeval tv {
   621      .tv_sec = 0, .tv_usec = 10
   622    };
   623    EXPECT_THAT(
   624        setsockopt(sockets->first_fd(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)),
   625        SyscallSucceeds());
   626  
   627    char buf[20] = {};
   628    ASSERT_NO_FATAL_FAILURE(SendNullCmsg(sockets->first_fd(), buf, sizeof(buf)));
   629  }
   630  
   631  TEST_P(AllSocketPairTest, RecvTimeoutDefault) {
   632    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   633  
   634    timeval actual_tv = {.tv_sec = -1, .tv_usec = -1};
   635    socklen_t len = sizeof(actual_tv);
   636    EXPECT_THAT(getsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVTIMEO,
   637                           &actual_tv, &len),
   638                SyscallSucceeds());
   639    EXPECT_EQ(actual_tv.tv_sec, 0);
   640    EXPECT_EQ(actual_tv.tv_usec, 0);
   641  }
   642  
   643  TEST_P(AllSocketPairTest, SetGetRecvTimeout) {
   644    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   645  
   646    timeval tv = {.tv_sec = 123, .tv_usec = 456000};
   647    EXPECT_THAT(
   648        setsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)),
   649        SyscallSucceeds());
   650  
   651    timeval actual_tv = {};
   652    socklen_t len = sizeof(actual_tv);
   653    EXPECT_THAT(getsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVTIMEO,
   654                           &actual_tv, &len),
   655                SyscallSucceeds());
   656    EXPECT_EQ(actual_tv.tv_sec, 123);
   657    EXPECT_EQ(actual_tv.tv_usec, 456000);
   658  }
   659  
   660  TEST_P(AllSocketPairTest, SetGetRecvTimeoutLargerArg) {
   661    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   662  
   663    struct timeval_with_extra {
   664      struct timeval tv;
   665      int64_t extra_data;
   666    } ABSL_ATTRIBUTE_PACKED;
   667  
   668    timeval_with_extra tv_extra = {
   669        .tv = {.tv_sec = 0, .tv_usec = 432000},
   670    };
   671  
   672    EXPECT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVTIMEO,
   673                           &tv_extra, sizeof(tv_extra)),
   674                SyscallSucceeds());
   675  
   676    timeval_with_extra actual_tv = {};
   677    socklen_t len = sizeof(actual_tv);
   678    EXPECT_THAT(getsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVTIMEO,
   679                           &actual_tv, &len),
   680                SyscallSucceeds());
   681    EXPECT_EQ(actual_tv.tv.tv_sec, 0);
   682    EXPECT_EQ(actual_tv.tv.tv_usec, 432000);
   683  }
   684  
   685  TEST_P(AllSocketPairTest, RecvTimeoutRecvmsgOneSecondSucceeds) {
   686    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   687  
   688    struct timeval tv {
   689      .tv_sec = 1, .tv_usec = 0
   690    };
   691    EXPECT_THAT(
   692        setsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)),
   693        SyscallSucceeds());
   694  
   695    struct msghdr msg = {};
   696    char buf[20] = {};
   697    struct iovec iov;
   698    iov.iov_base = buf;
   699    iov.iov_len = sizeof(buf);
   700    msg.msg_iov = &iov;
   701    msg.msg_iovlen = 1;
   702  
   703    EXPECT_THAT(RetryEINTR(recvmsg)(sockets->first_fd(), &msg, 0),
   704                SyscallFailsWithErrno(EAGAIN));
   705  }
   706  
   707  TEST_P(AllSocketPairTest, RecvTimeoutUsecTooLarge) {
   708    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   709  
   710    struct timeval tv {
   711      .tv_sec = 0, .tv_usec = 2000000  // 2 seconds.
   712    };
   713    EXPECT_THAT(
   714        setsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)),
   715        SyscallFailsWithErrno(EDOM));
   716  }
   717  
   718  TEST_P(AllSocketPairTest, SendTimeoutUsecTooLarge) {
   719    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   720  
   721    struct timeval tv {
   722      .tv_sec = 0, .tv_usec = 2000000  // 2 seconds.
   723    };
   724    EXPECT_THAT(
   725        setsockopt(sockets->first_fd(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)),
   726        SyscallFailsWithErrno(EDOM));
   727  }
   728  
   729  TEST_P(AllSocketPairTest, RecvTimeoutUsecNeg) {
   730    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   731  
   732    struct timeval tv {
   733      .tv_sec = 0, .tv_usec = -1
   734    };
   735    EXPECT_THAT(
   736        setsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)),
   737        SyscallFailsWithErrno(EDOM));
   738  }
   739  
   740  TEST_P(AllSocketPairTest, SendTimeoutUsecNeg) {
   741    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   742  
   743    struct timeval tv {
   744      .tv_sec = 0, .tv_usec = -1
   745    };
   746    EXPECT_THAT(
   747        setsockopt(sockets->first_fd(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)),
   748        SyscallFailsWithErrno(EDOM));
   749  }
   750  
   751  TEST_P(AllSocketPairTest, RecvTimeoutNegSecRead) {
   752    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   753  
   754    struct timeval tv {
   755      .tv_sec = -1, .tv_usec = 0
   756    };
   757    EXPECT_THAT(
   758        setsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)),
   759        SyscallSucceeds());
   760  
   761    char buf[20] = {};
   762    EXPECT_THAT(RetryEINTR(read)(sockets->first_fd(), buf, sizeof(buf)),
   763                SyscallFailsWithErrno(EAGAIN));
   764  }
   765  
   766  TEST_P(AllSocketPairTest, RecvTimeoutNegSecRecv) {
   767    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   768  
   769    struct timeval tv {
   770      .tv_sec = -1, .tv_usec = 0
   771    };
   772    EXPECT_THAT(
   773        setsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)),
   774        SyscallSucceeds());
   775  
   776    char buf[20] = {};
   777    EXPECT_THAT(RetryEINTR(recv)(sockets->first_fd(), buf, sizeof(buf), 0),
   778                SyscallFailsWithErrno(EAGAIN));
   779  }
   780  
   781  TEST_P(AllSocketPairTest, RecvTimeoutNegSecRecvmsg) {
   782    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   783  
   784    struct timeval tv {
   785      .tv_sec = -1, .tv_usec = 0
   786    };
   787    EXPECT_THAT(
   788        setsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)),
   789        SyscallSucceeds());
   790  
   791    struct msghdr msg = {};
   792    char buf[20] = {};
   793    struct iovec iov;
   794    iov.iov_base = buf;
   795    iov.iov_len = sizeof(buf);
   796    msg.msg_iov = &iov;
   797    msg.msg_iovlen = 1;
   798  
   799    EXPECT_THAT(RetryEINTR(recvmsg)(sockets->first_fd(), &msg, 0),
   800                SyscallFailsWithErrno(EAGAIN));
   801  }
   802  
   803  TEST_P(AllSocketPairTest, RecvWaitAll) {
   804    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   805  
   806    char sent_data[100];
   807    RandomizeBuffer(sent_data, sizeof(sent_data));
   808  
   809    ASSERT_THAT(write(sockets->first_fd(), sent_data, sizeof(sent_data)),
   810                SyscallSucceedsWithValue(sizeof(sent_data)));
   811  
   812    char received_data[sizeof(sent_data)] = {};
   813    ASSERT_THAT(RetryEINTR(recv)(sockets->second_fd(), received_data,
   814                                 sizeof(received_data), MSG_WAITALL),
   815                SyscallSucceedsWithValue(sizeof(sent_data)));
   816  
   817    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   818  }
   819  
   820  TEST_P(AllSocketPairTest, RecvWaitAllDontWait) {
   821    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   822  
   823    char data[100] = {};
   824    ASSERT_THAT(RetryEINTR(recv)(sockets->second_fd(), data, sizeof(data),
   825                                 MSG_WAITALL | MSG_DONTWAIT),
   826                SyscallFailsWithErrno(EAGAIN));
   827  }
   828  
   829  TEST_P(AllSocketPairTest, RecvTimeoutWaitAll) {
   830    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   831  
   832    struct timeval tv {
   833      .tv_sec = 1, .tv_usec = 0
   834    };
   835    EXPECT_THAT(setsockopt(sockets->second_fd(), SOL_SOCKET, SO_RCVTIMEO, &tv,
   836                           sizeof(tv)),
   837                SyscallSucceeds());
   838  
   839    char sent_data[100];
   840    RandomizeBuffer(sent_data, sizeof(sent_data));
   841  
   842    ASSERT_THAT(write(sockets->first_fd(), sent_data, sizeof(sent_data)),
   843                SyscallSucceedsWithValue(sizeof(sent_data)));
   844  
   845    char received_data[sizeof(sent_data) * 2] = {};
   846    ASSERT_THAT(RetryEINTR(recv)(sockets->second_fd(), received_data,
   847                                 sizeof(received_data), MSG_WAITALL),
   848                SyscallSucceedsWithValue(sizeof(sent_data)));
   849  
   850    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   851  }
   852  
   853  TEST_P(AllSocketPairTest, GetSockoptType) {
   854    int type = GetParam().type;
   855    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   856    for (const int fd : {sockets->first_fd(), sockets->second_fd()}) {
   857      int opt;
   858      socklen_t optlen = sizeof(opt);
   859      EXPECT_THAT(getsockopt(fd, SOL_SOCKET, SO_TYPE, &opt, &optlen),
   860                  SyscallSucceeds());
   861  
   862      // Type may have SOCK_NONBLOCK and SOCK_CLOEXEC ORed into it. Remove these
   863      // before comparison.
   864      type &= ~(SOCK_NONBLOCK | SOCK_CLOEXEC);
   865      EXPECT_EQ(opt, type) << absl::StrFormat(
   866          "getsockopt(%d, SOL_SOCKET, SO_TYPE, &opt, &optlen) => opt=%d was "
   867          "unexpected",
   868          fd, opt);
   869    }
   870  }
   871  
   872  TEST_P(AllSocketPairTest, GetSockoptDomain) {
   873    const int domain = GetParam().domain;
   874    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   875    for (const int fd : {sockets->first_fd(), sockets->second_fd()}) {
   876      int opt;
   877      socklen_t optlen = sizeof(opt);
   878      EXPECT_THAT(getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &opt, &optlen),
   879                  SyscallSucceeds());
   880      EXPECT_EQ(opt, domain) << absl::StrFormat(
   881          "getsockopt(%d, SOL_SOCKET, SO_DOMAIN, &opt, &optlen) => opt=%d was "
   882          "unexpected",
   883          fd, opt);
   884    }
   885  }
   886  
   887  TEST_P(AllSocketPairTest, GetSockoptProtocol) {
   888    const int protocol = GetParam().protocol;
   889    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   890    for (const int fd : {sockets->first_fd(), sockets->second_fd()}) {
   891      int opt;
   892      socklen_t optlen = sizeof(opt);
   893      EXPECT_THAT(getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &opt, &optlen),
   894                  SyscallSucceeds());
   895      EXPECT_EQ(opt, protocol) << absl::StrFormat(
   896          "getsockopt(%d, SOL_SOCKET, SO_PROTOCOL, &opt, &optlen) => opt=%d was "
   897          "unexpected",
   898          fd, opt);
   899    }
   900  }
   901  
   902  TEST_P(AllSocketPairTest, SetAndGetBooleanSocketOptions) {
   903    int sock_opts[] = {SO_BROADCAST, SO_PASSCRED,  SO_NO_CHECK,
   904                       SO_REUSEADDR, SO_REUSEPORT, SO_KEEPALIVE};
   905    for (int sock_opt : sock_opts) {
   906      auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   907      int enable = -1;
   908      socklen_t enableLen = sizeof(enable);
   909  
   910      // Test that the option is initially set to false.
   911      ASSERT_THAT(getsockopt(sockets->first_fd(), SOL_SOCKET, sock_opt, &enable,
   912                             &enableLen),
   913                  SyscallSucceeds());
   914      ASSERT_EQ(enableLen, sizeof(enable));
   915      EXPECT_EQ(enable, 0) << absl::StrFormat(
   916          "getsockopt(fd, SOL_SOCKET, %d, &enable, &enableLen) => enable=%d",
   917          sock_opt, enable);
   918  
   919      // Test that setting the option to true is reflected in the subsequent
   920      // call to getsockopt(2).
   921      enable = 1;
   922      ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, sock_opt, &enable,
   923                             sizeof(enable)),
   924                  SyscallSucceeds());
   925      enable = -1;
   926      enableLen = sizeof(enable);
   927      ASSERT_THAT(getsockopt(sockets->first_fd(), SOL_SOCKET, sock_opt, &enable,
   928                             &enableLen),
   929                  SyscallSucceeds());
   930      ASSERT_EQ(enableLen, sizeof(enable));
   931      EXPECT_EQ(enable, 1) << absl::StrFormat(
   932          "getsockopt(fd, SOL_SOCKET, %d, &enable, &enableLen) => enable=%d",
   933          sock_opt, enable);
   934    }
   935  }
   936  
   937  TEST_P(AllSocketPairTest, GetSocketOutOfBandInlineOption) {
   938    // gVisor does not support this option, unless using Hostinet.
   939    SKIP_IF(!IsRunningOnGvisor() || IsRunningWithHostinet());
   940  
   941    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   942    int enable = -1;
   943    socklen_t enableLen = sizeof(enable);
   944  
   945    int want = 1;
   946    ASSERT_THAT(getsockopt(sockets->first_fd(), SOL_SOCKET, SO_OOBINLINE, &enable,
   947                           &enableLen),
   948                SyscallSucceeds());
   949    ASSERT_EQ(enableLen, sizeof(enable));
   950    EXPECT_EQ(enable, want);
   951  }
   952  
   953  TEST_P(AllSocketPairTest, GetSocketRcvbufOption) {
   954    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   955  
   956    int rcvBufSz = 0;
   957    ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVBUF, &rcvBufSz,
   958                           sizeof(rcvBufSz)),
   959                SyscallSucceeds());
   960  
   961    int opt = 0;
   962    socklen_t opt_len = sizeof(opt);
   963    ASSERT_THAT(
   964        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVBUF, &opt, &opt_len),
   965        SyscallSucceeds());
   966    ASSERT_EQ(opt_len, sizeof(opt));
   967  
   968    if (IsRunningOnGvisor() && !IsRunningWithHostinet()) {
   969      // Minimum buffer size in gVisor is 4KiB.
   970      const int minRcvBufSizeGvisor = 4096;
   971      EXPECT_EQ(opt, minRcvBufSizeGvisor);
   972    } else {
   973      // This value is derived as (2048 + sizeof(sk_buff)).
   974      const int minRcvBufSizeLinux = 2304;
   975      EXPECT_EQ(opt, minRcvBufSizeLinux);
   976    }
   977  }
   978  
   979  TEST_P(AllSocketPairTest, GetSetSocketRcvlowatOption) {
   980    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   981  
   982    int opt = 0;
   983    socklen_t opt_len = sizeof(opt);
   984    constexpr int defaultSz = 1;
   985    ASSERT_THAT(
   986        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVLOWAT, &opt, &opt_len),
   987        SyscallSucceeds());
   988    ASSERT_EQ(opt_len, sizeof(opt));
   989    EXPECT_EQ(opt, defaultSz);
   990  
   991    int rcvlowatSz = 100;
   992    ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVLOWAT,
   993                           &rcvlowatSz, sizeof(rcvlowatSz)),
   994                SyscallSucceeds());
   995  
   996    ASSERT_THAT(
   997        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVLOWAT, &opt, &opt_len),
   998        SyscallSucceeds());
   999    ASSERT_EQ(opt_len, sizeof(opt));
  1000  
  1001    if (IsRunningOnGvisor() && !IsRunningWithHostinet()) {
  1002      // TODO(b/226603727): Add support for setting SO_RCVLOWAT option in gVisor.
  1003      EXPECT_EQ(opt, defaultSz);
  1004    } else {
  1005      EXPECT_EQ(opt, rcvlowatSz);
  1006    }
  1007  }
  1008  }  // namespace testing
  1009  }  // namespace gvisor