]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Fix TCP I/O timeout and callback being used for HTTP/2
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 3 May 2024 13:37:28 +0000 (15:37 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 3 May 2024 13:37:28 +0000 (15:37 +0200)
They were always replaced by the correct HTTP/2 ones anyway, but
it's a lot cleaner that way.

pdns/dnsdistdist/dnsdist-nghttp2-in.cc
pdns/dnsdistdist/dnsdist-nghttp2-in.hh
pdns/dnsdistdist/dnsdist-tcp-upstream.hh
pdns/dnsdistdist/dnsdist-tcp.cc

index f88294168e72d8c58c686793df9d8a0be4360682..e54d7f2f27f8324841604b06d5727beec8e19a76 100644 (file)
@@ -1166,10 +1166,23 @@ boost::optional<struct timeval> IncomingHTTP2Connection::getIdleClientReadTTD(st
   return now;
 }
 
+void IncomingHTTP2Connection::updateIO(std::shared_ptr<IncomingTCPConnectionState>& 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<struct timeval> ttd{boost::none};
 
+  if (newState == IOState::Async) {
+    auto shared = shared_from_this();
+    updateIOForAsync(shared);
+    return;
+  }
+
   auto shared = std::dynamic_pointer_cast<IncomingHTTP2Connection>(shared_from_this());
   if (!shared || !d_ioState) {
     return;
index e63077882c39288d856aea4c02c65025e1f45aeb..d6d16a69186614f77a65242c64179b2a6b9c1c98 100644 (file)
@@ -87,6 +87,7 @@ private:
 
   void stopIO();
   uint32_t getConcurrentStreamsCount() const;
+  void updateIO(std::shared_ptr<IncomingTCPConnectionState>& 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);
index 40ca9335a35479f4543776029d78224c05a21c8b..b6b7a91464ee6774d25da14eed168154134d5439 100644 (file)
@@ -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<IncomingTCPConnectionState>& state, IOState newState, const struct timeval& now);
 
   static void queueResponse(std::shared_ptr<IncomingTCPConnectionState>& state, const struct timeval& now, TCPResponse&& response, bool fromBackend);
   static void handleTimeout(std::shared_ptr<IncomingTCPConnectionState>& state, bool write);
 
   virtual void handleIO();
+  virtual void updateIO(std::shared_ptr<IncomingTCPConnectionState>& conn, IOState newState, const timeval& now);
+  void updateIOForAsync(std::shared_ptr<IncomingTCPConnectionState>& conn);
 
   QueryProcessingResult handleQuery(PacketBuffer&& query, const struct timeval& now, std::optional<int32_t> streamID);
   virtual void handleResponse(const struct timeval& now, TCPResponse&& response) override;
index 27b2a116e0dbab566ddc7659c390d47dd212d618..8cc1c6c2062275349a118bcad0237fb97a65fc6b 100644 (file)
@@ -398,7 +398,7 @@ void IncomingTCPConnectionState::queueResponse(std::shared_ptr<IncomingTCPConnec
 
     // for the same reason we need to update the state right away, nobody will do that for us
     if (state->active()) {
-      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<IncomingTCPConnectionState>& 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<IncomingTCPConnectionState>& 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 */