gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/syscalls/linux/socket_stream.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_stream.h"
    16  
    17  #include <stdio.h>
    18  #include <sys/socket.h>
    19  #include <sys/types.h>
    20  #include <sys/un.h>
    21  
    22  #include "gtest/gtest.h"
    23  #include "absl/time/clock.h"
    24  #include "test/syscalls/linux/unix_domain_socket_test_util.h"
    25  #include "test/util/socket_util.h"
    26  #include "test/util/test_util.h"
    27  
    28  namespace gvisor {
    29  namespace testing {
    30  
    31  TEST_P(StreamSocketPairTest, SplitRecv) {
    32    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    33    char sent_data[512];
    34    RandomizeBuffer(sent_data, sizeof(sent_data));
    35    ASSERT_THAT(
    36        RetryEINTR(send)(sockets->first_fd(), sent_data, sizeof(sent_data), 0),
    37        SyscallSucceedsWithValue(sizeof(sent_data)));
    38    char received_data[sizeof(sent_data) / 2];
    39    ASSERT_THAT(RetryEINTR(recv)(sockets->second_fd(), received_data,
    40                                 sizeof(received_data), 0),
    41                SyscallSucceedsWithValue(sizeof(received_data)));
    42    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(received_data)));
    43    ASSERT_THAT(RetryEINTR(recv)(sockets->second_fd(), received_data,
    44                                 sizeof(received_data), 0),
    45                SyscallSucceedsWithValue(sizeof(received_data)));
    46    EXPECT_EQ(0, memcmp(sent_data + sizeof(received_data), received_data,
    47                        sizeof(received_data)));
    48  }
    49  
    50  // Stream sockets allow data sent with multiple sends to be read in a single
    51  // recv.
    52  //
    53  // CoalescedRecv checks that multiple messages are readable in a single recv.
    54  TEST_P(StreamSocketPairTest, CoalescedRecv) {
    55    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    56    char sent_data1[20];
    57    RandomizeBuffer(sent_data1, sizeof(sent_data1));
    58    ASSERT_THAT(
    59        RetryEINTR(send)(sockets->first_fd(), sent_data1, sizeof(sent_data1), 0),
    60        SyscallSucceedsWithValue(sizeof(sent_data1)));
    61    char sent_data2[20];
    62    RandomizeBuffer(sent_data2, sizeof(sent_data2));
    63    ASSERT_THAT(
    64        RetryEINTR(send)(sockets->first_fd(), sent_data2, sizeof(sent_data2), 0),
    65        SyscallSucceedsWithValue(sizeof(sent_data2)));
    66    char received_data[sizeof(sent_data1) + sizeof(sent_data2)];
    67    ASSERT_THAT(RetryEINTR(recv)(sockets->second_fd(), received_data,
    68                                 sizeof(received_data), 0),
    69                SyscallSucceedsWithValue(sizeof(received_data)));
    70    EXPECT_EQ(0, memcmp(sent_data1, received_data, sizeof(sent_data1)));
    71    EXPECT_EQ(0, memcmp(sent_data2, received_data + sizeof(sent_data1),
    72                        sizeof(sent_data2)));
    73  }
    74  
    75  TEST_P(StreamSocketPairTest, WriteOneSideClosed) {
    76    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    77    ASSERT_THAT(close(sockets->release_first_fd()), SyscallSucceeds());
    78    const char str[] = "abc";
    79    ASSERT_THAT(write(sockets->second_fd(), str, 3),
    80                SyscallFailsWithErrno(EPIPE));
    81  }
    82  
    83  TEST_P(StreamSocketPairTest, RecvmsgMsghdrFlagsNoMsgTrunc) {
    84    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    85  
    86    char sent_data[10];
    87    RandomizeBuffer(sent_data, sizeof(sent_data));
    88    ASSERT_THAT(
    89        RetryEINTR(send)(sockets->first_fd(), sent_data, sizeof(sent_data), 0),
    90        SyscallSucceedsWithValue(sizeof(sent_data)));
    91  
    92    char received_data[sizeof(sent_data) / 2] = {};
    93  
    94    struct iovec iov;
    95    iov.iov_base = received_data;
    96    iov.iov_len = sizeof(received_data);
    97    struct msghdr msg = {};
    98    msg.msg_flags = -1;
    99    msg.msg_iov = &iov;
   100    msg.msg_iovlen = 1;
   101  
   102    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
   103                SyscallSucceedsWithValue(sizeof(received_data)));
   104    EXPECT_EQ(0, memcmp(received_data, sent_data, sizeof(received_data)));
   105  
   106    // Check that msghdr flags were cleared (MSG_TRUNC was not set).
   107    ASSERT_EQ(msg.msg_flags & MSG_TRUNC, 0);
   108  }
   109  
   110  TEST_P(StreamSocketPairTest, RecvmsgTruncZeroLen) {
   111    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   112  
   113    char sent_data[10];
   114    RandomizeBuffer(sent_data, sizeof(sent_data));
   115    ASSERT_THAT(
   116        RetryEINTR(send)(sockets->first_fd(), sent_data, sizeof(sent_data), 0),
   117        SyscallSucceedsWithValue(sizeof(sent_data)));
   118  
   119    char received_data[0] = {};
   120  
   121    struct iovec iov;
   122    iov.iov_base = received_data;
   123    iov.iov_len = sizeof(received_data);
   124    struct msghdr msg = {};
   125    msg.msg_flags = -1;
   126    msg.msg_iov = &iov;
   127    msg.msg_iovlen = 1;
   128  
   129    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, MSG_TRUNC),
   130                SyscallSucceedsWithValue(0));
   131  
   132    // Check that msghdr flags were cleared (MSG_TRUNC was not set).
   133    ASSERT_EQ(msg.msg_flags & MSG_TRUNC, 0);
   134  }
   135  
   136  TEST_P(StreamSocketPairTest, RecvmsgTruncPeekZeroLen) {
   137    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   138  
   139    char sent_data[10];
   140    RandomizeBuffer(sent_data, sizeof(sent_data));
   141    ASSERT_THAT(
   142        RetryEINTR(send)(sockets->first_fd(), sent_data, sizeof(sent_data), 0),
   143        SyscallSucceedsWithValue(sizeof(sent_data)));
   144  
   145    char received_data[0] = {};
   146  
   147    struct iovec iov;
   148    iov.iov_base = received_data;
   149    iov.iov_len = sizeof(received_data);
   150    struct msghdr msg = {};
   151    msg.msg_flags = -1;
   152    msg.msg_iov = &iov;
   153    msg.msg_iovlen = 1;
   154  
   155    ASSERT_THAT(
   156        RetryEINTR(recvmsg)(sockets->second_fd(), &msg, MSG_TRUNC | MSG_PEEK),
   157        SyscallSucceedsWithValue(0));
   158  
   159    // Check that msghdr flags were cleared (MSG_TRUNC was not set).
   160    ASSERT_EQ(msg.msg_flags & MSG_TRUNC, 0);
   161  }
   162  
   163  TEST_P(StreamSocketPairTest, MsgTrunc) {
   164    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   165    char sent_data[512];
   166    RandomizeBuffer(sent_data, sizeof(sent_data));
   167    ASSERT_THAT(
   168        RetryEINTR(send)(sockets->first_fd(), sent_data, sizeof(sent_data), 0),
   169        SyscallSucceedsWithValue(sizeof(sent_data)));
   170    char received_data[sizeof(sent_data)];
   171    ASSERT_THAT(RetryEINTR(recv)(sockets->second_fd(), received_data,
   172                                 sizeof(received_data) / 2, MSG_TRUNC),
   173                SyscallSucceedsWithValue(sizeof(sent_data) / 2));
   174    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data) / 2));
   175  }
   176  
   177  }  // namespace testing
   178  }  // namespace gvisor