From: Remi Gacogne Date: Fri, 3 May 2024 13:37:28 +0000 (+0200) Subject: dnsdist: Fix TCP I/O timeout and callback being used for HTTP/2 X-Git-Tag: rec-5.1.0-alpha1~13^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=399424c7c53d4087f260c06ff066f7a6f5aed7df;p=thirdparty%2Fpdns.git dnsdist: Fix TCP I/O timeout and callback being used for HTTP/2 They were always replaced by the correct HTTP/2 ones anyway, but it's a lot cleaner that way. --- diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc index f88294168e..e54d7f2f27 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc @@ -1166,10 +1166,23 @@ boost::optional IncomingHTTP2Connection::getIdleClientReadTTD(st return now; } +void IncomingHTTP2Connection::updateIO(std::shared_ptr& conn, IOState newState, const timeval& now) +{ + (void)conn; + (void)now; + updateIO(newState, newState == IOState::NeedWrite ? handleWritableIOCallback : handleReadableIOCallback); +} + void IncomingHTTP2Connection::updateIO(IOState newState, const FDMultiplexer::callbackfunc_t& callback) { boost::optional ttd{boost::none}; + if (newState == IOState::Async) { + auto shared = shared_from_this(); + updateIOForAsync(shared); + return; + } + auto shared = std::dynamic_pointer_cast(shared_from_this()); if (!shared || !d_ioState) { return; diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.hh b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh index e63077882c..d6d16a6918 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.hh +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh @@ -87,6 +87,7 @@ private: void stopIO(); uint32_t getConcurrentStreamsCount() const; + void updateIO(std::shared_ptr& conn, IOState newState, const timeval& now) override; void updateIO(IOState newState, const FDMultiplexer::callbackfunc_t& callback); void handleIOError(); bool sendResponse(StreamID streamID, PendingQuery& context, uint16_t responseCode, const HeadersMap& customResponseHeaders, const std::string& contentType = "", bool addContentType = true); diff --git a/pdns/dnsdistdist/dnsdist-tcp-upstream.hh b/pdns/dnsdistdist/dnsdist-tcp-upstream.hh index 40ca9335a3..b6b7a91464 100644 --- a/pdns/dnsdistdist/dnsdist-tcp-upstream.hh +++ b/pdns/dnsdistdist/dnsdist-tcp-upstream.hh @@ -125,12 +125,13 @@ public: static void handleIOCallback(int desc, FDMultiplexer::funcparam_t& param); static void handleAsyncReady(int desc, FDMultiplexer::funcparam_t& param); - static void updateIO(std::shared_ptr& state, IOState newState, const struct timeval& now); static void queueResponse(std::shared_ptr& state, const struct timeval& now, TCPResponse&& response, bool fromBackend); static void handleTimeout(std::shared_ptr& state, bool write); virtual void handleIO(); + virtual void updateIO(std::shared_ptr& conn, IOState newState, const timeval& now); + void updateIOForAsync(std::shared_ptr& conn); QueryProcessingResult handleQuery(PacketBuffer&& query, const struct timeval& now, std::optional streamID); virtual void handleResponse(const struct timeval& now, TCPResponse&& response) override; diff --git a/pdns/dnsdistdist/dnsdist-tcp.cc b/pdns/dnsdistdist/dnsdist-tcp.cc index 27b2a116e0..8cc1c6c206 100644 --- a/pdns/dnsdistdist/dnsdist-tcp.cc +++ b/pdns/dnsdistdist/dnsdist-tcp.cc @@ -398,7 +398,7 @@ void IncomingTCPConnectionState::queueResponse(std::shared_ptractive()) { - updateIO(state, iostate, now); + state->updateIO(state, iostate, now); // if we have not finished reading every available byte, we _need_ to do an actual read // attempt before waiting for the socket to become readable again, because if there is // buffered data available the socket might never become readable again. @@ -440,18 +440,23 @@ void IncomingTCPConnectionState::handleAsyncReady([[maybe_unused]] int desc, FDM } } +void IncomingTCPConnectionState::updateIOForAsync(std::shared_ptr& conn) +{ + auto fds = conn->d_handler.getAsyncFDs(); + for (const auto desc : fds) { + conn->d_threadData.mplexer->addReadFD(desc, handleAsyncReady, conn); + } + conn->d_ioState->update(IOState::Done, handleIOCallback, conn); +} + void IncomingTCPConnectionState::updateIO(std::shared_ptr& state, IOState newState, const struct timeval& now) { if (newState == IOState::Async) { - auto fds = state->d_handler.getAsyncFDs(); - for (const auto desc : fds) { - state->d_threadData.mplexer->addReadFD(desc, handleAsyncReady, state); - } - state->d_ioState->update(IOState::Done, handleIOCallback, state); - } - else { - state->d_ioState->update(newState, handleIOCallback, state, newState == IOState::NeedWrite ? state->getClientWriteTTD(now) : state->getClientReadTTD(now)); + updateIOForAsync(state); + return; } + + state->d_ioState->update(newState, handleIOCallback, state, newState == IOState::NeedWrite ? state->getClientWriteTTD(now) : state->getClientReadTTD(now)); } /* called from the backend code when a new response has been received */