diff --git a/test/syscalls/linux/tcp_socket.cc b/test/syscalls/linux/tcp_socket.cc index 5dff40ab9..496471835 100644 --- a/test/syscalls/linux/tcp_socket.cc +++ b/test/syscalls/linux/tcp_socket.cc @@ -110,28 +110,25 @@ class TcpSocketTest : public ::testing::TestWithParam { // that connects, and the accepted one. void SetUp() override; - // Closes the sockets created by SetUp(). - void TearDown() override; - // Listening socket. - int listener_ = -1; + FileDescriptor listener_; // Socket connected via connect(). - int first_fd = -1; + FileDescriptor connected_; // Socket connected via accept(). - int second_fd = -1; + FileDescriptor accepted_; // Initial size of the send buffer. int sendbuf_size_ = -1; }; void TcpSocketTest::SetUp() { - ASSERT_THAT(listener_ = socket(GetParam(), SOCK_STREAM, IPPROTO_TCP), - SyscallSucceeds()); + listener_ = + ASSERT_NO_ERRNO_AND_VALUE(Socket(GetParam(), SOCK_STREAM, IPPROTO_TCP)); - ASSERT_THAT(first_fd = socket(GetParam(), SOCK_STREAM, IPPROTO_TCP), - SyscallSucceeds()); + connected_ = + ASSERT_NO_ERRNO_AND_VALUE(Socket(GetParam(), SOCK_STREAM, IPPROTO_TCP)); // Initialize address to the loopback one. sockaddr_storage addr = @@ -139,37 +136,28 @@ void TcpSocketTest::SetUp() { socklen_t addrlen = sizeof(addr); // Bind to some port then start listening. - ASSERT_THAT(bind(listener_, AsSockAddr(&addr), addrlen), SyscallSucceeds()); + ASSERT_THAT(bind(listener_.get(), AsSockAddr(&addr), addrlen), + SyscallSucceeds()); - ASSERT_THAT(listen(listener_, SOMAXCONN), SyscallSucceeds()); + ASSERT_THAT(listen(listener_.get(), SOMAXCONN), SyscallSucceeds()); // Get the address we're listening on, then connect to it. We need to do this // because we're allowing the stack to pick a port for us. - ASSERT_THAT(getsockname(listener_, AsSockAddr(&addr), &addrlen), + ASSERT_THAT(getsockname(listener_.get(), AsSockAddr(&addr), &addrlen), SyscallSucceeds()); - ASSERT_THAT(RetryEINTR(connect)(first_fd, AsSockAddr(&addr), addrlen), + ASSERT_THAT(RetryEINTR(connect)(connected_.get(), AsSockAddr(&addr), addrlen), SyscallSucceeds()); // Get the initial send buffer size. socklen_t optlen = sizeof(sendbuf_size_); - ASSERT_THAT( - getsockopt(first_fd, SOL_SOCKET, SO_SNDBUF, &sendbuf_size_, &optlen), - SyscallSucceeds()); + ASSERT_THAT(getsockopt(connected_.get(), SOL_SOCKET, SO_SNDBUF, + &sendbuf_size_, &optlen), + SyscallSucceeds()); // Accept the connection. - ASSERT_THAT(second_fd = RetryEINTR(accept)(listener_, nullptr, nullptr), - SyscallSucceeds()); -} - -void TcpSocketTest::TearDown() { - EXPECT_THAT(close(listener_), SyscallSucceeds()); - if (first_fd >= 0) { - EXPECT_THAT(close(first_fd), SyscallSucceeds()); - } - if (second_fd >= 0) { - EXPECT_THAT(close(second_fd), SyscallSucceeds()); - } + accepted_ = + ASSERT_NO_ERRNO_AND_VALUE(Accept(listener_.get(), nullptr, nullptr)); } TEST_P(TcpSocketTest, ConnectedAcceptedPeerAndLocalAreReciprocals) { @@ -181,7 +169,7 @@ TEST_P(TcpSocketTest, ConnectedAcceptedPeerAndLocalAreReciprocals) { socklen_t name_len = sizeof(name); }; - FdAndAddrs connected{.fd = first_fd}, accepted{.fd = second_fd}; + FdAndAddrs connected{.fd = connected_.get()}, accepted{.fd = accepted_.get()}; for (FdAndAddrs* fd_and_addrs : {&connected, &accepted}) { ASSERT_THAT(getpeername(fd_and_addrs->fd, AsSockAddr(&fd_and_addrs->peer), @@ -206,55 +194,56 @@ TEST_P(TcpSocketTest, ConnectOnEstablishedConnection) { ASSERT_NO_ERRNO_AND_VALUE(InetLoopbackAddr(GetParam())); socklen_t addrlen = sizeof(addr); - ASSERT_THAT(connect(first_fd, reinterpret_cast(&addr), - addrlen), + ASSERT_THAT(connect(connected_.get(), + reinterpret_cast(&addr), addrlen), SyscallFailsWithErrno(EISCONN)); - ASSERT_THAT(connect(second_fd, + ASSERT_THAT(connect(accepted_.get(), reinterpret_cast(&addr), addrlen), SyscallFailsWithErrno(EISCONN)); } TEST_P(TcpSocketTest, ShutdownWriteInTimeWait) { - EXPECT_THAT(shutdown(second_fd, SHUT_WR), SyscallSucceeds()); - EXPECT_THAT(shutdown(first_fd, SHUT_RDWR), SyscallSucceeds()); + EXPECT_THAT(shutdown(accepted_.get(), SHUT_WR), SyscallSucceeds()); + EXPECT_THAT(shutdown(connected_.get(), SHUT_RDWR), SyscallSucceeds()); absl::SleepFor(absl::Seconds(1)); // Wait to enter TIME_WAIT. - EXPECT_THAT(shutdown(second_fd, SHUT_WR), SyscallFailsWithErrno(ENOTCONN)); + EXPECT_THAT(shutdown(accepted_.get(), SHUT_WR), + SyscallFailsWithErrno(ENOTCONN)); } TEST_P(TcpSocketTest, ShutdownWriteInFinWait1) { - EXPECT_THAT(shutdown(second_fd, SHUT_WR), SyscallSucceeds()); - EXPECT_THAT(shutdown(second_fd, SHUT_WR), SyscallSucceeds()); + EXPECT_THAT(shutdown(accepted_.get(), SHUT_WR), SyscallSucceeds()); + EXPECT_THAT(shutdown(accepted_.get(), SHUT_WR), SyscallSucceeds()); absl::SleepFor(absl::Seconds(1)); // Wait to enter FIN-WAIT2. - EXPECT_THAT(shutdown(second_fd, SHUT_WR), SyscallSucceeds()); + EXPECT_THAT(shutdown(accepted_.get(), SHUT_WR), SyscallSucceeds()); } TEST_P(TcpSocketTest, DataCoalesced) { char buf[10]; // Write in two steps. - ASSERT_THAT(RetryEINTR(write)(first_fd, buf, sizeof(buf) / 2), + ASSERT_THAT(RetryEINTR(write)(connected_.get(), buf, sizeof(buf) / 2), SyscallSucceedsWithValue(sizeof(buf) / 2)); - ASSERT_THAT(RetryEINTR(write)(first_fd, buf, sizeof(buf) / 2), + ASSERT_THAT(RetryEINTR(write)(connected_.get(), buf, sizeof(buf) / 2), SyscallSucceedsWithValue(sizeof(buf) / 2)); // Allow stack to process both packets. absl::SleepFor(absl::Seconds(1)); // Read in one shot. - EXPECT_THAT(RetryEINTR(recv)(second_fd, buf, sizeof(buf), 0), + EXPECT_THAT(RetryEINTR(recv)(accepted_.get(), buf, sizeof(buf), 0), SyscallSucceedsWithValue(sizeof(buf))); } TEST_P(TcpSocketTest, SenderAddressIgnored) { char buf[3]; - ASSERT_THAT(RetryEINTR(write)(first_fd, buf, sizeof(buf)), + ASSERT_THAT(RetryEINTR(write)(connected_.get(), buf, sizeof(buf)), SyscallSucceedsWithValue(sizeof(buf))); struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); memset(&addr, 0, sizeof(addr)); - ASSERT_THAT(RetryEINTR(recvfrom)(second_fd, buf, sizeof(buf), 0, + ASSERT_THAT(RetryEINTR(recvfrom)(accepted_.get(), buf, sizeof(buf), 0, AsSockAddr(&addr), &addrlen), SyscallSucceedsWithValue(3)); @@ -267,14 +256,14 @@ TEST_P(TcpSocketTest, SenderAddressIgnored) { TEST_P(TcpSocketTest, SenderAddressIgnoredOnPeek) { char buf[3]; - ASSERT_THAT(RetryEINTR(write)(first_fd, buf, sizeof(buf)), + ASSERT_THAT(RetryEINTR(write)(connected_.get(), buf, sizeof(buf)), SyscallSucceedsWithValue(sizeof(buf))); struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); memset(&addr, 0, sizeof(addr)); - ASSERT_THAT(RetryEINTR(recvfrom)(second_fd, buf, sizeof(buf), MSG_PEEK, + ASSERT_THAT(RetryEINTR(recvfrom)(accepted_.get(), buf, sizeof(buf), MSG_PEEK, AsSockAddr(&addr), &addrlen), SyscallSucceedsWithValue(3)); @@ -291,7 +280,7 @@ TEST_P(TcpSocketTest, SendtoAddressIgnored) { addr.ss_family = GetParam(); // FIXME(b/63803955) char data = '\0'; - EXPECT_THAT(RetryEINTR(sendto)(first_fd, &data, sizeof(data), 0, + EXPECT_THAT(RetryEINTR(sendto)(connected_.get(), &data, sizeof(data), 0, AsSockAddr(&addr), sizeof(addr)), SyscallSucceedsWithValue(1)); } @@ -309,10 +298,10 @@ TEST_P(TcpSocketTest, WritevZeroIovec) { vecs[1].iov_base = buf + 1; vecs[1].iov_len = 0; - EXPECT_THAT(RetryEINTR(writev)(first_fd, vecs, 2), + EXPECT_THAT(RetryEINTR(writev)(connected_.get(), vecs, 2), SyscallSucceedsWithValue(1)); - EXPECT_THAT(RetryEINTR(recv)(second_fd, recv_buf, 1, 0), + EXPECT_THAT(RetryEINTR(recv)(accepted_.get(), recv_buf, 1, 0), SyscallSucceedsWithValue(1)); EXPECT_EQ(memcmp(recv_buf, buf, 1), 0); } @@ -320,9 +309,10 @@ TEST_P(TcpSocketTest, WritevZeroIovec) { TEST_P(TcpSocketTest, ZeroWriteAllowed) { char buf[3]; // Send a zero length packet. - ASSERT_THAT(RetryEINTR(write)(first_fd, buf, 0), SyscallSucceedsWithValue(0)); + ASSERT_THAT(RetryEINTR(write)(connected_.get(), buf, 0), + SyscallSucceedsWithValue(0)); // Verify that there is no packet available. - EXPECT_THAT(RetryEINTR(recv)(second_fd, buf, sizeof(buf), MSG_DONTWAIT), + EXPECT_THAT(RetryEINTR(recv)(accepted_.get(), buf, sizeof(buf), MSG_DONTWAIT), SyscallFailsWithErrno(EAGAIN)); } @@ -332,9 +322,9 @@ TEST_P(TcpSocketTest, ZeroWriteAllowed) { TEST_P(TcpSocketTest, NonblockingLargeWrite) { // Set the FD to O_NONBLOCK. int opts; - ASSERT_THAT(opts = fcntl(first_fd, F_GETFL), SyscallSucceeds()); + ASSERT_THAT(opts = fcntl(connected_.get(), F_GETFL), SyscallSucceeds()); opts |= O_NONBLOCK; - ASSERT_THAT(fcntl(first_fd, F_SETFL, opts), SyscallSucceeds()); + ASSERT_THAT(fcntl(connected_.get(), F_SETFL, opts), SyscallSucceeds()); // Allocate a buffer three times the size of the send buffer. We do this with // a vector to avoid allocating on the stack. @@ -343,7 +333,7 @@ TEST_P(TcpSocketTest, NonblockingLargeWrite) { // Try to write the whole thing. int n; - ASSERT_THAT(n = RetryEINTR(write)(first_fd, buf.data(), size), + ASSERT_THAT(n = RetryEINTR(write)(connected_.get(), buf.data(), size), SyscallSucceeds()); // We should have written something, but not the whole thing. @@ -367,8 +357,7 @@ TEST_P(TcpSocketTest, BlockingLargeWrite) { // Take ownership of the FD so that we close it on failure. This will // unblock the blocking write below. - FileDescriptor fd(second_fd); - second_fd = -1; + FileDescriptor fd(std::move(accepted_)); char readbuf[2500] = {}; int n = -1; @@ -381,12 +370,12 @@ TEST_P(TcpSocketTest, BlockingLargeWrite) { // Try to write the whole thing. int n; - ASSERT_THAT(n = WriteFd(first_fd, writebuf.data(), size), SyscallSucceeds()); + ASSERT_THAT(n = WriteFd(connected_.get(), writebuf.data(), size), + SyscallSucceeds()); // We should have written the whole thing. EXPECT_EQ(n, size); - EXPECT_THAT(close(first_fd), SyscallSucceedsWithValue(0)); - first_fd = -1; + EXPECT_THAT(close(connected_.release()), SyscallSucceedsWithValue(0)); t.Join(); // We should have read the whole thing. @@ -404,8 +393,9 @@ TEST_P(TcpSocketTest, LargeSendDontWait) { // Try to write the whole thing with MSG_DONTWAIT flag, which can // return a partial write. int n; - ASSERT_THAT(n = RetryEINTR(send)(first_fd, buf.data(), size, MSG_DONTWAIT), - SyscallSucceeds()); + ASSERT_THAT( + n = RetryEINTR(send)(connected_.get(), buf.data(), size, MSG_DONTWAIT), + SyscallSucceeds()); // We should have written something, but not the whole thing. EXPECT_GT(n, 0); @@ -417,9 +407,9 @@ TEST_P(TcpSocketTest, LargeSendDontWait) { TEST_P(TcpSocketTest, NonblockingLargeSend) { // Set the FD to O_NONBLOCK. int opts; - ASSERT_THAT(opts = fcntl(first_fd, F_GETFL), SyscallSucceeds()); + ASSERT_THAT(opts = fcntl(connected_.get(), F_GETFL), SyscallSucceeds()); opts |= O_NONBLOCK; - ASSERT_THAT(fcntl(first_fd, F_SETFL, opts), SyscallSucceeds()); + ASSERT_THAT(fcntl(connected_.get(), F_SETFL, opts), SyscallSucceeds()); // Allocate a buffer three times the size of the send buffer. We do this on // with a vector to avoid allocating on the stack. @@ -428,7 +418,7 @@ TEST_P(TcpSocketTest, NonblockingLargeSend) { // Try to write the whole thing. int n; - ASSERT_THAT(n = RetryEINTR(send)(first_fd, buf.data(), size, 0), + ASSERT_THAT(n = RetryEINTR(send)(connected_.get(), buf.data(), size, 0), SyscallSucceeds()); // We should have written something, but not the whole thing. @@ -451,8 +441,7 @@ TEST_P(TcpSocketTest, BlockingLargeSend) { // Take ownership of the FD so that we close it on failure. This will // unblock the blocking write below. - FileDescriptor fd(second_fd); - second_fd = -1; + FileDescriptor fd(std::move(accepted_)); char readbuf[2500] = {}; int n = -1; @@ -465,13 +454,12 @@ TEST_P(TcpSocketTest, BlockingLargeSend) { // Try to send the whole thing. int n; - ASSERT_THAT(n = SendFd(first_fd, writebuf.data(), size, 0), + ASSERT_THAT(n = SendFd(connected_.get(), writebuf.data(), size, 0), SyscallSucceeds()); // We should have written the whole thing. EXPECT_EQ(n, size); - EXPECT_THAT(close(first_fd), SyscallSucceedsWithValue(0)); - first_fd = -1; + EXPECT_THAT(close(connected_.release()), SyscallSucceedsWithValue(0)); t.Join(); // We should have read the whole thing. @@ -480,19 +468,20 @@ TEST_P(TcpSocketTest, BlockingLargeSend) { // Test that polling on a socket with a full send buffer will block. TEST_P(TcpSocketTest, PollWithFullBufferBlocks) { - FillSocketBuffers(first_fd, second_fd); + FillSocketBuffers(connected_.get(), accepted_.get()); // Now polling on the FD with a timeout should return 0 corresponding to no // FDs ready. - struct pollfd poll_fd = {first_fd, POLLOUT, 0}; + struct pollfd poll_fd = {connected_.get(), POLLOUT, 0}; EXPECT_THAT(RetryEINTR(poll)(&poll_fd, 1, 10), SyscallSucceedsWithValue(0)); } TEST_P(TcpSocketTest, ClosedWriteBlockingSocket) { - FillSocketBuffers(first_fd, second_fd); + FillSocketBuffers(connected_.get(), accepted_.get()); constexpr int timeout = 10; struct timeval tv = {.tv_sec = timeout, .tv_usec = 0}; - EXPECT_THAT(setsockopt(first_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)), - SyscallSucceeds()); + EXPECT_THAT( + setsockopt(connected_.get(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)), + SyscallSucceeds()); struct timespec begin; struct timespec end; @@ -502,16 +491,15 @@ TEST_P(TcpSocketTest, ClosedWriteBlockingSocket) { ScopedThread send_thread([this]() { char send_byte; // Expect the send() to be blocked until receive timeout. - ASSERT_THAT(RetryEINTR(send)(first_fd, &send_byte, sizeof(send_byte), 0), - SyscallFailsWithErrno(EAGAIN)); + ASSERT_THAT( + RetryEINTR(send)(connected_.get(), &send_byte, sizeof(send_byte), 0), + SyscallFailsWithErrno(EAGAIN)); }); // Wait for the thread to be blocked on write. absl::SleepFor(absl::Milliseconds(250)); // Socket close does not have any effect on a blocked write. - ASSERT_THAT(close(first_fd), SyscallSucceeds()); - // Indicate to the cleanup routine that we are already closed. - first_fd = -1; + ASSERT_THAT(close(connected_.release()), SyscallSucceeds()); send_thread.Join(); @@ -524,8 +512,9 @@ TEST_P(TcpSocketTest, ClosedWriteBlockingSocket) { TEST_P(TcpSocketTest, ClosedReadBlockingSocket) { constexpr int timeout = 10; struct timeval tv = {.tv_sec = timeout, .tv_usec = 0}; - EXPECT_THAT(setsockopt(first_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)), - SyscallSucceeds()); + EXPECT_THAT( + setsockopt(connected_.get(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)), + SyscallSucceeds()); struct timespec begin; struct timespec end; @@ -535,16 +524,14 @@ TEST_P(TcpSocketTest, ClosedReadBlockingSocket) { ScopedThread read_thread([this]() { char read_byte; // Expect the read() to be blocked until receive timeout. - ASSERT_THAT(read(first_fd, &read_byte, sizeof(read_byte)), + ASSERT_THAT(read(connected_.get(), &read_byte, sizeof(read_byte)), SyscallFailsWithErrno(EAGAIN)); }); // Wait for the thread to be blocked on read. absl::SleepFor(absl::Milliseconds(250)); // Socket close does not have any effect on a blocked read. - ASSERT_THAT(close(first_fd), SyscallSucceeds()); - // Indicate to the cleanup routine that we are already closed. - first_fd = -1; + ASSERT_THAT(close(connected_.release()), SyscallSucceeds()); read_thread.Join(); @@ -557,10 +544,11 @@ TEST_P(TcpSocketTest, ClosedReadBlockingSocket) { TEST_P(TcpSocketTest, MsgTrunc) { char sent_data[512]; RandomizeBuffer(sent_data, sizeof(sent_data)); - ASSERT_THAT(RetryEINTR(send)(first_fd, sent_data, sizeof(sent_data), 0), - SyscallSucceedsWithValue(sizeof(sent_data))); + ASSERT_THAT( + RetryEINTR(send)(connected_.get(), sent_data, sizeof(sent_data), 0), + SyscallSucceedsWithValue(sizeof(sent_data))); char received_data[sizeof(sent_data)] = {}; - ASSERT_THAT(RetryEINTR(recv)(second_fd, received_data, + ASSERT_THAT(RetryEINTR(recv)(accepted_.get(), received_data, sizeof(received_data) / 2, MSG_TRUNC), SyscallSucceedsWithValue(sizeof(sent_data) / 2)); @@ -574,12 +562,13 @@ TEST_P(TcpSocketTest, MsgTrunc) { TEST_P(TcpSocketTest, MsgTruncWithCtrunc) { char sent_data[512]; RandomizeBuffer(sent_data, sizeof(sent_data)); - ASSERT_THAT(RetryEINTR(send)(first_fd, sent_data, sizeof(sent_data), 0), - SyscallSucceedsWithValue(sizeof(sent_data))); + ASSERT_THAT( + RetryEINTR(send)(connected_.get(), sent_data, sizeof(sent_data), 0), + SyscallSucceedsWithValue(sizeof(sent_data))); char received_data[sizeof(sent_data)] = {}; ASSERT_THAT( - RetryEINTR(recv)(second_fd, received_data, sizeof(received_data) / 2, - MSG_TRUNC | MSG_CTRUNC), + RetryEINTR(recv)(accepted_.get(), received_data, + sizeof(received_data) / 2, MSG_TRUNC | MSG_CTRUNC), SyscallSucceedsWithValue(sizeof(sent_data) / 2)); // Check that we didn't get anything. @@ -592,10 +581,11 @@ TEST_P(TcpSocketTest, MsgTruncWithCtrunc) { TEST_P(TcpSocketTest, MsgTruncWithCtruncOnly) { char sent_data[512]; RandomizeBuffer(sent_data, sizeof(sent_data)); - ASSERT_THAT(RetryEINTR(send)(first_fd, sent_data, sizeof(sent_data), 0), - SyscallSucceedsWithValue(sizeof(sent_data))); + ASSERT_THAT( + RetryEINTR(send)(connected_.get(), sent_data, sizeof(sent_data), 0), + SyscallSucceedsWithValue(sizeof(sent_data))); char received_data[sizeof(sent_data)] = {}; - ASSERT_THAT(RetryEINTR(recv)(second_fd, received_data, + ASSERT_THAT(RetryEINTR(recv)(accepted_.get(), received_data, sizeof(received_data) / 2, MSG_CTRUNC), SyscallSucceedsWithValue(sizeof(sent_data) / 2)); @@ -606,11 +596,12 @@ TEST_P(TcpSocketTest, MsgTruncWithCtruncOnly) { TEST_P(TcpSocketTest, MsgTruncLargeSize) { char sent_data[512]; RandomizeBuffer(sent_data, sizeof(sent_data)); - ASSERT_THAT(RetryEINTR(send)(first_fd, sent_data, sizeof(sent_data), 0), - SyscallSucceedsWithValue(sizeof(sent_data))); + ASSERT_THAT( + RetryEINTR(send)(connected_.get(), sent_data, sizeof(sent_data), 0), + SyscallSucceedsWithValue(sizeof(sent_data))); char received_data[sizeof(sent_data) * 2] = {}; - ASSERT_THAT(RetryEINTR(recv)(second_fd, received_data, sizeof(received_data), - MSG_TRUNC), + ASSERT_THAT(RetryEINTR(recv)(accepted_.get(), received_data, + sizeof(received_data), MSG_TRUNC), SyscallSucceedsWithValue(sizeof(sent_data))); // Check that we didn't get anything. @@ -621,10 +612,11 @@ TEST_P(TcpSocketTest, MsgTruncLargeSize) { TEST_P(TcpSocketTest, MsgTruncPeek) { char sent_data[512]; RandomizeBuffer(sent_data, sizeof(sent_data)); - ASSERT_THAT(RetryEINTR(send)(first_fd, sent_data, sizeof(sent_data), 0), - SyscallSucceedsWithValue(sizeof(sent_data))); + ASSERT_THAT( + RetryEINTR(send)(connected_.get(), sent_data, sizeof(sent_data), 0), + SyscallSucceedsWithValue(sizeof(sent_data))); char received_data[sizeof(sent_data)] = {}; - ASSERT_THAT(RetryEINTR(recv)(second_fd, received_data, + ASSERT_THAT(RetryEINTR(recv)(accepted_.get(), received_data, sizeof(received_data) / 2, MSG_TRUNC | MSG_PEEK), SyscallSucceedsWithValue(sizeof(sent_data) / 2)); @@ -633,39 +625,42 @@ TEST_P(TcpSocketTest, MsgTruncPeek) { EXPECT_EQ(0, memcmp(zeros, received_data, sizeof(received_data))); // Check that we can still get all of the data. - ASSERT_THAT( - RetryEINTR(recv)(second_fd, received_data, sizeof(received_data), 0), - SyscallSucceedsWithValue(sizeof(sent_data))); + ASSERT_THAT(RetryEINTR(recv)(accepted_.get(), received_data, + sizeof(received_data), 0), + SyscallSucceedsWithValue(sizeof(sent_data))); EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data))); } TEST_P(TcpSocketTest, NoDelayDefault) { int get = -1; socklen_t get_len = sizeof(get); - EXPECT_THAT(getsockopt(first_fd, IPPROTO_TCP, TCP_NODELAY, &get, &get_len), - SyscallSucceedsWithValue(0)); + EXPECT_THAT( + getsockopt(connected_.get(), IPPROTO_TCP, TCP_NODELAY, &get, &get_len), + SyscallSucceedsWithValue(0)); EXPECT_EQ(get_len, sizeof(get)); EXPECT_EQ(get, kSockOptOff); } TEST_P(TcpSocketTest, SetNoDelay) { - ASSERT_THAT(setsockopt(first_fd, IPPROTO_TCP, TCP_NODELAY, &kSockOptOn, - sizeof(kSockOptOn)), + ASSERT_THAT(setsockopt(connected_.get(), IPPROTO_TCP, TCP_NODELAY, + &kSockOptOn, sizeof(kSockOptOn)), SyscallSucceeds()); int get = -1; socklen_t get_len = sizeof(get); - EXPECT_THAT(getsockopt(first_fd, IPPROTO_TCP, TCP_NODELAY, &get, &get_len), - SyscallSucceedsWithValue(0)); + EXPECT_THAT( + getsockopt(connected_.get(), IPPROTO_TCP, TCP_NODELAY, &get, &get_len), + SyscallSucceedsWithValue(0)); EXPECT_EQ(get_len, sizeof(get)); EXPECT_EQ(get, kSockOptOn); - ASSERT_THAT(setsockopt(first_fd, IPPROTO_TCP, TCP_NODELAY, &kSockOptOff, - sizeof(kSockOptOff)), + ASSERT_THAT(setsockopt(connected_.get(), IPPROTO_TCP, TCP_NODELAY, + &kSockOptOff, sizeof(kSockOptOff)), SyscallSucceeds()); - EXPECT_THAT(getsockopt(first_fd, IPPROTO_TCP, TCP_NODELAY, &get, &get_len), - SyscallSucceedsWithValue(0)); + EXPECT_THAT( + getsockopt(connected_.get(), IPPROTO_TCP, TCP_NODELAY, &get, &get_len), + SyscallSucceedsWithValue(0)); EXPECT_EQ(get_len, sizeof(get)); EXPECT_EQ(get, kSockOptOff); } @@ -676,33 +671,33 @@ TEST_P(TcpSocketTest, SetNoDelay) { TEST_P(TcpSocketTest, TcpInqSetSockOpt) { char buf[1024]; - ASSERT_THAT(RetryEINTR(write)(first_fd, buf, sizeof(buf)), + ASSERT_THAT(RetryEINTR(write)(connected_.get(), buf, sizeof(buf)), SyscallSucceedsWithValue(sizeof(buf))); // TCP_INQ is disabled by default. int val = -1; socklen_t slen = sizeof(val); - EXPECT_THAT(getsockopt(second_fd, SOL_TCP, TCP_INQ, &val, &slen), + EXPECT_THAT(getsockopt(accepted_.get(), SOL_TCP, TCP_INQ, &val, &slen), SyscallSucceedsWithValue(0)); ASSERT_EQ(val, 0); // Try to set TCP_INQ. val = 1; - EXPECT_THAT(setsockopt(second_fd, SOL_TCP, TCP_INQ, &val, sizeof(val)), + EXPECT_THAT(setsockopt(accepted_.get(), SOL_TCP, TCP_INQ, &val, sizeof(val)), SyscallSucceedsWithValue(0)); val = -1; slen = sizeof(val); - EXPECT_THAT(getsockopt(second_fd, SOL_TCP, TCP_INQ, &val, &slen), + EXPECT_THAT(getsockopt(accepted_.get(), SOL_TCP, TCP_INQ, &val, &slen), SyscallSucceedsWithValue(0)); ASSERT_EQ(val, 1); // Try to unset TCP_INQ. val = 0; - EXPECT_THAT(setsockopt(second_fd, SOL_TCP, TCP_INQ, &val, sizeof(val)), + EXPECT_THAT(setsockopt(accepted_.get(), SOL_TCP, TCP_INQ, &val, sizeof(val)), SyscallSucceedsWithValue(0)); val = -1; slen = sizeof(val); - EXPECT_THAT(getsockopt(second_fd, SOL_TCP, TCP_INQ, &val, &slen), + EXPECT_THAT(getsockopt(accepted_.get(), SOL_TCP, TCP_INQ, &val, &slen), SyscallSucceedsWithValue(0)); ASSERT_EQ(val, 0); } @@ -713,18 +708,18 @@ TEST_P(TcpSocketTest, TcpInq) { int size = sizeof(buf); int kChunk = sizeof(buf) / 4; for (int i = 0; i < size; i += kChunk) { - ASSERT_THAT(RetryEINTR(write)(first_fd, buf, kChunk), + ASSERT_THAT(RetryEINTR(write)(connected_.get(), buf, kChunk), SyscallSucceedsWithValue(kChunk)); } int val = 1; kChunk = sizeof(buf) / 2; - EXPECT_THAT(setsockopt(second_fd, SOL_TCP, TCP_INQ, &val, sizeof(val)), + EXPECT_THAT(setsockopt(accepted_.get(), SOL_TCP, TCP_INQ, &val, sizeof(val)), SyscallSucceedsWithValue(0)); // Wait when all data will be in the received queue. while (true) { - ASSERT_THAT(ioctl(second_fd, TIOCINQ, &size), SyscallSucceeds()); + ASSERT_THAT(ioctl(accepted_.get(), TIOCINQ, &size), SyscallSucceeds()); if (size == sizeof(buf)) { break; } @@ -743,7 +738,7 @@ TEST_P(TcpSocketTest, TcpInq) { iov.iov_len = kChunk; msg.msg_iov = &iov; msg.msg_iovlen = 1; - ASSERT_THAT(RetryEINTR(recvmsg)(second_fd, &msg, 0), + ASSERT_THAT(RetryEINTR(recvmsg)(accepted_.get(), &msg, 0), SyscallSucceedsWithValue(kChunk)); size -= kChunk; @@ -762,7 +757,7 @@ TEST_P(TcpSocketTest, TcpInq) { TEST_P(TcpSocketTest, Tiocinq) { char buf[1024]; size_t size = sizeof(buf); - ASSERT_THAT(RetryEINTR(write)(first_fd, buf, size), + ASSERT_THAT(RetryEINTR(write)(connected_.get(), buf, size), SyscallSucceedsWithValue(size)); uint32_t seed = time(nullptr); @@ -770,26 +765,26 @@ TEST_P(TcpSocketTest, Tiocinq) { while (size > 0) { size_t chunk = (rand_r(&seed) % max_chunk) + 1; ssize_t read = - RetryEINTR(recvfrom)(second_fd, buf, chunk, 0, nullptr, nullptr); + RetryEINTR(recvfrom)(accepted_.get(), buf, chunk, 0, nullptr, nullptr); ASSERT_THAT(read, SyscallSucceeds()); size -= read; int inq = 0; - ASSERT_THAT(ioctl(second_fd, TIOCINQ, &inq), SyscallSucceeds()); + ASSERT_THAT(ioctl(accepted_.get(), TIOCINQ, &inq), SyscallSucceeds()); ASSERT_EQ(inq, size); } } TEST_P(TcpSocketTest, TcpSCMPriority) { char buf[1024]; - ASSERT_THAT(RetryEINTR(write)(first_fd, buf, sizeof(buf)), + ASSERT_THAT(RetryEINTR(write)(connected_.get(), buf, sizeof(buf)), SyscallSucceedsWithValue(sizeof(buf))); int val = 1; - EXPECT_THAT(setsockopt(second_fd, SOL_TCP, TCP_INQ, &val, sizeof(val)), + EXPECT_THAT(setsockopt(accepted_.get(), SOL_TCP, TCP_INQ, &val, sizeof(val)), SyscallSucceedsWithValue(0)); EXPECT_THAT( - setsockopt(second_fd, SOL_SOCKET, SO_TIMESTAMP, &val, sizeof(val)), + setsockopt(accepted_.get(), SOL_SOCKET, SO_TIMESTAMP, &val, sizeof(val)), SyscallSucceedsWithValue(0)); struct msghdr msg = {}; @@ -803,7 +798,7 @@ TEST_P(TcpSocketTest, TcpSCMPriority) { iov.iov_len = sizeof(buf); msg.msg_iov = &iov; msg.msg_iovlen = 1; - ASSERT_THAT(RetryEINTR(recvmsg)(second_fd, &msg, 0), + ASSERT_THAT(RetryEINTR(recvmsg)(accepted_.get(), &msg, 0), SyscallSucceedsWithValue(sizeof(buf))); struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); @@ -830,24 +825,24 @@ TEST_P(TcpSocketTest, TcpSCMPriority) { } TEST_P(TcpSocketTest, TimeWaitPollHUP) { - shutdown(first_fd, SHUT_RDWR); + shutdown(connected_.get(), SHUT_RDWR); ScopedThread t([&]() { constexpr int kTimeout = 10000; constexpr int16_t want_events = POLLHUP; struct pollfd pfd = { - .fd = first_fd, + .fd = connected_.get(), .events = want_events, }; ASSERT_THAT(poll(&pfd, 1, kTimeout), SyscallSucceedsWithValue(1)); }); - shutdown(second_fd, SHUT_RDWR); + shutdown(accepted_.get(), SHUT_RDWR); t.Join(); // At this point first_fd should be in TIME-WAIT and polling for POLLHUP // should return with 1 FD. constexpr int kTimeout = 10000; constexpr int16_t want_events = POLLHUP; struct pollfd pfd = { - .fd = first_fd, + .fd = connected_.get(), .events = want_events, }; ASSERT_THAT(poll(&pfd, 1, kTimeout), SyscallSucceedsWithValue(1)); @@ -911,36 +906,37 @@ TEST_P(SimpleTcpSocketTest, GetPeerNameUnconnected) { TEST_P(TcpSocketTest, FullBuffer) { // Set both FDs to be blocking. int flags = 0; - ASSERT_THAT(flags = fcntl(first_fd, F_GETFL), SyscallSucceeds()); - EXPECT_THAT(fcntl(first_fd, F_SETFL, flags & ~O_NONBLOCK), SyscallSucceeds()); + ASSERT_THAT(flags = fcntl(connected_.get(), F_GETFL), SyscallSucceeds()); + EXPECT_THAT(fcntl(connected_.get(), F_SETFL, flags & ~O_NONBLOCK), + SyscallSucceeds()); flags = 0; - ASSERT_THAT(flags = fcntl(second_fd, F_GETFL), SyscallSucceeds()); - EXPECT_THAT(fcntl(second_fd, F_SETFL, flags & ~O_NONBLOCK), + ASSERT_THAT(flags = fcntl(accepted_.get(), F_GETFL), SyscallSucceeds()); + EXPECT_THAT(fcntl(accepted_.get(), F_SETFL, flags & ~O_NONBLOCK), SyscallSucceeds()); // 2500 was chosen as a small value that can be set on Linux. int set_snd = 2500; - EXPECT_THAT( - setsockopt(first_fd, SOL_SOCKET, SO_SNDBUF, &set_snd, sizeof(set_snd)), - SyscallSucceedsWithValue(0)); + EXPECT_THAT(setsockopt(connected_.get(), SOL_SOCKET, SO_SNDBUF, &set_snd, + sizeof(set_snd)), + SyscallSucceedsWithValue(0)); int get_snd = -1; socklen_t get_snd_len = sizeof(get_snd); - EXPECT_THAT( - getsockopt(first_fd, SOL_SOCKET, SO_SNDBUF, &get_snd, &get_snd_len), - SyscallSucceedsWithValue(0)); + EXPECT_THAT(getsockopt(connected_.get(), SOL_SOCKET, SO_SNDBUF, &get_snd, + &get_snd_len), + SyscallSucceedsWithValue(0)); EXPECT_EQ(get_snd_len, sizeof(get_snd)); EXPECT_GT(get_snd, 0); // 2500 was chosen as a small value that can be set on Linux and gVisor. int set_rcv = 2500; - EXPECT_THAT( - setsockopt(second_fd, SOL_SOCKET, SO_RCVBUF, &set_rcv, sizeof(set_rcv)), - SyscallSucceedsWithValue(0)); + EXPECT_THAT(setsockopt(accepted_.get(), SOL_SOCKET, SO_RCVBUF, &set_rcv, + sizeof(set_rcv)), + SyscallSucceedsWithValue(0)); int get_rcv = -1; socklen_t get_rcv_len = sizeof(get_rcv); - EXPECT_THAT( - getsockopt(second_fd, SOL_SOCKET, SO_RCVBUF, &get_rcv, &get_rcv_len), - SyscallSucceedsWithValue(0)); + EXPECT_THAT(getsockopt(accepted_.get(), SOL_SOCKET, SO_RCVBUF, &get_rcv, + &get_rcv_len), + SyscallSucceedsWithValue(0)); EXPECT_EQ(get_rcv_len, sizeof(get_rcv)); EXPECT_GE(get_rcv, 2500); @@ -957,30 +953,30 @@ TEST_P(TcpSocketTest, FullBuffer) { } ScopedThread t([this, &iovecs]() { int result = -1; - EXPECT_THAT( - result = RetryEINTR(writev)(first_fd, iovecs.data(), iovecs.size()), - SyscallSucceeds()); + EXPECT_THAT(result = RetryEINTR(writev)(connected_.get(), iovecs.data(), + iovecs.size()), + SyscallSucceeds()); EXPECT_GT(result, 1); EXPECT_LT(result, sizeof(data) * iovecs.size()); }); char recv = 0; - EXPECT_THAT(RetryEINTR(read)(second_fd, &recv, 1), + EXPECT_THAT(RetryEINTR(read)(accepted_.get(), &recv, 1), SyscallSucceedsWithValue(1)); - EXPECT_THAT(close(second_fd), SyscallSucceedsWithValue(0)); - second_fd = -1; + EXPECT_THAT(close(accepted_.release()), SyscallSucceedsWithValue(0)); } TEST_P(TcpSocketTest, PollAfterShutdown) { ScopedThread client_thread([this]() { - EXPECT_THAT(shutdown(first_fd, SHUT_WR), SyscallSucceedsWithValue(0)); - struct pollfd poll_fd = {first_fd, POLLIN | POLLERR | POLLHUP, 0}; + EXPECT_THAT(shutdown(connected_.get(), SHUT_WR), + SyscallSucceedsWithValue(0)); + struct pollfd poll_fd = {connected_.get(), POLLIN | POLLERR | POLLHUP, 0}; EXPECT_THAT(RetryEINTR(poll)(&poll_fd, 1, 10000), SyscallSucceedsWithValue(1)); }); - EXPECT_THAT(shutdown(second_fd, SHUT_WR), SyscallSucceedsWithValue(0)); - struct pollfd poll_fd = {second_fd, POLLIN | POLLERR | POLLHUP, 0}; + EXPECT_THAT(shutdown(accepted_.get(), SHUT_WR), SyscallSucceedsWithValue(0)); + struct pollfd poll_fd = {accepted_.get(), POLLIN | POLLERR | POLLHUP, 0}; EXPECT_THAT(RetryEINTR(poll)(&poll_fd, 1, 10000), SyscallSucceedsWithValue(1)); } @@ -2091,8 +2087,9 @@ TEST_P(SimpleTcpSocketTest, CloseNonConnectedLingerOption) { TEST_P(TcpSocketTest, GetSocketAcceptConnListener) { int got = -1; socklen_t length = sizeof(got); - ASSERT_THAT(getsockopt(listener_, SOL_SOCKET, SO_ACCEPTCONN, &got, &length), - SyscallSucceeds()); + ASSERT_THAT( + getsockopt(listener_.get(), SOL_SOCKET, SO_ACCEPTCONN, &got, &length), + SyscallSucceeds()); ASSERT_EQ(length, sizeof(got)); EXPECT_EQ(got, 1); } @@ -2101,13 +2098,15 @@ TEST_P(TcpSocketTest, GetSocketAcceptConnListener) { TEST_P(TcpSocketTest, GetSocketAcceptConnNonListener) { int got = -1; socklen_t length = sizeof(got); - ASSERT_THAT(getsockopt(first_fd, SOL_SOCKET, SO_ACCEPTCONN, &got, &length), - SyscallSucceeds()); + ASSERT_THAT( + getsockopt(connected_.get(), SOL_SOCKET, SO_ACCEPTCONN, &got, &length), + SyscallSucceeds()); ASSERT_EQ(length, sizeof(got)); EXPECT_EQ(got, 0); - ASSERT_THAT(getsockopt(second_fd, SOL_SOCKET, SO_ACCEPTCONN, &got, &length), - SyscallSucceeds()); + ASSERT_THAT( + getsockopt(accepted_.get(), SOL_SOCKET, SO_ACCEPTCONN, &got, &length), + SyscallSucceeds()); ASSERT_EQ(length, sizeof(got)); EXPECT_EQ(got, 0); } @@ -2403,24 +2402,24 @@ TEST_P(SimpleTcpSocketTest, SynRcvdOnListenerShutdown) { TEST_P(TcpSocketTest, SendUnblocksOnSendBufferIncrease) { // Set the FD to O_NONBLOCK. int opts; - ASSERT_THAT(opts = fcntl(first_fd, F_GETFL), SyscallSucceeds()); + ASSERT_THAT(opts = fcntl(connected_.get(), F_GETFL), SyscallSucceeds()); opts |= O_NONBLOCK; - ASSERT_THAT(fcntl(first_fd, F_SETFL, opts), SyscallSucceeds()); + ASSERT_THAT(fcntl(connected_.get(), F_SETFL, opts), SyscallSucceeds()); // Get maximum buffer size by trying to set it to a large value. constexpr int kSndBufSz = 0xffffffff; - ASSERT_THAT(setsockopt(first_fd, SOL_SOCKET, SO_SNDBUF, &kSndBufSz, + ASSERT_THAT(setsockopt(connected_.get(), SOL_SOCKET, SO_SNDBUF, &kSndBufSz, sizeof(kSndBufSz)), SyscallSucceeds()); int max_buffer_sz = 0; socklen_t max_len = sizeof(max_buffer_sz); - ASSERT_THAT( - getsockopt(first_fd, SOL_SOCKET, SO_SNDBUF, &max_buffer_sz, &max_len), - SyscallSucceeds()); + ASSERT_THAT(getsockopt(connected_.get(), SOL_SOCKET, SO_SNDBUF, + &max_buffer_sz, &max_len), + SyscallSucceeds()); int buffer_sz = max_buffer_sz >> 2; - EXPECT_THAT(setsockopt(first_fd, SOL_SOCKET, SO_SNDBUF, &buffer_sz, + EXPECT_THAT(setsockopt(connected_.get(), SOL_SOCKET, SO_SNDBUF, &buffer_sz, sizeof(buffer_sz)), SyscallSucceedsWithValue(0)); @@ -2428,7 +2427,8 @@ TEST_P(TcpSocketTest, SendUnblocksOnSendBufferIncrease) { std::vector buffer(max_buffer_sz); // Write until we receive an error. - while (RetryEINTR(send)(first_fd, buffer.data(), buffer.size(), 0) != -1) { + while (RetryEINTR(send)(connected_.get(), buffer.data(), buffer.size(), 0) != + -1) { // Sleep to give linux a chance to move data from the send buffer to the // receive buffer. usleep(10000); // 10ms. @@ -2439,19 +2439,19 @@ TEST_P(TcpSocketTest, SendUnblocksOnSendBufferIncrease) { ScopedThread send_thread([this]() { int flags = 0; - ASSERT_THAT(flags = fcntl(first_fd, F_GETFL), SyscallSucceeds()); - EXPECT_THAT(fcntl(first_fd, F_SETFL, flags & ~O_NONBLOCK), + ASSERT_THAT(flags = fcntl(connected_.get(), F_GETFL), SyscallSucceeds()); + EXPECT_THAT(fcntl(connected_.get(), F_SETFL, flags & ~O_NONBLOCK), SyscallSucceeds()); // Expect the send() to succeed. char buffer; - ASSERT_THAT(RetryEINTR(send)(first_fd, &buffer, sizeof(buffer), 0), + ASSERT_THAT(RetryEINTR(send)(connected_.get(), &buffer, sizeof(buffer), 0), SyscallSucceeds()); }); // Set SO_SNDBUF to maximum buffer size allowed. buffer_sz = max_buffer_sz >> 1; - EXPECT_THAT(setsockopt(first_fd, SOL_SOCKET, SO_SNDBUF, &buffer_sz, + EXPECT_THAT(setsockopt(connected_.get(), SOL_SOCKET, SO_SNDBUF, &buffer_sz, sizeof(buffer_sz)), SyscallSucceedsWithValue(0));