mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add test for poll(POLLIN) on TCP around accept
Add a test that asserts that POLLIN is set on a TCP listener when a new connection is available to be accepted and is unset after the connection is actually accepted. PiperOrigin-RevId: 518075095
This commit is contained in:
@@ -994,6 +994,55 @@ TEST_P(TcpSocketTest, PollAfterShutdown) {
|
||||
SyscallSucceedsWithValue(1));
|
||||
}
|
||||
|
||||
TEST_P(SimpleTcpSocketTest, PollAroundAccept) {
|
||||
const FileDescriptor listener =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Socket(GetParam(), SOCK_STREAM, IPPROTO_TCP));
|
||||
sockaddr_storage addr =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(InetLoopbackAddr(GetParam()));
|
||||
socklen_t addrlen = sizeof(addr);
|
||||
|
||||
// Bind to some port.
|
||||
ASSERT_THAT(bind(listener.get(), AsSockAddr(&addr), addrlen),
|
||||
SyscallSucceeds());
|
||||
ASSERT_THAT(listen(listener.get(), SOMAXCONN), SyscallSucceeds());
|
||||
|
||||
// Get the address we're bound to. We need to do this because we're allowing
|
||||
// the stack to pick a port for us.
|
||||
ASSERT_THAT(getsockname(listener.get(), AsSockAddr(&addr), &addrlen),
|
||||
SyscallSucceeds());
|
||||
switch (GetParam()) {
|
||||
case AF_INET:
|
||||
ASSERT_EQ(addrlen, sizeof(sockaddr_in));
|
||||
break;
|
||||
case AF_INET6:
|
||||
ASSERT_EQ(addrlen, sizeof(sockaddr_in6));
|
||||
break;
|
||||
}
|
||||
|
||||
// Before the listener socket receives a connection, it should not be eligible
|
||||
// for reading.
|
||||
struct pollfd poll_fd = {listener.get(), POLLIN, 0};
|
||||
EXPECT_THAT(RetryEINTR(poll)(&poll_fd, /* nfds */ 1, /* timeout */ 0),
|
||||
SyscallSucceedsWithValue(0));
|
||||
|
||||
FileDescriptor connector =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Socket(GetParam(), SOCK_STREAM, IPPROTO_TCP));
|
||||
ASSERT_THAT(RetryEINTR(connect)(connector.get(), AsSockAddr(&addr), addrlen),
|
||||
SyscallSucceeds());
|
||||
|
||||
// Now that a connection is pending, the listener is ready for a read.
|
||||
ASSERT_THAT(
|
||||
RetryEINTR(poll)(&poll_fd, /* nfds */ 1, /* infinite timeout */ -1),
|
||||
SyscallSucceedsWithValue(1));
|
||||
|
||||
// Accept the connection. This should make the listener no longer ready for a
|
||||
// read.
|
||||
const FileDescriptor accepted =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Accept(listener.get(), nullptr, nullptr));
|
||||
EXPECT_THAT(RetryEINTR(poll)(&poll_fd, /* nfds*/ 1, /* timeout */ 0),
|
||||
SyscallSucceedsWithValue(0));
|
||||
}
|
||||
|
||||
TEST_P(SimpleTcpSocketTest, NonBlockingConnectRetry) {
|
||||
const FileDescriptor listener =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Socket(GetParam(), SOCK_STREAM, IPPROTO_TCP));
|
||||
|
||||
Reference in New Issue
Block a user