From: Remi Gacogne Date: Fri, 24 Jun 2022 16:49:04 +0000 (+0200) Subject: dnsdist: Rewrite packets to remove records only if actually needed X-Git-Tag: rec-4.9.0-alpha0~19^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6b9508c78415e215b9c43585c91fa0622513bb25;p=thirdparty%2Fpdns.git dnsdist: Rewrite packets to remove records only if actually needed --- diff --git a/pdns/dnsparser.cc b/pdns/dnsparser.cc index 2e21461208..931a3a2f24 100644 --- a/pdns/dnsparser.cc +++ b/pdns/dnsparser.cc @@ -745,6 +745,42 @@ void editDNSPacketTTL(char* packet, size_t length, const std::function& qtypes) +{ + auto length = packet.size(); + if (length < sizeof(dnsheader)) { + return false; + } + + try { + auto dh = reinterpret_cast(packet.data()); + DNSPacketMangler dpm(const_cast(reinterpret_cast(packet.data())), length); + + const uint16_t qdcount = ntohs(dh->qdcount); + for (size_t n = 0; n < qdcount; ++n) { + dpm.skipDomainName(); + /* type and class */ + dpm.skipBytes(4); + } + const size_t recordsCount = static_cast(ntohs(dh->ancount)) + ntohs(dh->nscount) + ntohs(dh->arcount); + for (size_t n = 0; n < recordsCount; ++n) { + dpm.skipDomainName(); + uint16_t dnstype = dpm.get16BitInt(); + uint16_t dnsclass = dpm.get16BitInt(); + if (dnsclass == QClass::IN && qtypes.count(dnstype) > 0) { + return true; + } + /* ttl */ + dpm.skipBytes(4); + dpm.skipRData(); + } + } + catch (...) { + } + + return false; +} + static int rewritePacketWithoutRecordTypes(const PacketBuffer& initialPacket, PacketBuffer& newContent, const std::set& qtypes) { static const std::set& safeTypes{QType::A, QType::AAAA, QType::DHCID, QType::TXT, QType::OPT, QType::HINFO, QType::DNSKEY, QType::CDNSKEY, QType::DS, QType::CDS, QType::DLV, QType::SSHFP, QType::KEY, QType::CERT, QType::TLSA, QType::SMIMEA, QType::OPENPGPKEY, QType::SVCB, QType::HTTPS, QType::NSEC3, QType::CSYNC, QType::NSEC3PARAM, QType::LOC, QType::NID, QType::L32, QType::L64, QType::EUI48, QType::EUI64, QType::URI, QType::CAA}; @@ -866,6 +902,10 @@ void clearDNSPacketRecordTypes(vector& packet, const std::set& q void clearDNSPacketRecordTypes(PacketBuffer& packet, const std::set& qtypes) { + if (!checkIfPacketContainsRecords(packet, qtypes)) { + return; + } + PacketBuffer newContent; auto result = rewritePacketWithoutRecordTypes(packet, newContent, qtypes);