Просмотр исходного кода

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.
yhirose 6 дней назад
Родитель
Сommit
148d61a6a3
1 измененных файлов с 6 добавлено и 0 удалено
  1. 6 0
      test/test.cc

+ 6 - 0
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<sockaddr *>(&addr), sizeof(addr)));
     ASSERT_EQ(0, listen(s, 1));
     ASSERT_LE(0, disconnected_svr_sock = accept(s, nullptr, nullptr));