From: Remi Gacogne Date: Thu, 29 Apr 2021 11:28:33 +0000 (+0200) Subject: dnsdist: Do not try to parse non-DNS HTTP answers generated by Lua X-Git-Tag: dnsdist-1.7.0-alpha1~45^2~32 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f2db9ae8d91ba0a391ab4161af59db694571ed6d;p=thirdparty%2Fpdns.git dnsdist: Do not try to parse non-DNS HTTP answers generated by Lua --- diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index 087bf7cfd0..a2d7ef3a46 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -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(response.data()), response.size()); if (minTTL != std::numeric_limits::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(du->response.data()); + if (!du->tcp && du->truncated && du->response.size() > sizeof(dnsheader)) { + /* restoring the original ID */ + dnsheader* queryDH = reinterpret_cast(du->query.data() + du->proxyProtocolPayloadSize); + queryDH->id = htons(du->ids.origID); - if (dh->tc) { - /* restoring the original ID */ - dnsheader* queryDH = reinterpret_cast(du->query.data()); - queryDH->id = htons(du->ids.origID); + auto cpq = std::make_unique(du); - auto cpq = std::make_unique(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 */ diff --git a/pdns/doh.hh b/pdns/doh.hh index de8f67f42d..a30a0ac6f9 100644 --- a/pdns/doh.hh +++ b/pdns/doh.hh @@ -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;