From cb82b83f26661dced2ab072d8074d1f13c96f065 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 28 Jul 2025 16:31:36 +0200 Subject: [PATCH] dnsdist: Fix the accounting of "killed" streams The way the nghttp2 library works means that we can get notified that a stream has been closed while we are still in the function sending the actual response. This is not a "killed" stream, but just a regular closure. Signed-off-by: Remi Gacogne (cherry picked from commit b81ed956d2f0b6bc538b34ee7e7ad304be233e7a) --- pdns/dnsdistdist/dnsdist-nghttp2-in.cc | 14 +++++++++++--- pdns/dnsdistdist/dnsdist-nghttp2-in.hh | 1 + 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc index 62fde3d9bb..d62846829b 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc @@ -745,17 +745,18 @@ bool IncomingHTTP2Connection::sendResponse(IncomingHTTP2Connection::StreamID str NGHTTP2Headers::addCustomDynamicHeader(headers, key, value); } + context.d_sendingResponse = true; auto ret = nghttp2_submit_response(d_session.get(), streamID, headers.data(), headers.size(), &data_provider); if (ret != 0) { - d_currentStreams.erase(streamID); vinfolog("Error submitting HTTP response for stream %d: %s", streamID, nghttp2_strerror(ret)); + d_currentStreams.erase(streamID); return false; } ret = nghttp2_session_send(d_session.get()); if (ret != 0) { - d_currentStreams.erase(streamID); vinfolog("Error flushing HTTP response for stream %d: %s", streamID, nghttp2_strerror(ret)); + d_currentStreams.erase(streamID); return false; } @@ -951,9 +952,16 @@ int IncomingHTTP2Connection::on_stream_close_callback(nghttp2_session* session, { auto* conn = static_cast(user_data); - if (conn->d_currentStreams.erase(stream_id) > 0) { + auto streamIt = conn->d_currentStreams.find(stream_id); + if (streamIt == conn->d_currentStreams.end()) { + return 0; + } + + if (!streamIt->second.d_sendingResponse) { conn->d_killedStreams.emplace(stream_id); } + + conn->d_currentStreams.erase(streamIt); return 0; } diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.hh b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh index 16da4deb54..4bec5f8c96 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.hh +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh @@ -55,6 +55,7 @@ public: size_t d_queryPos{0}; uint32_t d_statusCode{0}; Method d_method{Method::Unknown}; + bool d_sendingResponse{false}; }; IncomingHTTP2Connection(ConnectionInfo&& connectionInfo, TCPClientThreadData& threadData, const struct timeval& now); -- 2.47.3