From: Remi Gacogne Date: Mon, 28 Jul 2025 14:31:36 +0000 (+0200) Subject: dnsdist: Fix the accounting of "killed" streams X-Git-Tag: dnsdist-1.9.11~3^2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cb82b83f26661dced2ab072d8074d1f13c96f065;p=thirdparty%2Fpdns.git 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) --- diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc index 62fde3d9b..d62846829 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 16da4deb5..4bec5f8c9 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);