From: Remi Gacogne Date: Tue, 24 Jan 2023 17:23:37 +0000 (+0100) Subject: dnsdist: Rewrite/clear records from DNS packets slightly faster X-Git-Tag: dnsdist-1.8.0-rc1~77^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=953708cbb42b35a1a4ab4fe1f498f8e20839def8;p=thirdparty%2Fpdns.git dnsdist: Rewrite/clear records from DNS packets slightly faster By using `std::unordered_set` instead of `std::set`. --- diff --git a/pdns/dnsdist-lua-actions.cc b/pdns/dnsdist-lua-actions.cc index fe5c5fb80c..fb0695c376 100644 --- a/pdns/dnsdist-lua-actions.cc +++ b/pdns/dnsdist-lua-actions.cc @@ -1762,7 +1762,7 @@ private: class ClearRecordTypesResponseAction : public DNSResponseAction, public boost::noncopyable { public: - ClearRecordTypesResponseAction(const std::set& qtypes) : d_qtypes(qtypes) + ClearRecordTypesResponseAction(const std::unordered_set& qtypes) : d_qtypes(qtypes) { } @@ -1780,7 +1780,7 @@ public: } private: - std::set d_qtypes{}; + std::unordered_set d_qtypes{}; }; class ContinueAction : public DNSAction @@ -2386,7 +2386,7 @@ void setupLuaActions(LuaContext& luaCtx) }); luaCtx.writeFunction("ClearRecordTypesResponseAction", [](LuaTypeOrArrayOf types) { - std::set qtypes{}; + std::unordered_set qtypes{}; if (types.type() == typeid(int)) { qtypes.insert(boost::get(types)); } else if (types.type() == typeid(LuaArray)) { diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi.cc b/pdns/dnsdistdist/dnsdist-lua-ffi.cc index 28738d0aac..9694cec93d 100644 --- a/pdns/dnsdistdist/dnsdist-lua-ffi.cc +++ b/pdns/dnsdistdist/dnsdist-lua-ffi.cc @@ -697,7 +697,7 @@ void dnsdist_ffi_dnsresponse_set_max_returned_ttl(dnsdist_ffi_dnsresponse_t* dr, void dnsdist_ffi_dnsresponse_clear_records_type(dnsdist_ffi_dnsresponse_t* dr, uint16_t qtype) { if (dr != nullptr && dr->dr != nullptr) { - clearDNSPacketRecordTypes(dr->dr->getMutableData(), std::set{qtype}); + clearDNSPacketRecordTypes(dr->dr->getMutableData(), std::unordered_set{qtype}); } } diff --git a/pdns/dnsparser.cc b/pdns/dnsparser.cc index 9a2ee1a599..82d77082a4 100644 --- a/pdns/dnsparser.cc +++ b/pdns/dnsparser.cc @@ -745,7 +745,7 @@ void editDNSPacketTTL(char* packet, size_t length, const std::function& qtypes) +static bool checkIfPacketContainsRecords(const PacketBuffer& packet, const std::unordered_set& qtypes) { auto length = packet.size(); if (length < sizeof(dnsheader)) { @@ -781,9 +781,9 @@ static bool checkIfPacketContainsRecords(const PacketBuffer& packet, const std:: return false; } -static int rewritePacketWithoutRecordTypes(const PacketBuffer& initialPacket, PacketBuffer& newContent, const std::set& qtypes) +static int rewritePacketWithoutRecordTypes(const PacketBuffer& initialPacket, PacketBuffer& newContent, const std::unordered_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}; + static const std::unordered_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}; if (initialPacket.size() < sizeof(dnsheader)) { return EINVAL; @@ -895,12 +895,12 @@ static int rewritePacketWithoutRecordTypes(const PacketBuffer& initialPacket, Pa return 0; } -void clearDNSPacketRecordTypes(vector& packet, const std::set& qtypes) +void clearDNSPacketRecordTypes(vector& packet, const std::unordered_set& qtypes) { return clearDNSPacketRecordTypes(reinterpret_cast(packet), qtypes); } -void clearDNSPacketRecordTypes(PacketBuffer& packet, const std::set& qtypes) +void clearDNSPacketRecordTypes(PacketBuffer& packet, const std::unordered_set& qtypes) { if (!checkIfPacketContainsRecords(packet, qtypes)) { return; diff --git a/pdns/dnsparser.hh b/pdns/dnsparser.hh index 0ac1903be0..1ea93d21b3 100644 --- a/pdns/dnsparser.hh +++ b/pdns/dnsparser.hh @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -472,9 +473,9 @@ string simpleCompress(const string& label, const string& root=""); void ageDNSPacket(char* packet, size_t length, uint32_t seconds); void ageDNSPacket(std::string& packet, uint32_t seconds); void editDNSPacketTTL(char* packet, size_t length, const std::function& visitor); -void clearDNSPacketRecordTypes(vector& packet, const std::set& qtypes); -void clearDNSPacketRecordTypes(PacketBuffer& packet, const std::set& qtypes); -void clearDNSPacketRecordTypes(char* packet, size_t& length, const std::set& qtypes); +void clearDNSPacketRecordTypes(vector& packet, const std::unordered_set& qtypes); +void clearDNSPacketRecordTypes(PacketBuffer& packet, const std::unordered_set& qtypes); +void clearDNSPacketRecordTypes(char* packet, size_t& length, const std::unordered_set& qtypes); uint32_t getDNSPacketMinTTL(const char* packet, size_t length, bool* seenAuthSOA=nullptr); uint32_t getDNSPacketLength(const char* packet, size_t length); uint16_t getRecordsOfTypeCount(const char* packet, size_t length, uint8_t section, uint16_t type); diff --git a/pdns/test-dnsparser_cc.cc b/pdns/test-dnsparser_cc.cc index b040237881..37f97d29fe 100644 --- a/pdns/test-dnsparser_cc.cc +++ b/pdns/test-dnsparser_cc.cc @@ -519,7 +519,7 @@ BOOST_AUTO_TEST_CASE(test_clearDNSPacketRecordTypes) { BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast(packet.data()), packet.size(), 1, QType::AAAA), 1); BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast(packet.data()), packet.size(), 3, QType::A), 1); - std::set toremove{QType::AAAA}; + std::unordered_set toremove{QType::AAAA}; clearDNSPacketRecordTypes(packet, toremove); BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast(packet.data()), packet.size(), 1, QType::A), 1); @@ -591,7 +591,7 @@ BOOST_AUTO_TEST_CASE(test_clearDNSPacketUnsafeRecordTypes) { BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast(packet.data()), packet.size(), 3, QType::A), 1); BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast(packet.data()), packet.size(), 3, QType::MX), 1); - std::set toremove{QType::AAAA}; + std::unordered_set toremove{QType::AAAA}; clearDNSPacketRecordTypes(packet, toremove); // nothing should have been removed as an "unsafe" MX RR is in the packet