From: Remi Gacogne Date: Fri, 11 Dec 2020 10:12:06 +0000 (+0100) Subject: rec: Use a short-lived NSEC3 hashes cache for denial validation X-Git-Tag: rec-4.5.0-alpha1~67^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=dabcae2a1b2223a5c77f9fed28525204b3d303a5;p=thirdparty%2Fpdns.git rec: Use a short-lived NSEC3 hashes cache for denial validation It turns out that computing those SHA1 hashes is far from cheap, and in almost all cases the salt and iterations are identical so no need to compute them several times. --- diff --git a/pdns/validate.cc b/pdns/validate.cc index 154d49f274..f97322a29f 100644 --- a/pdns/validate.cc +++ b/pdns/validate.cc @@ -80,7 +80,9 @@ static bool nsecProvesENT(const DNSName& name, const DNSName& begin, const DNSNa return begin.canonCompare(name) && next != name && next.isPartOf(name); } -static std::string getHashFromNSEC3(const DNSName& qname, const std::shared_ptr& nsec3) +using nsec3HashesCache = std::map, std::string>; + +static std::string getHashFromNSEC3(const DNSName& qname, const std::shared_ptr& nsec3, nsec3HashesCache& cache) { std::string result; @@ -88,7 +90,15 @@ static std::string getHashFromNSEC3(const DNSName& qname, const std::shared_ptr< return result; } - return hashQNameWithSalt(nsec3->d_salt, nsec3->d_iterations, qname); + auto it = cache.find({qname, nsec3->d_salt, nsec3->d_iterations}); + if (it != cache.end()) + { + return it->second; + } + + result = hashQNameWithSalt(nsec3->d_salt, nsec3->d_iterations, qname); + cache[{qname, nsec3->d_salt, nsec3->d_iterations}] = result; + return result; } /* There is no delegation at this exact point if: @@ -99,6 +109,8 @@ static std::string getHashFromNSEC3(const DNSName& qname, const std::shared_ptr< */ bool denialProvesNoDelegation(const DNSName& zone, const std::vector& dsrecords) { + nsec3HashesCache cache; + for (const auto& record : dsrecords) { if (record.d_type == QType::NSEC) { const auto nsec = getRR(record); @@ -120,7 +132,7 @@ bool denialProvesNoDelegation(const DNSName& zone, const std::vector& continue; } - const string h = getHashFromNSEC3(zone, nsec3); + const string h = getHashFromNSEC3(zone, nsec3, cache); if (h.empty()) { return false; } @@ -312,7 +324,7 @@ static bool provesNoWildCard(const DNSName& qname, const uint16_t qtype, const c If `wildcardExists` is not NULL, if will be set to true if a wildcard exists for this qname but doesn't have this qtype. */ -static bool provesNSEC3NoWildCard(DNSName wildcard, uint16_t const qtype, const cspmap_t & validrrsets, bool * wildcardExists=nullptr) +static bool provesNSEC3NoWildCard(DNSName wildcard, uint16_t const qtype, const cspmap_t& validrrsets, bool* wildcardExists, nsec3HashesCache& cache) { wildcard = g_wildcarddnsname + wildcard; LOG("Trying to prove that there is no wildcard for "<