From: Remi Gacogne Date: Wed, 28 Apr 2021 16:26:29 +0000 (+0200) Subject: dnsdist: Properly handle truncation for cross-protocol answers X-Git-Tag: dnsdist-1.7.0-alpha1~45^2~35 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f54c0740b1f9756f585b024f5c593ad94c8954a6;p=thirdparty%2Fpdns.git dnsdist: Properly handle truncation for cross-protocol answers --- diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 73669e2562..8e63525deb 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -1289,7 +1289,7 @@ ProcessQueryResult processQuery(DNSQuestion& dq, ClientState& cs, LocalHolders& class UDPTCPCrossQuerySender : public TCPQuerySender { public: - UDPTCPCrossQuerySender(const ClientState& cs, std::shared_ptr& ds): d_cs(cs), d_ds(ds) + UDPTCPCrossQuerySender(const ClientState& cs, std::shared_ptr& ds, uint16_t payloadSize): d_cs(cs), d_ds(ds), d_payloadSize(payloadSize) { } @@ -1317,6 +1317,11 @@ public: thread_local LocalStateHolder> localRespRuleActions = g_respruleactions.getLocal(); DNSResponse dr = makeDNSResponseFromIDState(ids, response.d_buffer); + if (response.d_buffer.size() > d_payloadSize) { + truncateTC(dr.getMutableData(), dr.getMaximumSize(), dr.qname->wirelength()); + dr.getHeader()->tc = true; + } + dnsheader cleartextDH; memcpy(&cleartextDH, dr.getHeader(), sizeof(cleartextDH)); @@ -1357,6 +1362,7 @@ public: private: const ClientState& d_cs; std::shared_ptr d_ds{nullptr}; + uint16_t d_payloadSize{0}; }; class UDPCrossProtocolQuery : public CrossProtocolQuery @@ -1364,6 +1370,8 @@ class UDPCrossProtocolQuery : public CrossProtocolQuery public: UDPCrossProtocolQuery(PacketBuffer&& buffer, IDState&& ids, std::shared_ptr& ds): d_cs(*ids.cs) { + uint16_t z = 0; + getEDNSUDPPayloadSizeAndZ(reinterpret_cast(buffer.data()), buffer.size(), &d_payloadSize, &z); query = InternalQuery(std::move(buffer), std::move(ids)); downstream = ds; proxyProtocolPayloadSize = 0; @@ -1375,12 +1383,13 @@ public: std::shared_ptr getTCPQuerySender() override { - auto sender = std::make_shared(d_cs, downstream); + auto sender = std::make_shared(d_cs, downstream, d_payloadSize); return sender; } private: const ClientState& d_cs; + uint16_t d_payloadSize{0}; }; static void processUDPQuery(ClientState& cs, LocalHolders& holders, const struct msghdr* msgh, const ComboAddress& remote, ComboAddress& dest, PacketBuffer& query, struct mmsghdr* responsesVect, unsigned int* queuedResponses, struct iovec* respIOV, cmsgbuf_aligned* respCBuf)