]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Get rid of allocations in the packet cache's fast path 9420/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 28 Aug 2020 08:42:23 +0000 (10:42 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 28 Aug 2020 08:42:23 +0000 (10:42 +0200)
This delivers a nice speed-up, up to ~40% in unrealistic micro-benchmarks,
likely much less in practice.

pdns/dnsdist-cache.cc
pdns/dnsdist-cache.hh
pdns/fuzz_dnsdistcache.cc

index c31a0a554c05411033d0f88be06bb2b521d4a9c2..9990f5abab20178b608cab6f93c3368fc25da5e3 100644 (file)
@@ -203,7 +203,7 @@ void DNSDistPacketCache::insert(uint32_t key, const boost::optional<Netmask>& su
 
 bool DNSDistPacketCache::get(const DNSQuestion& dq, uint16_t consumed, uint16_t queryId, char* response, uint16_t* responseLen, uint32_t* keyOut, boost::optional<Netmask>& 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<const unsigned char*>(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");
   }
index 966f55cf50fa757ec58063a330078a43e5305c0e..79200c4b3948bc59ee9497301fbe9a77329c42e7 100644 (file)
@@ -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<Netmask>& subnet);
 
 private:
index 8b670fe470d4022ba1ed63a8b8c42365a43ba9c4..b34a0c3e6e2ff5c604181961c03a4c29a85680e1 100644 (file)
@@ -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<const char*>(data), size, sizeof(dnsheader), false, &qtype, &qclass, &consumed);
-    DNSDistPacketCache::getKey(qname.toString(), consumed, data, size, false);
+    const DNSName qname(reinterpret_cast<const char*>(data), size, sizeof(dnsheader), false, &qtype, &qclass, &consumed);
+    DNSDistPacketCache::getKey(qname.getStorage(), consumed, data, size, false);
     boost::optional<Netmask> subnet;
     DNSDistPacketCache::getClientSubnet(reinterpret_cast<const char*>(data), consumed, size, subnet);
   }