From 89a8a238a9ce0eb4e76bae268d35721ac30a1957 Mon Sep 17 00:00:00 2001 From: Alex Konradi Date: Mon, 3 Oct 2022 09:39:34 -0700 Subject: [PATCH] Use FileDescriptor for TcpSocketTest fixture members Use the FileDescriptor helper class to manage the lifetime of file descriptors held as TcpSocketTest members. This will help prevent leaks if some part of the test setup fails. Also rename `first_fd` and `second_fd` to be a) more meaningfully named and b) conform to Google C++ naming conventions for class members. Updates #8028 PiperOrigin-RevId: 478527874 --- test/syscalls/linux/tcp_socket.cc | 360 +++++++++++++++--------------- 1 file changed, 180 insertions(+), 180 deletions(-) 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));