From 0170f02ab082d555722798e00e73be719b2a47ed Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 28 Apr 2025 12:47:39 +0200 Subject: [PATCH] dnsdist: Gracefully handle timeout/response for a closed HTTP stream 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 | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc index 6dd09de922..6c36f6bf74 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc @@ -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); } -- 2.47.2