From: Remi Gacogne Date: Fri, 28 Aug 2020 08:42:23 +0000 (+0200) Subject: dnsdist: Get rid of allocations in the packet cache's fast path X-Git-Tag: rec-4.5.0-alpha0~31^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=83c22ef3ded5bd60058a6f46bf202eb7e8ff4029;p=thirdparty%2Fpdns.git dnsdist: Get rid of allocations in the packet cache's fast path This delivers a nice speed-up, up to ~40% in unrealistic micro-benchmarks, likely much less in practice. --- diff --git a/pdns/dnsdist-cache.cc b/pdns/dnsdist-cache.cc index c31a0a554c..9990f5abab 100644 --- a/pdns/dnsdist-cache.cc +++ b/pdns/dnsdist-cache.cc @@ -203,7 +203,7 @@ void DNSDistPacketCache::insert(uint32_t key, const boost::optional& su bool DNSDistPacketCache::get(const DNSQuestion& dq, uint16_t consumed, uint16_t queryId, char* response, uint16_t* responseLen, uint32_t* keyOut, boost::optional& subnet, bool dnssecOK, uint32_t allowExpired, bool skipAging) { - std::string dnsQName(dq.qname->toDNSString()); + const auto& dnsQName = dq.qname->getStorage(); uint32_t key = getKey(dnsQName, consumed, reinterpret_cast(dq.dh), dq.len, dq.tcp); if (keyOut) @@ -411,15 +411,14 @@ uint32_t DNSDistPacketCache::getMinTTL(const char* packet, uint16_t length, bool return getDNSPacketMinTTL(packet, length, seenNoDataSOA); } -uint32_t DNSDistPacketCache::getKey(const std::string& qname, uint16_t consumed, const unsigned char* packet, uint16_t packetLen, bool tcp) +uint32_t DNSDistPacketCache::getKey(const DNSName::string_t& qname, uint16_t consumed, const unsigned char* packet, uint16_t packetLen, bool tcp) { uint32_t result = 0; /* skip the query ID */ if (packetLen < sizeof(dnsheader)) throw std::range_error("Computing packet cache key for an invalid packet size"); result = burtle(packet + 2, sizeof(dnsheader) - 2, result); - string lc(toLower(qname)); - result = burtle((const unsigned char*) lc.c_str(), lc.length(), result); + result = burtleCI((const unsigned char*) qname.c_str(), qname.length(), result); if (packetLen < sizeof(dnsheader) + consumed) { throw std::range_error("Computing packet cache key for an invalid packet"); } diff --git a/pdns/dnsdist-cache.hh b/pdns/dnsdist-cache.hh index 966f55cf50..79200c4b39 100644 --- a/pdns/dnsdist-cache.hh +++ b/pdns/dnsdist-cache.hh @@ -66,7 +66,7 @@ public: } static uint32_t getMinTTL(const char* packet, uint16_t length, bool* seenNoDataSOA); - static uint32_t getKey(const std::string& qname, uint16_t consumed, const unsigned char* packet, uint16_t packetLen, bool tcp); + static uint32_t getKey(const DNSName::string_t& qname, uint16_t consumed, const unsigned char* packet, uint16_t packetLen, bool tcp); static bool getClientSubnet(const char* packet, unsigned int consumed, uint16_t len, boost::optional& subnet); private: diff --git a/pdns/fuzz_dnsdistcache.cc b/pdns/fuzz_dnsdistcache.cc index 8b670fe470..b34a0c3e6e 100644 --- a/pdns/fuzz_dnsdistcache.cc +++ b/pdns/fuzz_dnsdistcache.cc @@ -35,8 +35,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { uint16_t qtype; uint16_t qclass; unsigned int consumed; - DNSName qname(reinterpret_cast(data), size, sizeof(dnsheader), false, &qtype, &qclass, &consumed); - DNSDistPacketCache::getKey(qname.toString(), consumed, data, size, false); + const DNSName qname(reinterpret_cast(data), size, sizeof(dnsheader), false, &qtype, &qclass, &consumed); + DNSDistPacketCache::getKey(qname.getStorage(), consumed, data, size, false); boost::optional subnet; DNSDistPacketCache::getClientSubnet(reinterpret_cast(data), consumed, size, subnet); }