]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Gracefully handle timeout/response for a closed HTTP stream 15485/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 28 Apr 2025 10:47:39 +0000 (12:47 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 29 Apr 2025 08:44:41 +0000 (10:44 +0200)
The remote end might very well have already closed the HTTP stream
corresponding to the timeout or response we are processing. While
this means we need to discard the event we were processing, it is
not an unexpected event and we should thus not raise an exception
since the caller cannot do anything about it.

(cherry picked from commit c3aab4cebf70815578e8bf449a7bce9d0827289e)

pdns/dnsdistdist/dnsdist-nghttp2-in.cc

index 6dd09de9229feb800b3c074a9463c028ab686901..6c36f6bf7405eb0a18c985079cf83c10627ba9e5 100644 (file)
@@ -552,7 +552,12 @@ IOState IncomingHTTP2Connection::sendResponse(const struct timeval& now, TCPResp
   if (response.d_idstate.d_streamID == -1) {
     throw std::runtime_error("Invalid DoH stream ID while sending response");
   }
-  auto& context = d_currentStreams.at(response.d_idstate.d_streamID);
+  auto streamIt = d_currentStreams.find(response.d_idstate.d_streamID);
+  if (streamIt == d_currentStreams.end()) {
+    /* it might have been closed by the remote end in the meantime */
+    return hasPendingWrite() ? IOState::NeedWrite : IOState::Done;
+  }
+  auto& context = streamIt->second;
 
   uint32_t statusCode = 200U;
   std::string contentType;
@@ -587,7 +592,12 @@ void IncomingHTTP2Connection::notifyIOError(const struct timeval& now, TCPRespon
     throw std::runtime_error("Invalid DoH stream ID while handling I/O error notification");
   }
 
-  auto& context = d_currentStreams.at(response.d_idstate.d_streamID);
+  auto streamIt = d_currentStreams.find(response.d_idstate.d_streamID);
+  if (streamIt == d_currentStreams.end()) {
+    /* it might have been closed by the remote end in the meantime */
+    return;
+  }
+  auto& context = streamIt->second;
   context.d_buffer = std::move(response.d_buffer);
   sendResponse(response.d_idstate.d_streamID, context, 502, d_ci.cs->dohFrontend->d_customResponseHeaders);
 }