mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add test demonstrating accept bug
Updates #3780. PiperOrigin-RevId: 328922573
This commit is contained in:
committed by
gVisor bot
parent
8ae0ab722c
commit
7bc9f9b47f
@@ -1111,6 +1111,82 @@ TEST_P(SocketInetLoopbackTest, AcceptedInheritsTCPUserTimeout) {
|
||||
EXPECT_EQ(get, kUserTimeout);
|
||||
}
|
||||
|
||||
TEST_P(SocketInetLoopbackTest, TCPAcceptAfterReset) {
|
||||
auto const& param = GetParam();
|
||||
TestAddress const& listener = param.listener;
|
||||
TestAddress const& connector = param.connector;
|
||||
|
||||
// Create the listening socket.
|
||||
const FileDescriptor listen_fd = ASSERT_NO_ERRNO_AND_VALUE(
|
||||
Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP));
|
||||
sockaddr_storage listen_addr = listener.addr;
|
||||
ASSERT_THAT(bind(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr),
|
||||
listener.addr_len),
|
||||
SyscallSucceeds());
|
||||
ASSERT_THAT(listen(listen_fd.get(), SOMAXCONN), SyscallSucceeds());
|
||||
|
||||
// Get the port bound by the listening socket.
|
||||
{
|
||||
socklen_t addrlen = listener.addr_len;
|
||||
ASSERT_THAT(
|
||||
getsockname(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr),
|
||||
&addrlen),
|
||||
SyscallSucceeds());
|
||||
}
|
||||
|
||||
const uint16_t port =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(AddrPort(listener.family(), listen_addr));
|
||||
|
||||
// Connect to the listening socket.
|
||||
FileDescriptor conn_fd = ASSERT_NO_ERRNO_AND_VALUE(
|
||||
Socket(connector.family(), SOCK_STREAM, IPPROTO_TCP));
|
||||
|
||||
sockaddr_storage conn_addr = connector.addr;
|
||||
ASSERT_NO_ERRNO(SetAddrPort(connector.family(), &conn_addr, port));
|
||||
ASSERT_THAT(RetryEINTR(connect)(conn_fd.get(),
|
||||
reinterpret_cast<sockaddr*>(&conn_addr),
|
||||
connector.addr_len),
|
||||
SyscallSucceeds());
|
||||
|
||||
// Trigger a RST by turning linger off and closing the socket.
|
||||
struct linger opt = {
|
||||
.l_onoff = 1,
|
||||
.l_linger = 0,
|
||||
};
|
||||
ASSERT_THAT(
|
||||
setsockopt(conn_fd.get(), SOL_SOCKET, SO_LINGER, &opt, sizeof(opt)),
|
||||
SyscallSucceeds());
|
||||
ASSERT_THAT(close(conn_fd.release()), SyscallSucceeds());
|
||||
|
||||
// TODO(gvisor.dev/issue/3780): Remove this.
|
||||
if (IsRunningOnGvisor()) {
|
||||
// Wait for the RST to be observed.
|
||||
absl::SleepFor(absl::Milliseconds(100));
|
||||
}
|
||||
|
||||
sockaddr_storage accept_addr;
|
||||
socklen_t addrlen = sizeof(accept_addr);
|
||||
|
||||
// TODO(gvisor.dev/issue/3780): Remove this.
|
||||
if (IsRunningOnGvisor()) {
|
||||
ASSERT_THAT(accept(listen_fd.get(),
|
||||
reinterpret_cast<sockaddr*>(&accept_addr), &addrlen),
|
||||
SyscallFailsWithErrno(ENOTCONN));
|
||||
return;
|
||||
}
|
||||
|
||||
conn_fd = ASSERT_NO_ERRNO_AND_VALUE(Accept(
|
||||
listen_fd.get(), reinterpret_cast<sockaddr*>(&accept_addr), &addrlen));
|
||||
ASSERT_EQ(addrlen, listener.addr_len);
|
||||
|
||||
int err;
|
||||
socklen_t optlen = sizeof(err);
|
||||
ASSERT_THAT(getsockopt(conn_fd.get(), SOL_SOCKET, SO_ERROR, &err, &optlen),
|
||||
SyscallSucceeds());
|
||||
ASSERT_EQ(err, ECONNRESET);
|
||||
ASSERT_EQ(optlen, sizeof(err));
|
||||
}
|
||||
|
||||
// TODO(gvisor.dev/issue/1688): Partially completed passive endpoints are not
|
||||
// saved. Enable S/R once issue is fixed.
|
||||
TEST_P(SocketInetLoopbackTest, TCPDeferAccept_NoRandomSave) {
|
||||
|
||||
Reference in New Issue
Block a user