]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Better handling of nghttp2 errors
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 17 Apr 2026 10:11:52 +0000 (12:11 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 17 Apr 2026 10:11:52 +0000 (12:11 +0200)
There are a few cases where an error returned by `nghttp2` could
have been silently ignored. Thanks to ilhamaf for reporting this!
As far as I can tell there is no actual impact, except perhaps that
we can detect errors/stale connections earlier, but I haven't been
able to cause any actual problem introduced by not handling these
errors properly.

Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
pdns/dnsdistdist/dnsdist-nghttp2-in.cc
pdns/dnsdistdist/dnsdist-nghttp2.cc

index 1bd69d6823d30ecda804f2048acaef9486643cab..7d2649b24b12f2dc8afc3660cee6f341de371922 100644 (file)
@@ -1245,7 +1245,10 @@ IOState IncomingHTTP2Connection::readHTTPData()
         throw std::runtime_error("Fatal error while passing received data to nghttp2: " + std::string(nghttp2_strerror((int)readlen)));
       }
 
-      nghttp2_session_send(d_session.get());
+      auto sendCode = nghttp2_session_send(d_session.get());
+      if (sendCode != 0) {
+        throw std::runtime_error("Fatal error while flushing HTTP data: " + std::string(nghttp2_strerror(static_cast<int>(sendCode))));
+      }
     }
   }
   catch (const std::exception& e) {
index 5fde5345b76fc0e2e018dc4fb5adb21ab0e06cfb..3edcbd5897c7fb9dd963bb2b772a00de63db71c2 100644 (file)
@@ -403,8 +403,8 @@ void DoHConnectionToBackend::handleReadableIOCallback(int fd, FDMultiplexer::fun
         // cerr<<"nghttp2_session_mem_recv returned "<<readlen<<endl;
         /* as long as we don't require a pause by returning nghttp2_error.NGHTTP2_ERR_PAUSE from a CB,
            all data should be consumed before returning */
-        if (readlen > 0 && static_cast<size_t>(readlen) < conn->d_inPos) {
-          throw std::runtime_error("Fatal error while passing received data to nghttp2: " + std::string(nghttp2_strerror((int)readlen)));
+        if (readlen < 0 || static_cast<size_t>(readlen) < conn->d_inPos) {
+          throw std::runtime_error("Fatal error while passing received data to nghttp2: " + std::string(nghttp2_strerror(static_cast<int>(readlen))));
         }
 
         struct timeval now{
@@ -413,8 +413,10 @@ void DoHConnectionToBackend::handleReadableIOCallback(int fd, FDMultiplexer::fun
         gettimeofday(&now, nullptr);
         conn->d_lastDataReceivedTime = now;
 
-        // cerr<<"after read send"<<endl;
-        nghttp2_session_send(conn->d_session.get());
+        auto sendCode = nghttp2_session_send(conn->d_session.get());
+        if (sendCode != 0) {
+          throw std::runtime_error("Fatal error while flushing HTTP data: " + std::string(nghttp2_strerror(static_cast<int>(sendCode))));
+        }
       }
 
       if (newState == IOState::Done) {