From 148d61a6a32bf16170754eb035aeaa476354289e Mon Sep 17 00:00:00 2001 From: yhirose Date: Sun, 2 Aug 2026 19:32:03 -0400 Subject: [PATCH] Give the raw listener in wait_writable_INET the socket options its neighbours have (#2527) SocketStream.wait_writable_INET binds PORT + 1 directly, and it was the only raw listener in the file that did not set SO_REUSEPORT/SO_REUSEADDR first. PORT + 1 is shared with three SSL redirect tests and with VulnerabilityTest.CRLFInjectionInHeaders, so once any of those has run, the TIME_WAIT entries they leave make bind() fail here. That failure did not surface where it happened. The bind runs on a worker thread, where a failed ASSERT_EQ only returns from the lambda, so the test carried on and failed later at ASSERT_NE(disconnected_svr_sock, -1) with nothing pointing at the port. Within one run of the suite the test comes before everything that uses PORT + 1, so a clean run passes; it failed when a previous process had left TIME_WAIT behind, which made it look intermittent. Running any of those four tests first and then this one reproduces it every time: 4 of 4 before this change, 4 of 4 passing after, with up to eight TIME_WAIT entries on the port. Call default_socket_options(), which is what the library does for its own listeners and what the other raw listeners in this file already do. --- test/test.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/test.cc b/test/test.cc index da82ec3..15b1ab1 100644 --- a/test/test.cc +++ b/test/test.cc @@ -301,6 +301,12 @@ TEST(SocketStream, wait_writable_INET) { std::thread svr{[&] { const int s = socket(AF_INET, SOCK_STREAM, 0); ASSERT_LE(0, s); + // PORT + 1 is shared with the SSL redirect tests and with + // VulnerabilityTest.CRLFInjectionInHeaders, all of which set this. Without + // it, a TIME_WAIT one of them left behind makes bind() fail here, and + // because that happens on a worker thread the ASSERT does not stop the + // test: it runs on and fails at the disconnected_svr_sock check instead. + default_socket_options(s); ASSERT_EQ(0, ::bind(s, reinterpret_cast(&addr), sizeof(addr))); ASSERT_EQ(0, listen(s, 1)); ASSERT_LE(0, disconnected_svr_sock = accept(s, nullptr, nullptr));