]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Do not try to parse non-DNS HTTP answers generated by Lua
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 29 Apr 2021 11:28:33 +0000 (13:28 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 26 Aug 2021 14:30:27 +0000 (16:30 +0200)
pdns/dnsdistdist/doh.cc
pdns/doh.hh

index 087bf7cfd05364bcf9e85c32830fa94117cfd41b..a2d7ef3a46345815c7af9ab2d83140ec92d2a05d 100644 (file)
@@ -356,7 +356,7 @@ static void handleResponse(DOHFrontend& df, st_h2o_req_t* req, uint16_t statusCo
       }
     }
 
-    if (df.d_sendCacheControlHeaders && !response.empty()) {
+    if (df.d_sendCacheControlHeaders && response.size() > sizeof(dnsheader)) {
       uint32_t minTTL = getDNSPacketMinTTL(reinterpret_cast<const char*>(response.data()), response.size());
       if (minTTL != std::numeric_limits<uint32_t>::max()) {
         std::string cacheControlValue = "max-age=" + std::to_string(minTTL);
@@ -501,6 +501,7 @@ public:
   DoHCrossProtocolQuery(DOHUnit* du_): du(du_)
   {
     query = InternalQuery(std::move(du->query), std::move(du->ids));
+    query.d_proxyProtocolPayloadAdded = du->proxyProtocolPayloadSize > 0;
     downstream = du->downstream;
     proxyProtocolPayloadSize = du->proxyProtocolPayloadSize;
   }
@@ -1287,25 +1288,22 @@ static void on_dnsdist(h2o_socket_t *listener, const char *err)
     return;
   }
 
-  if (!du->response.empty() && !du->tcp) {
-    const dnsheader* dh = reinterpret_cast<const struct dnsheader*>(du->response.data());
+  if (!du->tcp && du->truncated && du->response.size() > sizeof(dnsheader)) {
+    /* restoring the original ID */
+    dnsheader* queryDH = reinterpret_cast<struct dnsheader*>(du->query.data() + du->proxyProtocolPayloadSize);
+    queryDH->id = htons(du->ids.origID);
 
-    if (dh->tc) {
-      /* restoring the original ID */
-      dnsheader* queryDH = reinterpret_cast<struct dnsheader*>(du->query.data());
-      queryDH->id = htons(du->ids.origID);
+    auto cpq = std::make_unique<DoHCrossProtocolQuery>(du);
 
-      auto cpq = std::make_unique<DoHCrossProtocolQuery>(du);
-
-      du->get();
-      du->tcp = true;
+    du->get();
+    du->tcp = true;
+    du->truncated = false;
 
-      if (g_tcpclientthreads && g_tcpclientthreads->passCrossProtocolQueryToThread(std::move(cpq))) {
-        return;
-      }
-      else {
-        du->release();
-      }
+    if (g_tcpclientthreads && g_tcpclientthreads->passCrossProtocolQueryToThread(std::move(cpq))) {
+      return;
+    }
+    else {
+      du->release();
     }
   }
 
@@ -1643,6 +1641,9 @@ void DOHUnit::handleUDPResponse(PacketBuffer&& udpResponse, IDState&& state)
       ++ids.cs->responses;
     }
   }
+  else {
+    truncated = true;
+  }
 
   sendDoHUnitToTheMainThread(this, "DoH response");
   /* the reference counter has been incremented in sendDoHUnitToTheMainThread */
index de8f67f42d9d4960f98c880c4b0165f296ce2752..a30a0ac6f924581121f146103c176240753e2c43 100644 (file)
@@ -235,6 +235,7 @@ struct DOHUnit
   /* whether the query was re-sent to the backend over
      TCP after receiving a truncated answer over UDP */
   bool tcp{false};
+  bool truncated{false};
 
   std::string getHTTPPath() const;
   std::string getHTTPHost() const;