github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/syscalls/linux/socket_unix_seqpacket.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_unix_seqpacket.h"
    16  
    17  #include <stdio.h>
    18  #include <sys/un.h>
    19  
    20  #include "gtest/gtest.h"
    21  #include "absl/time/clock.h"
    22  #include "absl/time/time.h"
    23  #include "test/syscalls/linux/socket_test_util.h"
    24  #include "test/syscalls/linux/unix_domain_socket_test_util.h"
    25  #include "test/util/test_util.h"
    26  
    27  namespace gvisor {
    28  namespace testing {
    29  
    30  namespace {
    31  
    32  TEST_P(SeqpacketUnixSocketPairTest, WriteOneSideClosed) {
    33    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    34    ASSERT_THAT(close(sockets->release_first_fd()), SyscallSucceeds());
    35    constexpr char kStr[] = "abc";
    36    ASSERT_THAT(write(sockets->second_fd(), kStr, 3),
    37                SyscallFailsWithErrno(EPIPE));
    38  }
    39  
    40  TEST_P(SeqpacketUnixSocketPairTest, ReadOneSideClosed) {
    41    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    42    ASSERT_THAT(close(sockets->release_first_fd()), SyscallSucceeds());
    43    char data[10] = {};
    44    ASSERT_THAT(read(sockets->second_fd(), data, sizeof(data)),
    45                SyscallSucceedsWithValue(0));
    46  }
    47  
    48  TEST_P(SeqpacketUnixSocketPairTest, Sendto) {
    49    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    50  
    51    struct sockaddr_un addr = {};
    52    addr.sun_family = AF_UNIX;
    53    constexpr char kPath[] = "\0nonexistent";
    54    memcpy(addr.sun_path, kPath, sizeof(kPath));
    55  
    56    constexpr char kStr[] = "abc";
    57    ASSERT_THAT(sendto(sockets->second_fd(), kStr, 3, 0, (struct sockaddr*)&addr,
    58                       sizeof(addr)),
    59                SyscallSucceedsWithValue(3));
    60  
    61    char data[10] = {};
    62    ASSERT_THAT(read(sockets->first_fd(), data, sizeof(data)),
    63                SyscallSucceedsWithValue(3));
    64  }
    65  
    66  TEST_P(SeqpacketUnixSocketPairTest, IncreasedSocketSendBufUnblocksWrites) {
    67    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    68    int sock = sockets->first_fd();
    69    int buf_size = 0;
    70    socklen_t buf_size_len = sizeof(buf_size);
    71    ASSERT_THAT(getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &buf_size, &buf_size_len),
    72                SyscallSucceeds());
    73    int opts;
    74    ASSERT_THAT(opts = fcntl(sock, F_GETFL), SyscallSucceeds());
    75    opts |= O_NONBLOCK;
    76    ASSERT_THAT(fcntl(sock, F_SETFL, opts), SyscallSucceeds());
    77  
    78    std::vector<char> buf(buf_size / 4);
    79    // Write till the socket buffer is full.
    80    while (RetryEINTR(send)(sock, buf.data(), buf.size(), 0) != -1) {
    81      // Sleep to give linux a chance to move data from the send buffer to the
    82      // receive buffer.
    83      absl::SleepFor(absl::Milliseconds(10));  // 10ms.
    84    }
    85    // The last error should have been EWOULDBLOCK.
    86    ASSERT_EQ(errno, EWOULDBLOCK);
    87  
    88    // Now increase the socket send buffer.
    89    buf_size = buf_size * 2;
    90    ASSERT_THAT(
    91        setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &buf_size, sizeof(buf_size)),
    92        SyscallSucceeds());
    93  
    94    // Skip test if the setsockopt didn't increase the sendbuf. This happens for
    95    // tests where the socket is a host fd where gVisor does not permit increasing
    96    // send buffer size.
    97    int new_buf_size = 0;
    98    buf_size_len = sizeof(new_buf_size);
    99    ASSERT_THAT(
   100        getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &new_buf_size, &buf_size_len),
   101        SyscallSucceeds());
   102    if (IsRunningOnGvisor() && (new_buf_size <= buf_size)) {
   103      GTEST_SKIP() << "Skipping test new send buffer size " << new_buf_size
   104                   << " is the same as the value before setsockopt, "
   105                   << " socket is probably a host backed socket." << std ::endl;
   106    }
   107    //  send should succeed again.
   108    ASSERT_THAT(RetryEINTR(send)(sock, buf.data(), buf.size(), 0),
   109                SyscallSucceeds());
   110  }
   111  
   112  }  // namespace
   113  
   114  }  // namespace testing
   115  }  // namespace gvisor