From f8f66c9103d0d0ff893f28f658791534ac70e674 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 13 Dec 2022 09:30:46 +0100 Subject: [PATCH] Step 3: reformat moved files previously not formatted --- .not-formatted | 15 - pdns/recursordist/filterpo.cc | 100 +- pdns/recursordist/filterpo.hh | 93 +- pdns/recursordist/lazy_allocator.hh | 76 +- pdns/recursordist/lwres.cc | 108 +- pdns/recursordist/lwres.hh | 23 +- pdns/recursordist/mtasker_context.hh | 29 +- pdns/recursordist/mtasker_fcontext.cc | 160 +-- pdns/recursordist/mtasker_ucontext.cc | 165 +-- pdns/recursordist/nod.cc | 32 +- pdns/recursordist/nod.hh | 189 ++-- pdns/recursordist/resolve-context.hh | 7 +- pdns/recursordist/root-addresses.hh | 58 +- pdns/recursordist/rpzloader.cc | 236 +++-- pdns/recursordist/syncres.cc | 1403 +++++++++++++------------ pdns/recursordist/syncres.hh | 214 ++-- 16 files changed, 1510 insertions(+), 1398 deletions(-) diff --git a/.not-formatted b/.not-formatted index 1725c9bdaa..e2be06d1a1 100644 --- a/.not-formatted +++ b/.not-formatted @@ -154,8 +154,6 @@ ./pdns/ednspadding.cc ./pdns/ednssubnet.cc ./pdns/ednssubnet.hh -./pdns/filterpo.cc -./pdns/filterpo.hh ./pdns/fstrm_logger.cc ./pdns/fstrm_logger.hh ./pdns/fuzz_dnsdistcache.cc @@ -183,7 +181,6 @@ ./pdns/json.cc ./pdns/json.hh ./pdns/kvresp.cc -./pdns/lazy_allocator.hh ./pdns/libssl.cc ./pdns/libssl.hh ./pdns/lock.hh @@ -192,8 +189,6 @@ ./pdns/lua-base4.cc ./pdns/lua-base4.hh ./pdns/lua-record.cc -./pdns/lwres.cc -./pdns/lwres.hh ./pdns/malloctrace.cc ./pdns/malloctrace.hh ./pdns/mastercommunicator.cc @@ -203,14 +198,9 @@ ./pdns/misc.hh ./pdns/mtasker.cc ./pdns/mtasker.hh -./pdns/mtasker_context.hh -./pdns/mtasker_fcontext.cc -./pdns/mtasker_ucontext.cc ./pdns/nameserver.cc ./pdns/nameserver.hh ./pdns/namespaces.hh -./pdns/nod.cc -./pdns/nod.hh ./pdns/noinitvector.hh ./pdns/notify.cc ./pdns/nproxy.cc @@ -237,14 +227,11 @@ ./pdns/rcpgenerator.hh ./pdns/remote_logger.cc ./pdns/remote_logger.hh -./pdns/resolve-context.hh ./pdns/resolver.cc ./pdns/resolver.hh ./pdns/responsestats-auth.cc ./pdns/rfc2136handler.cc -./pdns/root-addresses.hh ./pdns/root-dnssec.hh -./pdns/rpzloader.cc ./pdns/saxfr.cc ./pdns/sdig.cc ./pdns/secpoll-auth.cc @@ -277,8 +264,6 @@ ./pdns/stubresolver.cc ./pdns/svc-records.cc ./pdns/svc-records.hh -./pdns/syncres.cc -./pdns/syncres.hh ./pdns/tcpiohandler.cc ./pdns/tcpiohandler.hh ./pdns/tcpreceiver.cc diff --git a/pdns/recursordist/filterpo.cc b/pdns/recursordist/filterpo.cc index 528cacccff..2d2d201a50 100644 --- a/pdns/recursordist/filterpo.cc +++ b/pdns/recursordist/filterpo.cc @@ -111,16 +111,16 @@ bool DNSFilterEngine::Zone::findNamedPolicy(const std::unordered_map::const_iterator iter; iter = polmap.find(qname); - if(iter != polmap.end()) { - pol=iter->second; + if (iter != polmap.end()) { + pol = iter->second; return true; } DNSName s(qname); - while(s.chopOff()){ - iter = polmap.find(g_wildcarddnsname+s); - if(iter != polmap.end()) { - pol=iter->second; + while (s.chopOff()) { + iter = polmap.find(g_wildcarddnsname + s); + if (iter != polmap.end()) { + pol = iter->second; pol.d_trigger = iter->first; pol.d_hit = qname.toStringNoDot(); return true; @@ -146,7 +146,7 @@ bool DNSFilterEngine::Zone::findExactNamedPolicy(const std::unordered_map& discardedPolicies, Policy& pol) const +bool DNSFilterEngine::getProcessingPolicy(const DNSName& qname, const std::unordered_map& discardedPolicies, Policy& pol) const { // cout<<"Got question for nameserver name "< zoneEnabled(d_zones.size()); @@ -182,12 +182,12 @@ bool DNSFilterEngine::getProcessingPolicy(const DNSName& qname, const std::unord std::vector wcNames; wcNames.reserve(qname.countLabels()); DNSName s(qname); - while (s.chopOff()){ - wcNames.emplace_back(g_wildcarddnsname+s); + while (s.chopOff()) { + wcNames.emplace_back(g_wildcarddnsname + s); } count = 0; - for(const auto& z : d_zones) { + for (const auto& z : d_zones) { if (!zoneEnabled[count]) { ++count; continue; @@ -211,10 +211,10 @@ bool DNSFilterEngine::getProcessingPolicy(const DNSName& qname, const std::unord return false; } -bool DNSFilterEngine::getProcessingPolicy(const ComboAddress& address, const std::unordered_map& discardedPolicies, Policy& pol) const +bool DNSFilterEngine::getProcessingPolicy(const ComboAddress& address, const std::unordered_map& discardedPolicies, Policy& pol) const { // cout<<"Got question for nameserver IP "<getPriority() >= pol.getPriority()) { break; } @@ -223,7 +223,7 @@ bool DNSFilterEngine::getProcessingPolicy(const ComboAddress& address, const std continue; } - if(z->findNSIPPolicy(address, pol)) { + if (z->findNSIPPolicy(address, pol)) { // cerr<<"Had a hit on the nameserver ("<& discardedPolicies, Policy& pol) const +bool DNSFilterEngine::getClientPolicy(const ComboAddress& ca, const std::unordered_map& discardedPolicies, Policy& pol) const { // cout<<"Got question from "<& discardedPolicies, Policy& pol) const +bool DNSFilterEngine::getQueryPolicy(const DNSName& qname, const std::unordered_map& discardedPolicies, Policy& pol) const { - //cerr<<"Got question for "< zoneEnabled(d_zones.size()); size_t count = 0; bool allEmpty = true; @@ -261,7 +261,8 @@ bool DNSFilterEngine::getQueryPolicy(const DNSName& qname, const std::unordered_ bool enabled = true; if (z->getPriority() >= pol.getPriority()) { enabled = false; - } else { + } + else { const auto& zoneName = z->getName(); if (discardedPolicies.find(zoneName) != discardedPolicies.end()) { enabled = false; @@ -288,8 +289,8 @@ bool DNSFilterEngine::getQueryPolicy(const DNSName& qname, const std::unordered_ std::vector wcNames; wcNames.reserve(qname.countLabels()); DNSName s(qname); - while (s.chopOff()){ - wcNames.emplace_back(g_wildcarddnsname+s); + while (s.chopOff()) { + wcNames.emplace_back(g_wildcarddnsname + s); } count = 0; @@ -319,7 +320,7 @@ bool DNSFilterEngine::getQueryPolicy(const DNSName& qname, const std::unordered_ return false; } -bool DNSFilterEngine::getPostPolicy(const vector& records, const std::unordered_map& discardedPolicies, Policy& pol) const +bool DNSFilterEngine::getPostPolicy(const vector& records, const std::unordered_map& discardedPolicies, Policy& pol) const { for (const auto& record : records) { if (getPostPolicy(record, discardedPolicies, pol)) { @@ -330,7 +331,7 @@ bool DNSFilterEngine::getPostPolicy(const vector& records, const std: return false; } -bool DNSFilterEngine::getPostPolicy(const DNSRecord& record, const std::unordered_map& discardedPolicies, Policy& pol) const +bool DNSFilterEngine::getPostPolicy(const DNSRecord& record, const std::unordered_map& discardedPolicies, Policy& pol) const { ComboAddress ca; if (record.d_place != DNSResourceRecord::ANSWER) { @@ -342,7 +343,7 @@ bool DNSFilterEngine::getPostPolicy(const DNSRecord& record, const std::unordere ca = rec->getCA(); } } - else if(record.d_type == QType::AAAA) { + else if (record.d_type == QType::AAAA) { if (auto rec = getRR(record)) { ca = rec->getCA(); } @@ -370,11 +371,11 @@ bool DNSFilterEngine::getPostPolicy(const DNSRecord& record, const std::unordere void DNSFilterEngine::assureZones(size_t zone) { - if(d_zones.size() <= zone) - d_zones.resize(zone+1); + if (d_zones.size() <= zone) + d_zones.resize(zone + 1); } -void DNSFilterEngine::Zone::addNameTrigger(std::unordered_map& map, const DNSName& n, Policy&& pol, bool ignoreDuplicate, PolicyType ptype) +void DNSFilterEngine::Zone::addNameTrigger(std::unordered_map& map, const DNSName& n, Policy&& pol, bool ignoreDuplicate, PolicyType ptype) { auto it = map.find(n); @@ -428,7 +429,7 @@ void DNSFilterEngine::Zone::addNetmaskTrigger(NetmaskTree& nmt, const Ne } } -bool DNSFilterEngine::Zone::rmNameTrigger(std::unordered_map& map, const DNSName& n, const Policy& pol) +bool DNSFilterEngine::Zone::rmNameTrigger(std::unordered_map& map, const DNSName& n, const Policy& pol) { auto found = map.find(n); if (found == map.end()) { @@ -551,13 +552,15 @@ bool DNSFilterEngine::Zone::rmNSIPTrigger(const Netmask& nm, const Policy& pol) return rmNetmaskTrigger(d_propolNSAddr, nm, pol); } -std::string DNSFilterEngine::Policy::getLogString() const { +std::string DNSFilterEngine::Policy::getLogString() const +{ return ": RPZ Hit; PolicyName=" + getName() + "; Trigger=" + d_trigger.toLogString() + "; Hit=" + d_hit + "; Type=" + getTypeToString(d_type) + "; Kind=" + getKindToString(d_kind); } -void DNSFilterEngine::Policy::info(Logr::Priority prio, const std::shared_ptr& log) const { +void DNSFilterEngine::Policy::info(Logr::Priority prio, const std::shared_ptr& log) const +{ log->info(prio, "RPZ Hit", "policyName", Logging::Loggable(getName()), "trigger", Logging::Loggable(d_trigger), - "hit", Logging::Loggable(d_hit), "type", Logging::Loggable(getTypeToString(d_type)), + "hit", Logging::Loggable(d_hit), "type", Logging::Loggable(getTypeToString(d_type)), "kind", Logging::Loggable(getKindToString(d_kind))); } @@ -625,9 +628,9 @@ std::vector DNSFilterEngine::Policy::getCustomRecords(const DNSName& std::string DNSFilterEngine::getKindToString(DNSFilterEngine::PolicyKind kind) { - //static const std::string rpzPrefix("rpz-"); + // static const std::string rpzPrefix("rpz-"); - switch(kind) { + switch (kind) { case DNSFilterEngine::PolicyKind::NoAction: return rpzNoActionName; case DNSFilterEngine::PolicyKind::Drop: @@ -647,7 +650,7 @@ std::string DNSFilterEngine::getKindToString(DNSFilterEngine::PolicyKind kind) std::string DNSFilterEngine::getTypeToString(DNSFilterEngine::PolicyType type) { - switch(type) { + switch (type) { case DNSFilterEngine::PolicyType::None: return "none"; case DNSFilterEngine::PolicyType::QName: @@ -707,7 +710,7 @@ DNSName DNSFilterEngine::Zone::maskToRPZ(const Netmask& nm) DNSName temp; static_assert(sizeof(addr.sin6.sin6_addr.s6_addr) == sizeof(uint16_t) * 8); auto src = reinterpret_cast(&addr.sin6.sin6_addr.s6_addr); - std::array elems; + std::array elems; // this routine was adopted from libc's inet_ntop6, written by Paul Vixie // because the RPZ spec (https://datatracker.ietf.org/doc/html/draft-vixie-dnsop-dns-rpz-00#section-4.1.1) says: @@ -720,18 +723,23 @@ DNSName DNSFilterEngine::Zone::maskToRPZ(const Netmask& nm) // // 'cur.len > best.len' from the original code is replaced by 'cur.len >= best.len', so the last-longest wins. - struct { int base, len; } best = {-1, 0}, cur = {-1, 0}; + struct + { + int base, len; + } best = {-1, 0}, cur = {-1, 0}; for (int i = 0; i < (int)elems.size(); i++) { elems[i] = ntohs(src[i]); if (elems[i] == 0) { - if (cur.base == -1) { // start of a run of zeroes - cur = { i, 1 }; - } else { - cur.len++; // continuation of a run of zeroes + if (cur.base == -1) { // start of a run of zeroes + cur = {i, 1}; } - } else { // not a zero - if (cur.base != -1) { // end of a run of zeroes + else { + cur.len++; // continuation of a run of zeroes + } + } + else { // not a zero + if (cur.base != -1) { // end of a run of zeroes if (best.base == -1 || cur.len >= best.len) { // first run of zeroes, or a better one than we found before best = cur; } @@ -740,20 +748,21 @@ DNSName DNSFilterEngine::Zone::maskToRPZ(const Netmask& nm) } } - if (cur.base != -1) { // address ended with a zero - if (best.base == -1 || cur.len >= best.len) { // first run of zeroes, or a better one than we found before + if (cur.base != -1) { // address ended with a zero + if (best.base == -1 || cur.len >= best.len) { // first run of zeroes, or a better one than we found before best = cur; } } - if (best.base != -1 && best.len < 2) { // if our best run is only one zero long, we do not replace it + if (best.base != -1 && best.len < 2) { // if our best run is only one zero long, we do not replace it best.base = -1; } - for (int i=0; i < (int)elems.size(); i++) { + for (int i = 0; i < (int)elems.size(); i++) { if (i == best.base) { temp = DNSName("zz") + temp; i = i + best.len - 1; - } else { + } + else { temp = DNSName((boost::format("%x") % elems.at(i)).str()) + temp; } } @@ -763,7 +772,6 @@ DNSName DNSFilterEngine::Zone::maskToRPZ(const Netmask& nm) return res; } - void DNSFilterEngine::Zone::dumpAddrPolicy(FILE* fp, const Netmask& nm, const DNSName& name, const Policy& pol) { DNSName full = maskToRPZ(nm); diff --git a/pdns/recursordist/filterpo.hh b/pdns/recursordist/filterpo.hh index 72ac97ad04..224ee3672c 100644 --- a/pdns/recursordist/filterpo.hh +++ b/pdns/recursordist/filterpo.hh @@ -63,15 +63,30 @@ is consulted. Then within that zone, rules again have precedences. */ - class DNSFilterEngine { public: - enum class PolicyKind : uint8_t { NoAction, Drop, NXDOMAIN, NODATA, Truncate, Custom}; - enum class PolicyType : uint8_t { None, QName, ClientIP, ResponseIP, NSDName, NSIP }; + enum class PolicyKind : uint8_t + { + NoAction, + Drop, + NXDOMAIN, + NODATA, + Truncate, + Custom + }; + enum class PolicyType : uint8_t + { + None, + QName, + ClientIP, + ResponseIP, + NSDName, + NSIP + }; typedef uint16_t Priority; static const Priority maximumPriority = std::numeric_limits::max(); - + static std::string getKindToString(PolicyKind kind); static std::string getTypeToString(PolicyType type); @@ -88,11 +103,13 @@ public: struct Policy { - Policy(): d_ttl(0), d_kind(PolicyKind::NoAction), d_type(PolicyType::None) + Policy() : + d_ttl(0), d_kind(PolicyKind::NoAction), d_type(PolicyType::None) { } - Policy(PolicyKind kind, PolicyType type, int32_t ttl=0, std::shared_ptr data=nullptr, const std::vector>& custom={}): d_custom(custom), d_zoneData(data), d_ttl(ttl), d_kind(kind), d_type(type) + Policy(PolicyKind kind, PolicyType type, int32_t ttl = 0, std::shared_ptr data = nullptr, const std::vector>& custom = {}) : + d_custom(custom), d_zoneData(data), d_ttl(ttl), d_kind(kind), d_type(type) { } @@ -143,7 +160,8 @@ public: return notSet; } - bool policyOverridesGettag() const { + bool policyOverridesGettag() const + { if (d_zoneData) { return d_zoneData->d_policyOverridesGettag; } @@ -173,9 +191,11 @@ public: DNSRecord getRecordFromCustom(const DNSName& qname, const std::shared_ptr& custom) const; }; - class Zone { + class Zone + { public: - Zone(): d_zoneData(std::make_shared()) + Zone() : + d_zoneData(std::make_shared()) { } @@ -249,7 +269,7 @@ public: return d_qpolAddr.size() + d_postpolAddr.size() + d_propolName.size() + d_propolNSAddr.size() + d_qpolName.size(); } - void dump(FILE * fp) const; + void dump(FILE* fp) const; void addClientTrigger(const Netmask& nm, Policy&& pol, bool ignoreDuplicate = false); void addQNameTrigger(const DNSName& nm, Policy&& pol, bool ignoreDuplicate = false); @@ -289,19 +309,21 @@ public: { return !d_postpolAddr.empty(); } - Priority getPriority() const { + Priority getPriority() const + { return d_zoneData->d_priority; } - void setPriority(Priority p) { + void setPriority(Priority p) + { d_zoneData->d_priority = p; } - + static DNSName maskToRPZ(const Netmask& nm); private: - void addNameTrigger(std::unordered_map& map, const DNSName& n, Policy&& pol, bool ignoreDuplicate, PolicyType ptype); + void addNameTrigger(std::unordered_map& map, const DNSName& n, Policy&& pol, bool ignoreDuplicate, PolicyType ptype); void addNetmaskTrigger(NetmaskTree& nmt, const Netmask& nm, Policy&& pol, bool ignoreDuplicate, PolicyType ptype); - bool rmNameTrigger(std::unordered_map& map, const DNSName& n, const Policy& pol); + bool rmNameTrigger(std::unordered_map& map, const DNSName& n, const Policy& pol); bool rmNetmaskTrigger(NetmaskTree& nmt, const Netmask& nm, const Policy& pol); private: @@ -310,11 +332,11 @@ public: static void dumpNamedPolicy(FILE* fp, const DNSName& name, const Policy& pol); static void dumpAddrPolicy(FILE* fp, const Netmask& nm, const DNSName& name, const Policy& pol); - std::unordered_map d_qpolName; // QNAME trigger (RPZ) - NetmaskTree d_qpolAddr; // Source address + std::unordered_map d_qpolName; // QNAME trigger (RPZ) + NetmaskTree d_qpolAddr; // Source address std::unordered_map d_propolName; // NSDNAME (RPZ) - NetmaskTree d_propolNSAddr; // NSIP (RPZ) - NetmaskTree d_postpolAddr; // IP trigger (RPZ) + NetmaskTree d_propolNSAddr; // NSIP (RPZ) + NetmaskTree d_postpolAddr; // IP trigger (RPZ) DNSName d_domain; std::shared_ptr d_zoneData{nullptr}; uint32_t d_serial{0}; @@ -324,7 +346,7 @@ public: DNSFilterEngine(); void clear() { - for(auto& z : d_zones) { + for (auto& z : d_zones) { z->clear(); } } @@ -365,15 +387,16 @@ public: } } - bool getQueryPolicy(const DNSName& qname, const std::unordered_map& discardedPolicies, Policy& policy) const; - bool getClientPolicy(const ComboAddress& ca, const std::unordered_map& discardedPolicies, Policy& policy) const; - bool getProcessingPolicy(const DNSName& qname, const std::unordered_map& discardedPolicies, Policy& policy) const; - bool getProcessingPolicy(const ComboAddress& address, const std::unordered_map& discardedPolicies, Policy& policy) const; - bool getPostPolicy(const vector& records, const std::unordered_map& discardedPolicies, Policy& policy) const; - bool getPostPolicy(const DNSRecord& record, const std::unordered_map& discardedPolicies, Policy& policy) const; + bool getQueryPolicy(const DNSName& qname, const std::unordered_map& discardedPolicies, Policy& policy) const; + bool getClientPolicy(const ComboAddress& ca, const std::unordered_map& discardedPolicies, Policy& policy) const; + bool getProcessingPolicy(const DNSName& qname, const std::unordered_map& discardedPolicies, Policy& policy) const; + bool getProcessingPolicy(const ComboAddress& address, const std::unordered_map& discardedPolicies, Policy& policy) const; + bool getPostPolicy(const vector& records, const std::unordered_map& discardedPolicies, Policy& policy) const; + bool getPostPolicy(const DNSRecord& record, const std::unordered_map& discardedPolicies, Policy& policy) const; // A few convenience methods for the unit test code - Policy getQueryPolicy(const DNSName& qname, const std::unordered_map& discardedPolicies, Priority p) const { + Policy getQueryPolicy(const DNSName& qname, const std::unordered_map& discardedPolicies, Priority p) const + { Policy policy; policy.d_zoneData = std::make_shared(); policy.d_zoneData->d_priority = p; @@ -381,7 +404,8 @@ public: return policy; } - Policy getClientPolicy(const ComboAddress& ca, const std::unordered_map& discardedPolicies, Priority p) const { + Policy getClientPolicy(const ComboAddress& ca, const std::unordered_map& discardedPolicies, Priority p) const + { Policy policy; policy.d_zoneData = std::make_shared(); policy.d_zoneData->d_priority = p; @@ -389,7 +413,8 @@ public: return policy; } - Policy getProcessingPolicy(const DNSName& qname, const std::unordered_map& discardedPolicies, Priority p) const { + Policy getProcessingPolicy(const DNSName& qname, const std::unordered_map& discardedPolicies, Priority p) const + { Policy policy; policy.d_zoneData = std::make_shared(); policy.d_zoneData->d_priority = p; @@ -397,7 +422,8 @@ public: return policy; } - Policy getProcessingPolicy(const ComboAddress& address, const std::unordered_map& discardedPolicies, Priority p) const { + Policy getProcessingPolicy(const ComboAddress& address, const std::unordered_map& discardedPolicies, Priority p) const + { Policy policy; policy.d_zoneData = std::make_shared(); policy.d_zoneData->d_priority = p; @@ -405,7 +431,8 @@ public: return policy; } - Policy getPostPolicy(const vector& records, const std::unordered_map& discardedPolicies, Priority p) const { + Policy getPostPolicy(const vector& records, const std::unordered_map& discardedPolicies, Priority p) const + { Policy policy; policy.d_zoneData = std::make_shared(); policy.d_zoneData->d_priority = p; @@ -413,9 +440,11 @@ public: return policy; } - size_t size() const { + size_t size() const + { return d_zones.size(); } + private: void assureZones(size_t zone); vector> d_zones; diff --git a/pdns/recursordist/lazy_allocator.hh b/pdns/recursordist/lazy_allocator.hh index 986f91bdae..7ddd31553c 100644 --- a/pdns/recursordist/lazy_allocator.hh +++ b/pdns/recursordist/lazy_allocator.hh @@ -32,55 +32,61 @@ #endif template -struct lazy_allocator { - using value_type = T; - using pointer = T*; - using size_type = std::size_t; - static_assert (std::is_trivial::value, - "lazy_allocator must only be used with trivial types"); +struct lazy_allocator +{ + using value_type = T; + using pointer = T*; + using size_type = std::size_t; + static_assert(std::is_trivial::value, + "lazy_allocator must only be used with trivial types"); - pointer - allocate (size_type const n) { + pointer + allocate(size_type const n) + { #ifdef __OpenBSD__ - void *p = mmap(nullptr, n * sizeof(value_type), - PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_STACK, -1, 0); - if (p == MAP_FAILED) - throw std::bad_alloc(); - return static_cast(p); + void* p = mmap(nullptr, n * sizeof(value_type), + PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_STACK, -1, 0); + if (p == MAP_FAILED) + throw std::bad_alloc(); + return static_cast(p); #else - return static_cast(::operator new (n * sizeof(value_type))); + return static_cast(::operator new(n * sizeof(value_type))); #endif - } + } - void - deallocate (pointer const ptr, size_type const n) noexcept { + void + deallocate(pointer const ptr, size_type const n) noexcept + { #ifdef __OpenBSD__ - munmap(ptr, n * sizeof(value_type)); + munmap(ptr, n * sizeof(value_type)); #else -#if defined(__cpp_sized_deallocation) && (__cpp_sized_deallocation >= 201309) - ::operator delete (ptr, n * sizeof(value_type)); +#if defined(__cpp_sized_deallocation) && (__cpp_sized_deallocation >= 201309) + ::operator delete(ptr, n * sizeof(value_type)); #else - (void) n; - ::operator delete (ptr); + (void)n; + ::operator delete(ptr); #endif #endif - } + } - void construct (T*) const noexcept {} + void construct(T*) const noexcept {} - template - void - construct (X* place, Args&&... args) const noexcept { - new (static_cast(place)) X (std::forward(args)...); - } + template + void + construct(X* place, Args&&... args) const noexcept + { + new (static_cast(place)) X(std::forward(args)...); + } }; -template inline -bool operator== (lazy_allocator const&, lazy_allocator const&) noexcept { - return true; +template +inline bool operator==(lazy_allocator const&, lazy_allocator const&) noexcept +{ + return true; } -template inline -bool operator!= (lazy_allocator const&, lazy_allocator const&) noexcept { - return false; +template +inline bool operator!=(lazy_allocator const&, lazy_allocator const&) noexcept +{ + return false; } diff --git a/pdns/recursordist/lwres.cc b/pdns/recursordist/lwres.cc index aa1c7889c1..7cf9d7972d 100644 --- a/pdns/recursordist/lwres.cc +++ b/pdns/recursordist/lwres.cc @@ -69,14 +69,14 @@ void remoteLoggerQueueData(RemoteLoggerInterface& r, const std::string& data) case RemoteLoggerInterface::Result::PipeFull: { const auto msg = RemoteLoggerInterface::toErrorString(ret); const auto name = r.name(); - SLOG(g_log << Logger::Debug << name << ": " << msg <withName(name)->info(Logr::Debug, msg)); break; } case RemoteLoggerInterface::Result::TooLarge: { const auto msg = RemoteLoggerInterface::toErrorString(ret); const auto name = r.name(); - SLOG(g_log << Logger::Notice << name << ": " << msg <withName(name)->info(Logr::Debug, msg)); break; } @@ -109,7 +109,7 @@ static bool isEnabledForQueries(const std::shared_ptr>>& fstreamLoggers, const struct timeval &queryTime, const ComboAddress& localip, const ComboAddress& ip, DnstapMessage::ProtocolType protocol, boost::optional auth, const vector& packet) +static void logFstreamQuery(const std::shared_ptr>>& fstreamLoggers, const struct timeval& queryTime, const ComboAddress& localip, const ComboAddress& ip, DnstapMessage::ProtocolType protocol, boost::optional auth, const vector& packet) { if (fstreamLoggers == nullptr) return; @@ -137,7 +137,7 @@ static bool isEnabledForResponses(const std::shared_ptr>>& fstreamLoggers, const ComboAddress&localip, const ComboAddress& ip, DnstapMessage::ProtocolType protocol, boost::optional auth, const PacketBuffer& packet, const struct timeval& queryTime, const struct timeval& replyTime) +static void logFstreamResponse(const std::shared_ptr>>& fstreamLoggers, const ComboAddress& localip, const ComboAddress& ip, DnstapMessage::ProtocolType protocol, boost::optional auth, const PacketBuffer& packet, const struct timeval& queryTime, const struct timeval& replyTime) { if (fstreamLoggers == nullptr) return; @@ -291,7 +291,10 @@ static bool tcpconnect(const struct timeval& now, const ComboAddress& ip, TCPOut return false; } - const struct timeval timeout{ g_networkTimeoutMsec / 1000, static_cast(g_networkTimeoutMsec) % 1000 * 1000}; + const struct timeval timeout + { + g_networkTimeoutMsec / 1000, static_cast(g_networkTimeoutMsec) % 1000 * 1000 + }; Socket s(ip.sin4.sin_family, SOCK_STREAM); s.setNonBlocking(); setTCPNoDelay(s.getHandle()); @@ -323,7 +326,7 @@ static LWResult::Result tcpsendrecv(const ComboAddress& ip, TCPOutConnectionMana { socklen_t slen = ip.getSocklen(); uint16_t tlen = htons(vpacket.size()); - const char *lenP = reinterpret_cast(&tlen); + const char* lenP = reinterpret_cast(&tlen); len = 0; // in case of error localip.sin4.sin_family = ip.sin4.sin_family; @@ -380,12 +383,12 @@ static void addPadding(const DNSPacketWriter& pw, size_t bufsize, DNSPacketWrite } /** lwr is only filled out in case 1 was returned, and even when returning 1 for 'success', lwr might contain DNS errors - Never throws! + Never throws! */ -static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, const std::shared_ptr>>& outgoingLoggers, const std::shared_ptr>>& fstrmLoggers, const std::set& exportTypes, LWResult *lwr, bool* chained, TCPOutConnectionManager::Connection& connection) +static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, const std::shared_ptr>>& outgoingLoggers, const std::shared_ptr>>& fstrmLoggers, const std::set& exportTypes, LWResult* lwr, bool* chained, TCPOutConnectionManager::Connection& connection) { size_t len; - size_t bufsize=g_outgoingEDNSBufsize; + size_t bufsize = g_outgoingEDNSBufsize; PacketBuffer buf; buf.resize(bufsize); vector vpacket; @@ -394,8 +397,8 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma DNSPacketWriter pw(vpacket, domain, type); bool dnsOverTLS = SyncRes::s_dot_to_port_853 && ip.getPort() == 853; - pw.getHeader()->rd=sendRDQuery; - pw.getHeader()->id=qid; + pw.getHeader()->rd = sendRDQuery; + pw.getHeader()->id = qid; /* RFC 6840 section 5.9: * This document further specifies that validating resolvers SHOULD set * the CD bit on every upstream query. This is regardless of whether @@ -406,22 +409,22 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma * an "upstream query". To stay true to "dnssec=off means 3.X behaviour", we * only set +CD on forwarded query in any mode other than dnssec=off. */ - pw.getHeader()->cd=(sendRDQuery && g_dnssecmode != DNSSECMode::Off); + pw.getHeader()->cd = (sendRDQuery && g_dnssecmode != DNSSECMode::Off); string ping; - bool weWantEDNSSubnet=false; + bool weWantEDNSSubnet = false; uint8_t outgoingECSBits = 0; ComboAddress outgoingECSAddr; - if(EDNS0Level > 0) { + if (EDNS0Level > 0) { DNSPacketWriter::optvect_t opts; - if(srcmask) { + if (srcmask) { EDNSSubnetOpts eo; eo.source = *srcmask; outgoingECSBits = srcmask->getBits(); outgoingECSAddr = srcmask->getNetwork(); // cout<<"Adding request mask: "<d_usec=dt.udiff(); - *now=dt.getTimeval(); + lwr->d_usec = dt.udiff(); + *now = dt.getTimeval(); if (ret != LWResult::Result::Success) { // includes 'timeout' - if (outgoingLoggers) { - logIncomingResponse(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, dnsOverTLS, srcmask, 0, -1, {}, queryTime, exportTypes); - } + if (outgoingLoggers) { + logIncomingResponse(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, dnsOverTLS, srcmask, 0, -1, {}, queryTime, exportTypes); + } return ret; } @@ -553,23 +556,23 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma lwr->d_records.clear(); try { - lwr->d_tcbit=0; + lwr->d_tcbit = 0; MOADNSParser mdp(false, reinterpret_cast(buf.data()), buf.size()); - lwr->d_aabit=mdp.d_header.aa; - lwr->d_tcbit=mdp.d_header.tc; - lwr->d_rcode=mdp.d_header.rcode; - - if(mdp.d_header.rcode == RCode::FormErr && mdp.d_qname.empty() && mdp.d_qtype == 0 && mdp.d_qclass == 0) { - if(outgoingLoggers) { + lwr->d_aabit = mdp.d_header.aa; + lwr->d_tcbit = mdp.d_header.tc; + lwr->d_rcode = mdp.d_header.rcode; + + if (mdp.d_header.rcode == RCode::FormErr && mdp.d_qname.empty() && mdp.d_qtype == 0 && mdp.d_qclass == 0) { + if (outgoingLoggers) { logIncomingResponse(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, dnsOverTLS, srcmask, len, lwr->d_rcode, lwr->d_records, queryTime, exportTypes); } lwr->d_validpacket = true; return LWResult::Result::Success; // this is "success", the error is set in lwr->d_rcode } - if(domain != mdp.d_qname) { - if(!mdp.d_qname.empty() && domain.toString().find((char)0) == string::npos /* ugly */) {// embedded nulls are too noisy, plus empty domains are too - SLOG(g_log<info(Logr::Notice, "Packet purporting to come from remote server contained wrong answer", "server", Logging::Loggable(ip), "qname", Logging::Loggable(domain), @@ -580,24 +583,24 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma } lwr->d_records.reserve(mdp.d_answers.size()); - for(const auto& a : mdp.d_answers) + for (const auto& a : mdp.d_answers) lwr->d_records.push_back(a.first); EDNSOpts edo; - if(EDNS0Level > 0 && getEDNSOpts(mdp, &edo)) { + if (EDNS0Level > 0 && getEDNSOpts(mdp, &edo)) { lwr->d_haveEDNS = true; - if(weWantEDNSSubnet) { - for(const auto& opt : edo.d_options) { - if(opt.first==EDNSOptionCode::ECS) { + if (weWantEDNSSubnet) { + for (const auto& opt : edo.d_options) { + if (opt.first == EDNSOptionCode::ECS) { EDNSSubnetOpts reso; - if(getEDNSSubnetOptsFromString(opt.second, &reso)) { + if (getEDNSSubnetOptsFromString(opt.second, &reso)) { // cerr<<"EDNS Subnet response: "<d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, dnsOverTLS, srcmask, len, lwr->d_rcode, lwr->d_records, queryTime, exportTypes); } - + lwr->d_validpacket = true; return LWResult::Result::Success; } - catch (const std::exception &mde) { + catch (const std::exception& mde) { if (::arg().mustDo("log-common-errors")) { - SLOG(g_log<error(Logr::Notice, mde.what(), "Unable to parse packet from remote server", "server", Logging::Loggable(ip), "exception", Logging::Loggable("std::exception"))); } @@ -626,28 +629,28 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma lwr->d_validpacket = false; t_Counters.at(rec::Counter::serverParseError)++; - if(outgoingLoggers) { + if (outgoingLoggers) { logIncomingResponse(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, dnsOverTLS, srcmask, len, lwr->d_rcode, lwr->d_records, queryTime, exportTypes); } return LWResult::Result::Success; // success - oddly enough } catch (...) { - SLOG(g_log<info(Logr::Notice, "Unknown error parsing packet from remote server", "server", Logging::Loggable(ip))); } t_Counters.at(rec::Counter::serverParseError)++; - out: +out: if (!lwr->d_rcode) { - lwr->d_rcode=RCode::ServFail; + lwr->d_rcode = RCode::ServFail; } return LWResult::Result::PermanentError; } -LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, const std::shared_ptr>>& outgoingLoggers, const std::shared_ptr>>& fstrmLoggers, const std::set& exportTypes, LWResult *lwr, bool* chained) +LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, const std::shared_ptr>>& outgoingLoggers, const std::shared_ptr>>& fstrmLoggers, const std::set& exportTypes, LWResult* lwr, bool* chained) { TCPOutConnectionManager::Connection connection; auto ret = asyncresolve(ip, domain, type, doTCP, sendRDQuery, EDNS0Level, now, srcmask, context, outgoingLoggers, fstrmLoggers, exportTypes, lwr, chained, connection); @@ -659,4 +662,3 @@ LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& domain, int } return ret; } - diff --git a/pdns/recursordist/lwres.hh b/pdns/recursordist/lwres.hh index 38a8817a1e..b34f3790b9 100644 --- a/pdns/recursordist/lwres.hh +++ b/pdns/recursordist/lwres.hh @@ -55,16 +55,25 @@ extern bool g_paddingOutgoing; class LWResException : public PDNSException { public: - LWResException(const string &reason_) : PDNSException(reason_){} + LWResException(const string& reason_) : + PDNSException(reason_) {} }; -//! LWRes class +//! LWRes class class LWResult { public: - LWResult() : d_usec(0) {} + LWResult() : + d_usec(0) {} - enum class Result : uint8_t { Timeout=0, Success=1, PermanentError=2 /* not transport related */, OSLimitError=3, Spoofed=4 /* Spoofing attempt (too many near-misses) */ }; + enum class Result : uint8_t + { + Timeout = 0, + Success = 1, + PermanentError = 2 /* not transport related */, + OSLimitError = 3, + Spoofed = 4 /* Spoofing attempt (too many near-misses) */ + }; vector d_records; int d_rcode{0}; @@ -74,9 +83,9 @@ public: bool d_haveEDNS{false}; }; -LWResult::Result asendto(const char *data, size_t len, int flags, const ComboAddress& ip, uint16_t id, - const DNSName& domain, uint16_t qtype, int* fd); -LWResult::Result arecvfrom(PacketBuffer& packet, int flags, const ComboAddress& ip, size_t *d_len, uint16_t id, +LWResult::Result asendto(const char* data, size_t len, int flags, const ComboAddress& ip, uint16_t id, + const DNSName& domain, uint16_t qtype, int* fd); +LWResult::Result arecvfrom(PacketBuffer& packet, int flags, const ComboAddress& ip, size_t* d_len, uint16_t id, const DNSName& domain, uint16_t qtype, int fd, const struct timeval* now); LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, const std::shared_ptr>>& outgoingLoggers, const std::shared_ptr>>& fstrmLoggers, const std::set& exportTypes, LWResult* res, bool* chained); diff --git a/pdns/recursordist/mtasker_context.hh b/pdns/recursordist/mtasker_context.hh index 2884c69671..e03a1709e4 100644 --- a/pdns/recursordist/mtasker_context.hh +++ b/pdns/recursordist/mtasker_context.hh @@ -25,28 +25,25 @@ #include #include -struct pdns_ucontext_t { - pdns_ucontext_t (); - pdns_ucontext_t (pdns_ucontext_t const&) = delete; - pdns_ucontext_t& operator= (pdns_ucontext_t const&) = delete; - ~pdns_ucontext_t (); +struct pdns_ucontext_t +{ + pdns_ucontext_t(); + pdns_ucontext_t(pdns_ucontext_t const&) = delete; + pdns_ucontext_t& operator=(pdns_ucontext_t const&) = delete; + ~pdns_ucontext_t(); - void* uc_mcontext; - pdns_ucontext_t* uc_link; - std::vector> uc_stack; - std::exception_ptr exception; + void* uc_mcontext; + pdns_ucontext_t* uc_link; + std::vector> uc_stack; + std::exception_ptr exception; #ifdef PDNS_USE_VALGRIND - int valgrind_id; + int valgrind_id; #endif /* PDNS_USE_VALGRIND */ }; -void -pdns_swapcontext -(pdns_ucontext_t& __restrict octx, pdns_ucontext_t const& __restrict ctx); +void pdns_swapcontext(pdns_ucontext_t& __restrict octx, pdns_ucontext_t const& __restrict ctx); -void -pdns_makecontext -(pdns_ucontext_t& ctx, std::function& start); +void pdns_makecontext(pdns_ucontext_t& ctx, std::function& start); #ifdef HAVE_FIBER_SANITIZER #include diff --git a/pdns/recursordist/mtasker_fcontext.cc b/pdns/recursordist/mtasker_fcontext.cc index b4aa3a44b3..dd3eb707ba 100644 --- a/pdns/recursordist/mtasker_fcontext.cc +++ b/pdns/recursordist/mtasker_fcontext.cc @@ -52,22 +52,24 @@ using fcontext_t = boost::context::fcontext_t*; /* Emulate the >= 1.56 API for Boost 1.52 through 1.55 */ static inline intptr_t -jump_fcontext (fcontext_t* const ofc, fcontext_t const nfc, - intptr_t const arg) { - /* If the fcontext_t is preallocated then use it, otherwise allocate one - * on the stack ('self') and stash a pointer away in *ofc so the returning - * MThread can access it. This is safe because we're suspended, so the - * context object always outlives the jump. - */ - if (*ofc) { - return boost::context::jump_fcontext (*ofc, nfc, arg); - } else { - boost::context::fcontext_t self; - *ofc = &self; - auto ret = boost::context::jump_fcontext (*ofc, nfc, arg); - *ofc = nullptr; - return ret; - } +jump_fcontext(fcontext_t* const ofc, fcontext_t const nfc, + intptr_t const arg) +{ + /* If the fcontext_t is preallocated then use it, otherwise allocate one + * on the stack ('self') and stash a pointer away in *ofc so the returning + * MThread can access it. This is safe because we're suspended, so the + * context object always outlives the jump. + */ + if (*ofc) { + return boost::context::jump_fcontext(*ofc, nfc, arg); + } + else { + boost::context::fcontext_t self; + *ofc = &self; + auto ret = boost::context::jump_fcontext(*ofc, nfc, arg); + *ofc = nullptr; + return ret; + } } #else @@ -80,28 +82,31 @@ using boost::context::detail::jump_fcontext; using boost::context::detail::transfer_t; #endif /* BOOST_VERSION < 106100 */ -static_assert (std::is_pointer::value, - "Boost Context has changed the fcontext_t type again :-("); +static_assert(std::is_pointer::value, + "Boost Context has changed the fcontext_t type again :-("); #endif /* Boost context only provides a means of passing a single argument across a * jump. args_t simply provides a way to pass more by reference. */ -struct args_t { +struct args_t +{ #if BOOST_VERSION < 106100 - fcontext_t prev_ctx = nullptr; + fcontext_t prev_ctx = nullptr; #endif - pdns_ucontext_t* self = nullptr; - std::function* work = nullptr; + pdns_ucontext_t* self = nullptr; + std::function* work = nullptr; }; -extern "C" { -static -void +extern "C" +{ + static void #if BOOST_VERSION < 106100 -threadWrapper (intptr_t const xargs) { + threadWrapper(intptr_t const xargs) + { #else -threadWrapper (transfer_t const t) { + threadWrapper(transfer_t const t) + { #endif /* Access the args passed from pdns_makecontext, and copy them directly from * the calling stack on to ours (we're now using the MThreads stack). @@ -123,10 +128,10 @@ threadWrapper (transfer_t const t) { /* we switch back to pdns_makecontext() */ notifyStackSwitchToKernel(); #if BOOST_VERSION < 106100 - jump_fcontext (reinterpret_cast(&ctx->uc_mcontext), - static_cast(args->prev_ctx), 0); + jump_fcontext(reinterpret_cast(&ctx->uc_mcontext), + static_cast(args->prev_ctx), 0); #else - transfer_t res = jump_fcontext (t.fctx, 0); + transfer_t res = jump_fcontext(t.fctx, 0); /* we got switched back from pdns_swapcontext() */ if (res.data) { /* if res.data is not a nullptr, it holds a pointer to the context @@ -140,41 +145,43 @@ threadWrapper (transfer_t const t) { args = nullptr; try { - auto start = std::move (*work); - start(); - } catch (...) { - ctx->exception = std::current_exception(); + auto start = std::move(*work); + start(); + } + catch (...) { + ctx->exception = std::current_exception(); } notifyStackSwitchToKernel(); /* Emulate the System V uc_link feature. */ auto const next_ctx = ctx->uc_link->uc_mcontext; #if BOOST_VERSION < 106100 - jump_fcontext (reinterpret_cast(&ctx->uc_mcontext), - static_cast(next_ctx), - reinterpret_cast(ctx)); + jump_fcontext(reinterpret_cast(&ctx->uc_mcontext), + static_cast(next_ctx), + reinterpret_cast(ctx)); #else - jump_fcontext (static_cast(next_ctx), 0); + jump_fcontext(static_cast(next_ctx), 0); #endif #ifdef NDEBUG __builtin_unreachable(); #endif -} + } } -pdns_ucontext_t::pdns_ucontext_t -(): uc_mcontext(nullptr), uc_link(nullptr) { +pdns_ucontext_t::pdns_ucontext_t() : + uc_mcontext(nullptr), uc_link(nullptr) +{ #ifdef PDNS_USE_VALGRIND valgrind_id = 0; #endif /* PDNS_USE_VALGRIND */ } -pdns_ucontext_t::~pdns_ucontext_t -() { - /* There's nothing to delete here since fcontext doesn't require anything - * to be heap allocated. - */ +pdns_ucontext_t::~pdns_ucontext_t() +{ + /* There's nothing to delete here since fcontext doesn't require anything + * to be heap allocated. + */ #ifdef PDNS_USE_VALGRIND if (valgrind_id != 0) { VALGRIND_STACK_DEREGISTER(valgrind_id); @@ -182,21 +189,20 @@ pdns_ucontext_t::~pdns_ucontext_t #endif /* PDNS_USE_VALGRIND */ } -void -pdns_swapcontext -(pdns_ucontext_t& __restrict octx, pdns_ucontext_t const& __restrict ctx) { +void pdns_swapcontext(pdns_ucontext_t& __restrict octx, pdns_ucontext_t const& __restrict ctx) +{ /* we either switch back to threadwrapper() if it's the first time, or we switch back to pdns_swapcontext(), in both case we will be returning from a call to jump_fcontext(). */ #if BOOST_VERSION < 106100 - intptr_t ptr = jump_fcontext(reinterpret_cast(&octx.uc_mcontext), - static_cast(ctx.uc_mcontext), 0); + intptr_t ptr = jump_fcontext(reinterpret_cast(&octx.uc_mcontext), + static_cast(ctx.uc_mcontext), 0); - auto origctx = reinterpret_cast(ptr); - if(origctx && origctx->exception) - std::rethrow_exception (origctx->exception); + auto origctx = reinterpret_cast(ptr); + if (origctx && origctx->exception) + std::rethrow_exception(origctx->exception); #else - transfer_t res = jump_fcontext (static_cast(ctx.uc_mcontext), &octx.uc_mcontext); + transfer_t res = jump_fcontext(static_cast(ctx.uc_mcontext), &octx.uc_mcontext); if (res.data) { /* if res.data is not a nullptr, it holds a pointer to the context we just switched from, and we need to fill it to be able to @@ -205,34 +211,32 @@ pdns_swapcontext *ptr = res.fctx; } if (ctx.exception) { - std::rethrow_exception (ctx.exception); + std::rethrow_exception(ctx.exception); } #endif } -void -pdns_makecontext -(pdns_ucontext_t& ctx, std::function& start) { - assert (ctx.uc_link); - assert (ctx.uc_stack.size() >= 8192); - assert (!ctx.uc_mcontext); - ctx.uc_mcontext = make_fcontext (&ctx.uc_stack[ctx.uc_stack.size()-1], - ctx.uc_stack.size()-1, &threadWrapper); - args_t args; - args.self = &ctx; - args.work = &start; - /* jumping to threadwrapper */ - notifyStackSwitch(&ctx.uc_stack[ctx.uc_stack.size()-1], ctx.uc_stack.size()-1); +void pdns_makecontext(pdns_ucontext_t& ctx, std::function& start) +{ + assert(ctx.uc_link); + assert(ctx.uc_stack.size() >= 8192); + assert(!ctx.uc_mcontext); + ctx.uc_mcontext = make_fcontext(&ctx.uc_stack[ctx.uc_stack.size() - 1], + ctx.uc_stack.size() - 1, &threadWrapper); + args_t args; + args.self = &ctx; + args.work = &start; + /* jumping to threadwrapper */ + notifyStackSwitch(&ctx.uc_stack[ctx.uc_stack.size() - 1], ctx.uc_stack.size() - 1); #if BOOST_VERSION < 106100 - jump_fcontext (reinterpret_cast(&args.prev_ctx), - static_cast(ctx.uc_mcontext), - reinterpret_cast(&args)); + jump_fcontext(reinterpret_cast(&args.prev_ctx), + static_cast(ctx.uc_mcontext), + reinterpret_cast(&args)); #else - transfer_t res = jump_fcontext (static_cast(ctx.uc_mcontext), - &args); - /* back from threadwrapper, updating the context */ - ctx.uc_mcontext = res.fctx; + transfer_t res = jump_fcontext(static_cast(ctx.uc_mcontext), + &args); + /* back from threadwrapper, updating the context */ + ctx.uc_mcontext = res.fctx; #endif - notifyStackSwitchDone(); - + notifyStackSwitchDone(); } diff --git a/pdns/recursordist/mtasker_ucontext.cc b/pdns/recursordist/mtasker_ucontext.cc index 83d326d4c3..2d0825921c 100644 --- a/pdns/recursordist/mtasker_ucontext.cc +++ b/pdns/recursordist/mtasker_ucontext.cc @@ -36,110 +36,113 @@ __thread void* t_mainStack{nullptr}; __thread size_t t_mainStackSize{0}; #endif /* HAVE_FIBER_SANITIZER */ -template static __attribute__((noinline, cold, noreturn)) -void -throw_errno (Message&& msg) { - throw std::system_error - (errno, std::system_category(), std::forward(msg)); +template +static __attribute__((noinline, cold, noreturn)) void +throw_errno(Message&& msg) +{ + throw std::system_error(errno, std::system_category(), std::forward(msg)); } -static inline -std::pair -splitPointer (void* const ptr) noexcept { - static_assert (sizeof(int) == 4, "splitPointer() requires an 4 byte 'int'"); -// In theory, we need this assertion. In practice, it prevents compilation -// on EL6 i386. Without the assertion, everything works. -// If you ever run into trouble with this code, please heed the warnings at -// http://man7.org/linux/man-pages/man3/makecontext.3.html#NOTES -// static_assert (sizeof(uintptr_t) == 8, -// "splitPointer() requires an 8 byte 'uintptr_t'"); - std::pair words; - auto rep = reinterpret_cast(ptr); - uint32_t const hw = rep >> 32; - auto const lw = static_cast(rep); - std::memcpy (&words.first, &hw, 4); - std::memcpy (&words.second, &lw, 4); - return words; +static inline std::pair +splitPointer(void* const ptr) noexcept +{ + static_assert(sizeof(int) == 4, "splitPointer() requires an 4 byte 'int'"); + // In theory, we need this assertion. In practice, it prevents compilation + // on EL6 i386. Without the assertion, everything works. + // If you ever run into trouble with this code, please heed the warnings at + // http://man7.org/linux/man-pages/man3/makecontext.3.html#NOTES + // static_assert (sizeof(uintptr_t) == 8, + // "splitPointer() requires an 8 byte 'uintptr_t'"); + std::pair words; + auto rep = reinterpret_cast(ptr); + uint32_t const hw = rep >> 32; + auto const lw = static_cast(rep); + std::memcpy(&words.first, &hw, 4); + std::memcpy(&words.second, &lw, 4); + return words; } -template static inline -T* -joinPtr (int const first, int const second) noexcept { - static_assert (sizeof(int) == 4, "joinPtr() requires an 4 byte 'int'"); -// See above. -// static_assert (sizeof(uintptr_t) == 8, -// "joinPtr() requires an 8 byte 'uintptr_t'"); - uint32_t hw; - uint32_t lw; - std::memcpy (&hw, &first, 4); - std::memcpy (&lw, &second, 4); - return reinterpret_cast((static_cast(hw) << 32) | lw); +template +static inline T* +joinPtr(int const first, int const second) noexcept +{ + static_assert(sizeof(int) == 4, "joinPtr() requires an 4 byte 'int'"); + // See above. + // static_assert (sizeof(uintptr_t) == 8, + // "joinPtr() requires an 8 byte 'uintptr_t'"); + uint32_t hw; + uint32_t lw; + std::memcpy(&hw, &first, 4); + std::memcpy(&lw, &second, 4); + return reinterpret_cast((static_cast(hw) << 32) | lw); } -extern "C" { -static -void -threadWrapper (int const ctx0, int const ctx1, int const fun0, int const fun1) { +extern "C" +{ + static void + threadWrapper(int const ctx0, int const ctx1, int const fun0, int const fun1) + { notifyStackSwitchDone(); auto ctx = joinPtr(ctx0, ctx1); try { - auto start = std::move(*joinPtr>(fun0, fun1)); - start(); - } catch (...) { - ctx->exception = std::current_exception(); + auto start = std::move(*joinPtr>(fun0, fun1)); + start(); + } + catch (...) { + ctx->exception = std::current_exception(); } notifyStackSwitchToKernel(); -} + } } // extern "C" -pdns_ucontext_t::pdns_ucontext_t() { - uc_mcontext = new ::ucontext_t(); - uc_link = nullptr; +pdns_ucontext_t::pdns_ucontext_t() +{ + uc_mcontext = new ::ucontext_t(); + uc_link = nullptr; #ifdef PDNS_USE_VALGRIND - valgrind_id = 0; + valgrind_id = 0; #endif /* PDNS_USE_VALGRIND */ } -pdns_ucontext_t::~pdns_ucontext_t() { - delete static_cast(uc_mcontext); +pdns_ucontext_t::~pdns_ucontext_t() +{ + delete static_cast(uc_mcontext); #ifdef PDNS_USE_VALGRIND - if (valgrind_id != 0) { - VALGRIND_STACK_DEREGISTER(valgrind_id); - } + if (valgrind_id != 0) { + VALGRIND_STACK_DEREGISTER(valgrind_id); + } #endif /* PDNS_USE_VALGRIND */ } -void -pdns_swapcontext -(pdns_ucontext_t& __restrict octx, pdns_ucontext_t const& __restrict ctx) { - if (::swapcontext (static_cast(octx.uc_mcontext), - static_cast(ctx.uc_mcontext))) { - throw_errno ("swapcontext() failed"); - } - if (ctx.exception) { - std::rethrow_exception (ctx.exception); - } +void pdns_swapcontext(pdns_ucontext_t& __restrict octx, pdns_ucontext_t const& __restrict ctx) +{ + if (::swapcontext(static_cast(octx.uc_mcontext), + static_cast(ctx.uc_mcontext))) { + throw_errno("swapcontext() failed"); + } + if (ctx.exception) { + std::rethrow_exception(ctx.exception); + } } -void -pdns_makecontext -(pdns_ucontext_t& ctx, std::function& start) { - assert (ctx.uc_link); - assert (ctx.uc_stack.size()); +void pdns_makecontext(pdns_ucontext_t& ctx, std::function& start) +{ + assert(ctx.uc_link); + assert(ctx.uc_stack.size()); - auto const mcp = static_cast(ctx.uc_mcontext); - auto const next = static_cast(ctx.uc_link->uc_mcontext); - if (::getcontext (mcp)) { - throw_errno ("getcontext() failed"); - } - mcp->uc_link = next; - mcp->uc_stack.ss_sp = ctx.uc_stack.data(); - mcp->uc_stack.ss_size = ctx.uc_stack.size()-1; - mcp->uc_stack.ss_flags = 0; + auto const mcp = static_cast(ctx.uc_mcontext); + auto const next = static_cast(ctx.uc_link->uc_mcontext); + if (::getcontext(mcp)) { + throw_errno("getcontext() failed"); + } + mcp->uc_link = next; + mcp->uc_stack.ss_sp = ctx.uc_stack.data(); + mcp->uc_stack.ss_size = ctx.uc_stack.size() - 1; + mcp->uc_stack.ss_flags = 0; - auto ctxarg = splitPointer (&ctx); - auto funarg = splitPointer (&start); - return ::makecontext (mcp, reinterpret_cast(&threadWrapper), - 4, ctxarg.first, ctxarg.second, - funarg.first, funarg.second); + auto ctxarg = splitPointer(&ctx); + auto funarg = splitPointer(&start); + return ::makecontext(mcp, reinterpret_cast(&threadWrapper), + 4, ctxarg.first, ctxarg.second, + funarg.first, funarg.second); } diff --git a/pdns/recursordist/nod.cc b/pdns/recursordist/nod.cc index 133323c5b3..fd16679d31 100644 --- a/pdns/recursordist/nod.cc +++ b/pdns/recursordist/nod.cc @@ -36,7 +36,7 @@ using namespace nod; namespace filesystem = boost::filesystem; -// PersistentSBF Implementation +// PersistentSBF Implementation std::mutex PersistentSBF::d_cachedir_mutex; @@ -55,7 +55,8 @@ void PersistentSBF::remove_tmp_files(const filesystem::path& p, std::lock_guard< // In this way, we can have per-thread SBFs, but still snapshot and restore. // The mutex has to be static because we can't have multiple (i.e. per-thread) // instances iterating and writing to the cache dir at the same time -bool PersistentSBF::init(bool ignore_pid) { +bool PersistentSBF::init(bool ignore_pid) +{ if (d_init) return false; @@ -67,16 +68,13 @@ bool PersistentSBF::init(bool ignore_pid) { if (filesystem::exists(p) && filesystem::is_directory(p)) { remove_tmp_files(p, lock); filesystem::path newest_file; - std::time_t newest_time=time(nullptr); + std::time_t newest_time = time(nullptr); Regex file_regex(d_prefix + ".*\\." + bf_suffix + "$"); for (filesystem::directory_iterator i(p); i != filesystem::directory_iterator(); ++i) { - if (filesystem::is_regular_file(i->path()) && - file_regex.match(i->path().filename().string())) { - if (ignore_pid || - (i->path().filename().string().find(std::to_string(getpid())) == std::string::npos)) { + if (filesystem::is_regular_file(i->path()) && file_regex.match(i->path().filename().string())) { + if (ignore_pid || (i->path().filename().string().find(std::to_string(getpid())) == std::string::npos)) { // look for the newest file matching the regex - if ((last_write_time(i->path()) < newest_time) || - newest_file.empty()) { + if ((last_write_time(i->path()) < newest_time) || newest_file.empty()) { newest_time = last_write_time(i->path()); newest_file = i->path(); } @@ -101,14 +99,14 @@ bool PersistentSBF::init(bool ignore_pid) { catch (const std::runtime_error& e) { infile.close(); filesystem::remove(newest_file); - SLOG(g_log<error(Logr::Warning, e.what(), "NODDB init: Cannot parse file, removed", "file", Logging::Loggable(filename))); + SLOG(g_log << Logger::Warning << "NODDB init: Cannot parse file: " << filename << ": " << e.what() << "; removed" << endl, + log->error(Logr::Warning, e.what(), "NODDB init: Cannot parse file, removed", "file", Logging::Loggable(filename))); } } } } catch (const filesystem::filesystem_error& e) { - SLOG(g_log<error(Logr::Warning, e.what(), "NODDB init failed", "exception", Logging::Loggable("filesystem::filesystem_error"))); return false; } @@ -157,7 +155,7 @@ bool PersistentSBF::snapshotCurrent(std::thread::id tid) throw std::runtime_error("Cannot create temp file: " + stringerror()); } std::string str = iss.str(); - ssize_t len = write(fd, str.data(), str.length()); + ssize_t len = write(fd, str.data(), str.length()); if (len != static_cast(str.length())) { close(fd); filesystem::remove(ftmp.c_str()); @@ -171,7 +169,7 @@ bool PersistentSBF::snapshotCurrent(std::thread::id tid) filesystem::rename(ftmp, f); } catch (const std::runtime_error& e) { - SLOG(g_log<error(Logr::Warning, e.what(), "NODDB snapshot: Cannot rename file", "exception", Logging::Loggable("std::runtime_error"))); filesystem::remove(ftmp); throw; @@ -179,12 +177,12 @@ bool PersistentSBF::snapshotCurrent(std::thread::id tid) return true; } catch (const std::runtime_error& e) { - SLOG(g_log<error(Logr::Warning, e.what(), "NODDB snapshot: Cannot write file", "exception", Logging::Loggable("std::runtime_error"))); + SLOG(g_log << Logger::Warning << "NODDB snapshot: Cannot write file: " << e.what() << endl, + log->error(Logr::Warning, e.what(), "NODDB snapshot: Cannot write file", "exception", Logging::Loggable("std::runtime_error"))); } } else { - SLOG(g_log<info(Logr::Warning, "NODDB snapshot: Cannot write file", "file", Logging::Loggable(f.string()))); } } diff --git a/pdns/recursordist/nod.hh b/pdns/recursordist/nod.hh index e6ecf6c251..ede60d31dd 100644 --- a/pdns/recursordist/nod.hh +++ b/pdns/recursordist/nod.hh @@ -28,94 +28,113 @@ #include "lock.hh" #include "stable-bloom.hh" -namespace nod { - const float c_fp_rate = 0.01; - const size_t c_num_cells = 67108864; - const uint8_t c_num_dec = 10; - const unsigned int snapshot_interval_default = 600; - const std::string bf_suffix = "bf"; - const std::string sbf_prefix = "sbf"; +namespace nod +{ +const float c_fp_rate = 0.01; +const size_t c_num_cells = 67108864; +const uint8_t c_num_dec = 10; +const unsigned int snapshot_interval_default = 600; +const std::string bf_suffix = "bf"; +const std::string sbf_prefix = "sbf"; - // Theses classes are not designed to be shared between threads - // Use a new instance per-thread, e.g. using thread local storage - // Synchronization (at the class level) is still needed for reading from - // and writing to the cache dir - // Synchronization (at the instance level) is needed when snapshotting - class PersistentSBF { - public: - PersistentSBF() : d_sbf(bf::stableBF(c_fp_rate, c_num_cells, c_num_dec)) {} - PersistentSBF(uint32_t num_cells) : d_sbf(bf::stableBF(c_fp_rate, num_cells, c_num_dec)) {} - bool init(bool ignore_pid=false); - void setPrefix(const std::string& prefix) { d_prefix = prefix; } // Added to filenames in cachedir - void setCacheDir(const std::string& cachedir); - bool snapshotCurrent(std::thread::id tid); // Write the current file out to disk - void add(const std::string& data) { - // The only time this should block is when snapshotting - d_sbf.lock()->add(data); - } - bool test(const std::string& data) { return d_sbf.lock()->test(data); } - bool testAndAdd(const std::string& data) { - // The only time this should block is when snapshotting - return d_sbf.lock()->testAndAdd(data); - } - private: - void remove_tmp_files(const boost::filesystem::path&, std::lock_guard&); +// Theses classes are not designed to be shared between threads +// Use a new instance per-thread, e.g. using thread local storage +// Synchronization (at the class level) is still needed for reading from +// and writing to the cache dir +// Synchronization (at the instance level) is needed when snapshotting +class PersistentSBF +{ +public: + PersistentSBF() : + d_sbf(bf::stableBF(c_fp_rate, c_num_cells, c_num_dec)) {} + PersistentSBF(uint32_t num_cells) : + d_sbf(bf::stableBF(c_fp_rate, num_cells, c_num_dec)) {} + bool init(bool ignore_pid = false); + void setPrefix(const std::string& prefix) { d_prefix = prefix; } // Added to filenames in cachedir + void setCacheDir(const std::string& cachedir); + bool snapshotCurrent(std::thread::id tid); // Write the current file out to disk + void add(const std::string& data) + { + // The only time this should block is when snapshotting + d_sbf.lock()->add(data); + } + bool test(const std::string& data) { return d_sbf.lock()->test(data); } + bool testAndAdd(const std::string& data) + { + // The only time this should block is when snapshotting + return d_sbf.lock()->testAndAdd(data); + } - bool d_init{false}; - LockGuarded d_sbf; // Stable Bloom Filter - std::string d_cachedir; - std::string d_prefix = sbf_prefix; - static std::mutex d_cachedir_mutex; // One mutex for all instances of this class - }; +private: + void remove_tmp_files(const boost::filesystem::path&, std::lock_guard&); - class NODDB { - public: - NODDB() : d_psbf{} {} - NODDB(uint32_t num_cells) : d_psbf{num_cells} {} - // Set ignore_pid to true if you don't mind loading files - // created by the current process - bool init(bool ignore_pid=false) { - d_psbf.setPrefix("nod"); - return d_psbf.init(ignore_pid); - } - bool isNewDomain(const std::string& domain); // Returns true if newly observed domain - bool isNewDomain(const DNSName& dname); // As above - bool isNewDomainWithParent(const std::string& domain, std::string& observed); // Returns true if newly observed domain, in which case "observed" contains the parent domain which *was* observed (or "" if domain is . or no parent domains observed) - bool isNewDomainWithParent(const DNSName& dname, std::string& observed); // As above - void addDomain(const DNSName& dname); // You need to add this to refresh frequently used domains - void addDomain(const std::string& domain); // As above - void setSnapshotInterval(unsigned int secs) { d_snapshot_interval = secs; } - void setCacheDir(const std::string& cachedir) { d_psbf.setCacheDir(cachedir); } - bool snapshotCurrent(std::thread::id tid) { return d_psbf.snapshotCurrent(tid); } - static void startHousekeepingThread(std::shared_ptr noddbp, std::thread::id tid) { - noddbp->housekeepingThread(tid); - } - private: - PersistentSBF d_psbf; - unsigned int d_snapshot_interval{snapshot_interval_default}; // Number seconds between snapshots - void housekeepingThread(std::thread::id tid); - }; + bool d_init{false}; + LockGuarded d_sbf; // Stable Bloom Filter + std::string d_cachedir; + std::string d_prefix = sbf_prefix; + static std::mutex d_cachedir_mutex; // One mutex for all instances of this class +}; - class UniqueResponseDB { - public: - UniqueResponseDB() : d_psbf{} {} - UniqueResponseDB(uint32_t num_cells) : d_psbf{num_cells} {} - bool init(bool ignore_pid=false) { - d_psbf.setPrefix("udr"); - return d_psbf.init(ignore_pid); - } - bool isUniqueResponse(const std::string& response); - void addResponse(const std::string& response); - void setSnapshotInterval(unsigned int secs) { d_snapshot_interval = secs; } - void setCacheDir(const std::string& cachedir) { d_psbf.setCacheDir(cachedir); } - bool snapshotCurrent(std::thread::id tid) { return d_psbf.snapshotCurrent(tid); } - static void startHousekeepingThread(std::shared_ptr udrdbp, std::thread::id tid) { - udrdbp->housekeepingThread(tid); - } - private: - PersistentSBF d_psbf; - unsigned int d_snapshot_interval{snapshot_interval_default}; // Number seconds between snapshots - void housekeepingThread(std::thread::id tid); - }; +class NODDB +{ +public: + NODDB() : + d_psbf{} {} + NODDB(uint32_t num_cells) : + d_psbf{num_cells} {} + // Set ignore_pid to true if you don't mind loading files + // created by the current process + bool init(bool ignore_pid = false) + { + d_psbf.setPrefix("nod"); + return d_psbf.init(ignore_pid); + } + bool isNewDomain(const std::string& domain); // Returns true if newly observed domain + bool isNewDomain(const DNSName& dname); // As above + bool isNewDomainWithParent(const std::string& domain, std::string& observed); // Returns true if newly observed domain, in which case "observed" contains the parent domain which *was* observed (or "" if domain is . or no parent domains observed) + bool isNewDomainWithParent(const DNSName& dname, std::string& observed); // As above + void addDomain(const DNSName& dname); // You need to add this to refresh frequently used domains + void addDomain(const std::string& domain); // As above + void setSnapshotInterval(unsigned int secs) { d_snapshot_interval = secs; } + void setCacheDir(const std::string& cachedir) { d_psbf.setCacheDir(cachedir); } + bool snapshotCurrent(std::thread::id tid) { return d_psbf.snapshotCurrent(tid); } + static void startHousekeepingThread(std::shared_ptr noddbp, std::thread::id tid) + { + noddbp->housekeepingThread(tid); + } + +private: + PersistentSBF d_psbf; + unsigned int d_snapshot_interval{snapshot_interval_default}; // Number seconds between snapshots + void housekeepingThread(std::thread::id tid); +}; + +class UniqueResponseDB +{ +public: + UniqueResponseDB() : + d_psbf{} {} + UniqueResponseDB(uint32_t num_cells) : + d_psbf{num_cells} {} + bool init(bool ignore_pid = false) + { + d_psbf.setPrefix("udr"); + return d_psbf.init(ignore_pid); + } + bool isUniqueResponse(const std::string& response); + void addResponse(const std::string& response); + void setSnapshotInterval(unsigned int secs) { d_snapshot_interval = secs; } + void setCacheDir(const std::string& cachedir) { d_psbf.setCacheDir(cachedir); } + bool snapshotCurrent(std::thread::id tid) { return d_psbf.snapshotCurrent(tid); } + static void startHousekeepingThread(std::shared_ptr udrdbp, std::thread::id tid) + { + udrdbp->housekeepingThread(tid); + } + +private: + PersistentSBF d_psbf; + unsigned int d_snapshot_interval{snapshot_interval_default}; // Number seconds between snapshots + void housekeepingThread(std::thread::id tid); +}; } diff --git a/pdns/recursordist/resolve-context.hh b/pdns/recursordist/resolve-context.hh index ccac550532..c7354c7fe1 100644 --- a/pdns/recursordist/resolve-context.hh +++ b/pdns/recursordist/resolve-context.hh @@ -5,14 +5,15 @@ #include #include -struct ResolveContext { +struct ResolveContext +{ ResolveContext() { } ResolveContext(const ResolveContext& ctx) = delete; - ResolveContext & operator=(const ResolveContext&) = delete; - + ResolveContext& operator=(const ResolveContext&) = delete; + boost::optional d_initialRequestId; DNSName d_nsName; #ifdef HAVE_FSTRM diff --git a/pdns/recursordist/root-addresses.hh b/pdns/recursordist/root-addresses.hh index a0167b261f..3455b9bcfe 100644 --- a/pdns/recursordist/root-addresses.hh +++ b/pdns/recursordist/root-addresses.hh @@ -21,34 +21,36 @@ */ #pragma once -static const char* const rootIps4[]={"198.41.0.4", // a.root-servers.net. - "199.9.14.201", // b.root-servers.net. - "192.33.4.12", // c.root-servers.net. - "199.7.91.13", // d.root-servers.net. - "192.203.230.10", // e.root-servers.net. - "192.5.5.241", // f.root-servers.net. - "192.112.36.4", // g.root-servers.net. - "198.97.190.53", // h.root-servers.net. - "192.36.148.17", // i.root-servers.net. - "192.58.128.30", // j.root-servers.net. - "193.0.14.129", // k.root-servers.net. - "199.7.83.42", // l.root-servers.net. - "202.12.27.33" // m.root-servers.net. - }; +static const char* const rootIps4[] = { + "198.41.0.4", // a.root-servers.net. + "199.9.14.201", // b.root-servers.net. + "192.33.4.12", // c.root-servers.net. + "199.7.91.13", // d.root-servers.net. + "192.203.230.10", // e.root-servers.net. + "192.5.5.241", // f.root-servers.net. + "192.112.36.4", // g.root-servers.net. + "198.97.190.53", // h.root-servers.net. + "192.36.148.17", // i.root-servers.net. + "192.58.128.30", // j.root-servers.net. + "193.0.14.129", // k.root-servers.net. + "199.7.83.42", // l.root-servers.net. + "202.12.27.33" // m.root-servers.net. +}; static size_t const rootIps4Count = sizeof(rootIps4) / sizeof(*rootIps4); -static const char* const rootIps6[]={"2001:503:ba3e::2:30", // a.root-servers.net. - "2001:500:200::b", // b.root-servers.net. - "2001:500:2::c", // c.root-servers.net. - "2001:500:2d::d", // d.root-servers.net. - "2001:500:a8::e", // e.root-servers.net. - "2001:500:2f::f", // f.root-servers.net. - "2001:500:12::d0d", // g.root-servers.net. - "2001:500:1::53", // h.root-servers.net. - "2001:7fe::53", // i.root-servers.net. - "2001:503:c27::2:30", // j.root-servers.net. - "2001:7fd::1", // k.root-servers.net. - "2001:500:9f::42", // l.root-servers.net. - "2001:dc3::35" // m.root-servers.net. - }; +static const char* const rootIps6[] = { + "2001:503:ba3e::2:30", // a.root-servers.net. + "2001:500:200::b", // b.root-servers.net. + "2001:500:2::c", // c.root-servers.net. + "2001:500:2d::d", // d.root-servers.net. + "2001:500:a8::e", // e.root-servers.net. + "2001:500:2f::f", // f.root-servers.net. + "2001:500:12::d0d", // g.root-servers.net. + "2001:500:1::53", // h.root-servers.net. + "2001:7fe::53", // i.root-servers.net. + "2001:503:c27::2:30", // j.root-servers.net. + "2001:7fd::1", // k.root-servers.net. + "2001:500:9f::42", // l.root-servers.net. + "2001:dc3::35" // m.root-servers.net. +}; static size_t const rootIps6Count = sizeof(rootIps6) / sizeof(*rootIps6); diff --git a/pdns/recursordist/rpzloader.cc b/pdns/recursordist/rpzloader.cc index f517aa96ca..df83ce07ac 100644 --- a/pdns/recursordist/rpzloader.cc +++ b/pdns/recursordist/rpzloader.cc @@ -21,21 +21,21 @@ Netmask makeNetmaskFromRPZ(const DNSName& name) * $NETMASK.zz (::/$NETMASK) * Terrible right? */ - if(parts.size() < 2 || parts.size() > 9) - throw PDNSException("Invalid IP address in RPZ: "+name.toLogString()); + if (parts.size() < 2 || parts.size() > 9) + throw PDNSException("Invalid IP address in RPZ: " + name.toLogString()); bool isV6 = (stoi(parts[0]) > 32); bool hadZZ = false; - for (auto &part : parts) { + for (auto& part : parts) { // Check if we have an IPv4 octet for (auto c : part) if (!isdigit(c)) isV6 = true; - if (pdns_iequals(part,"zz")) { + if (pdns_iequals(part, "zz")) { if (hadZZ) - throw PDNSException("more than one 'zz' label found in RPZ name"+name.toLogString()); + throw PDNSException("more than one 'zz' label found in RPZ name" + name.toLogString()); part = ""; isV6 = true; hadZZ = true; @@ -43,17 +43,17 @@ Netmask makeNetmaskFromRPZ(const DNSName& name) } if (isV6 && parts.size() < 9 && !hadZZ) - throw PDNSException("No 'zz' label found in an IPv6 RPZ name shorter than 9 elements: "+name.toLogString()); + throw PDNSException("No 'zz' label found in an IPv6 RPZ name shorter than 9 elements: " + name.toLogString()); if (parts.size() == 5 && !isV6) - return Netmask(parts[4]+"."+parts[3]+"."+parts[2]+"."+parts[1]+"/"+parts[0]); + return Netmask(parts[4] + "." + parts[3] + "." + parts[2] + "." + parts[1] + "/" + parts[0]); string v6; - if (parts[parts.size()-1] == "") { + if (parts[parts.size() - 1] == "") { v6 += ":"; } - for (uint8_t i = parts.size()-1 ; i > 0; i--) { + for (uint8_t i = parts.size() - 1; i > 0; i--) { v6 += parts[i]; if (i > 1 || (i == 1 && parts[i] == "")) { v6 += ":"; @@ -74,36 +74,37 @@ static void RPZRecordToPolicy(const DNSRecord& dr, std::shared_ptr(dr); if (!crc) { return; } - auto crcTarget=crc->getTarget(); - if(defpol) { - pol=*defpol; + auto crcTarget = crc->getTarget(); + if (defpol) { + pol = *defpol; defpolApplied = true; } - else if(crcTarget.isRoot()) { + else if (crcTarget.isRoot()) { // cerr<<"Wants NXDOMAIN for "<info(Logr::Info, "Discarding unsupported RPZ entry", "target", Logging::Loggable(crcTarget), "name", Logging::Loggable(dr.d_name))); return; } @@ -129,7 +130,7 @@ static void RPZRecordToPolicy(const DNSRecord& dr, std::shared_ptrd_ttl < 0) { pol.d_ttl = static_cast(std::min(maxTTL, dr.d_ttl)); - } else { + } + else { pol.d_ttl = static_cast(std::min(maxTTL, static_cast(pol.d_ttl))); } // now to DO something with that - if(dr.d_name.isPartOf(rpzNSDname)) { - DNSName filt=dr.d_name.makeRelative(rpzNSDname); - if(addOrRemove) + if (dr.d_name.isPartOf(rpzNSDname)) { + DNSName filt = dr.d_name.makeRelative(rpzNSDname); + if (addOrRemove) zone->addNSTrigger(filt, std::move(pol), defpolApplied); else zone->rmNSTrigger(filt, std::move(pol)); - } else if(dr.d_name.isPartOf(rpzClientIP)) { - DNSName filt=dr.d_name.makeRelative(rpzClientIP); - auto nm=makeNetmaskFromRPZ(filt); - if(addOrRemove) + } + else if (dr.d_name.isPartOf(rpzClientIP)) { + DNSName filt = dr.d_name.makeRelative(rpzClientIP); + auto nm = makeNetmaskFromRPZ(filt); + if (addOrRemove) zone->addClientTrigger(nm, std::move(pol), defpolApplied); else zone->rmClientTrigger(nm, std::move(pol)); - - } else if(dr.d_name.isPartOf(rpzIP)) { + } + else if (dr.d_name.isPartOf(rpzIP)) { // cerr<<"Should apply answer content IP policy: "<addResponseTrigger(nm, std::move(pol), defpolApplied); else zone->rmResponseTrigger(nm, std::move(pol)); - } else if(dr.d_name.isPartOf(rpzNSIP)) { - DNSName filt=dr.d_name.makeRelative(rpzNSIP); - auto nm=makeNetmaskFromRPZ(filt); - if(addOrRemove) + } + else if (dr.d_name.isPartOf(rpzNSIP)) { + DNSName filt = dr.d_name.makeRelative(rpzNSIP); + auto nm = makeNetmaskFromRPZ(filt); + if (addOrRemove) zone->addNSIPTrigger(nm, std::move(pol), defpolApplied); else zone->rmNSIPTrigger(nm, std::move(pol)); - } else { - if(addOrRemove) { + } + else { + if (addOrRemove) { /* if we did override the existing policy with the default policy, we might turn two A or AAAA into a CNAME, which would trigger an exception. Let's just ignore it. */ @@ -193,10 +198,10 @@ static shared_ptr loadRPZFromServer(Logr::log_t plogger, const { auto logger = plogger->withValues("primary", Logging::Loggable(primary)); - SLOG(g_log<info(Logr::Info, "Loading RPZ from nameserver")); - if(!tt.name.empty()) { - SLOG(g_log<info(Logr::Info, "Using TSIG key for authentication", "tsig_key_name", Logging::Loggable(tt.name), "tsig_key_algorithm", Logging::Loggable(tt.algo))); } @@ -205,44 +210,44 @@ static shared_ptr loadRPZFromServer(Logr::log_t plogger, const local = pdns::getQueryLocalAddress(primary.sin4.sin_family, 0); AXFRRetriever axfr(primary, zoneName, tt, &local, maxReceivedBytes, axfrTimeout); - unsigned int nrecords=0; + unsigned int nrecords = 0; Resolver::res_t nop; vector chunk; - time_t last=0; + time_t last = 0; time_t axfrStart = time(nullptr); time_t axfrNow = time(nullptr); shared_ptr sr; - while(axfr.getChunk(nop, &chunk, (axfrStart + axfrTimeout - axfrNow))) { - for(auto& dr : chunk) { - if(dr.d_type==QType::NS || dr.d_type==QType::TSIG) { - continue; + while (axfr.getChunk(nop, &chunk, (axfrStart + axfrTimeout - axfrNow))) { + for (auto& dr : chunk) { + if (dr.d_type == QType::NS || dr.d_type == QType::TSIG) { + continue; } dr.d_name.makeUsRelative(zoneName); - if(dr.d_type==QType::SOA) { - sr = getRR(dr); - continue; + if (dr.d_type == QType::SOA) { + sr = getRR(dr); + continue; } RPZRecordToPolicy(dr, zone, true, defpol, defpolOverrideLocal, maxTTL, logger); nrecords++; - } + } axfrNow = time(nullptr); if (axfrNow < axfrStart || axfrNow - axfrStart > axfrTimeout) { throw PDNSException("Total AXFR time exceeded!"); } - if(last != time(0)) { - SLOG(g_log<info(Logr::Info, "RPZ load in progress", "nrecords", Logging::Loggable(nrecords))); - last=time(0); + last = time(0); } } - SLOG(g_log<getZoneRepresentation()<getZoneRepresentation() << endl, logger->info(Logr::Info, "RPZ load completed", "nrecords", Logging::Loggable(nrecords), "soa", Logging::Loggable(sr->getZoneRepresentation()))); return sr; } -static LockGuarded > > s_rpzStats; +static LockGuarded>> s_rpzStats; shared_ptr getRPZZoneStats(const std::string& zone) { @@ -290,26 +295,26 @@ std::shared_ptr loadRPZFromFile(const std::string& fname, std: DNSResourceRecord drr; DNSName domain; auto log = g_slog->withName("rpz")->withValues("file", Logging::Loggable(fname), "zone", Logging::Loggable(zone->getName())); - while(zpt.get(drr)) { + while (zpt.get(drr)) { try { - if(drr.qtype.getCode() == QType::CNAME && drr.content.empty()) - drr.content="."; + if (drr.qtype.getCode() == QType::CNAME && drr.content.empty()) + drr.content = "."; DNSRecord dr(drr); - if(dr.d_type == QType::SOA) { + if (dr.d_type == QType::SOA) { sr = getRR(dr); domain = dr.d_name; zone->setDomain(domain); } - else if(dr.d_type == QType::NS) { - continue; + else if (dr.d_type == QType::NS) { + continue; } else { - dr.d_name=dr.d_name.makeRelative(domain); - RPZRecordToPolicy(dr, zone, true, defpol, defpolOverrideLocal, maxTTL, log); + dr.d_name = dr.d_name.makeRelative(domain); + RPZRecordToPolicy(dr, zone, true, defpol, defpolOverrideLocal, maxTTL, log); } } - catch(const PDNSException& pe) { - throw PDNSException("Issue parsing '"+drr.qname.toLogString()+"' '"+drr.content+"' at "+zpt.getLineOfFile()+": "+pe.reason); + catch (const PDNSException& pe) { + throw PDNSException("Issue parsing '" + drr.qname.toLogString() + "' '" + drr.content + "' at " + zpt.getLineOfFile() + ": " + pe.reason); } } @@ -326,16 +331,16 @@ static bool dumpZoneToDisk(Logr::log_t logger, const DNSName& zoneName, const st std::string temp = dumpZoneFileName + "XXXXXX"; int fd = mkstemp(&temp.at(0)); if (fd < 0) { - SLOG(g_log<error(Logr::Error, errno, "Unable to create temporary file")); return false; } - auto fp = std::unique_ptr(fdopen(fd, "w+"), fclose); + auto fp = std::unique_ptr(fdopen(fd, "w+"), fclose); if (!fp) { int err = errno; close(fd); - SLOG(g_log<error(Logr::Error, err, "Unable to open file pointer")); return false; } @@ -343,32 +348,32 @@ static bool dumpZoneToDisk(Logr::log_t logger, const DNSName& zoneName, const st try { newZone->dump(fp.get()); } - catch(const std::exception& e) { - SLOG(g_log<error(Logr::Error, e.what(), "Error while dumping the content of the RPZ")); return false; } if (fflush(fp.get()) != 0) { - SLOG(g_log<error(Logr::Warning, errno, "Error while flushing the content of the RPZ")); return false; } if (fsync(fileno(fp.get())) != 0) { - SLOG(g_log<error(Logr::Error, errno, "Error while syncing the content of the RPZ")); return false; } if (fclose(fp.release()) != 0) { - SLOG(g_log<error(Logr::Error, errno, "Error while writing the content of the RPZ")); return false; } if (rename(temp.c_str(), dumpZoneFileName.c_str()) != 0) { - SLOG(g_log<error(Logr::Error, errno, "Error while moving the content of the RPZ", "destination_file", Logging::Loggable(dumpZoneFileName))); return false; } @@ -387,7 +392,7 @@ void RPZIXFRTracker(const std::vector& primaries, const boost::opt /* we can _never_ modify this zone directly, we need to do a full copy then replace the existing zone */ std::shared_ptr oldZone = luaconfsLocal->dfe.getZone(zoneIdx); if (!oldZone) { - SLOG(g_log<error(Logr::Error, "Unable to retrieve RPZ zone from configuration", "index", Logging::Loggable(zoneIdx))); return; } @@ -414,8 +419,8 @@ void RPZIXFRTracker(const std::vector& primaries, const boost::opt setRPZZoneNewState(polName, sr->d_st.serial, newZone->size(), false, true); g_luaconfs.modify([zoneIdx, &newZone](LuaConfigItems& lci) { - lci.dfe.setZone(zoneIdx, newZone); - }); + lci.dfe.setZone(zoneIdx, newZone); + }); if (!dumpZoneFileName.empty()) { dumpZoneToDisk(logger, zoneName, newZone, dumpZoneFileName); @@ -424,13 +429,13 @@ void RPZIXFRTracker(const std::vector& primaries, const boost::opt /* no need to try another primary */ break; } - catch(const std::exception& e) { - SLOG(g_log<error(Logr::Warning, e.what(), "Unable to load RPZ zone, will retry", "from", Logging::Loggable(primary), "exception", Logging::Loggable("std::exception"), "refresh", Logging::Loggable(refresh))); incRPZFailedTransfers(polName); } - catch(const PDNSException& e) { - SLOG(g_log<error(Logr::Warning, e.reason, "Unable to load RPZ zone, will retry", "from", Logging::Loggable(primary), "exception", Logging::Loggable("PDNSException"), "refresh", Logging::Loggable(refresh))); incRPZFailedTransfers(polName); } @@ -443,9 +448,9 @@ void RPZIXFRTracker(const std::vector& primaries, const boost::opt bool skipRefreshDelay = isPreloaded; - for(;;) { + for (;;) { DNSRecord dr; - dr.d_content=sr; + dr.d_content = sr; if (skipRefreshDelay) { skipRefreshDelay = false; @@ -458,16 +463,16 @@ void RPZIXFRTracker(const std::vector& primaries, const boost::opt /* the configuration has been reloaded, meaning that a new thread has been started to handle that zone and we are now obsolete. */ - SLOG(g_log<info(Logr::Info, "A more recent configuration has been found, stopping the existing RPZ update thread")); return; } - vector, vector > > deltas; + vector, vector>> deltas; for (const auto& primary : primaries) { auto soa = getRR(dr); auto serial = soa ? soa->d_st.serial : 0; - SLOG(g_log<info(Logr::Info, "Getting IXFR deltas", "address", Logging::Loggable(primary), "ourserial", Logging::Loggable(serial))); ComboAddress local(localAddress); @@ -480,30 +485,31 @@ void RPZIXFRTracker(const std::vector& primaries, const boost::opt /* no need to try another primary */ break; - } catch(const std::runtime_error& e ){ - SLOG(g_log<error(Logr::Warning, e.what(), "Exception during retrieval of delta", "exception", Logging::Loggable("std::runtime_error"))); incRPZFailedTransfers(polName); continue; } } - if(deltas.empty()) { + if (deltas.empty()) { continue; } try { - SLOG(g_log<info(Logr::Info, "Processing deltas", "size", Logging::Loggable(deltas.size()))); if (luaconfsLocal->generation != configGeneration) { - SLOG(g_log<info(Logr::Info, "A more recent configuration has been found, stopping the existing RPZ update thread")) return; } oldZone = luaconfsLocal->dfe.getZone(zoneIdx); if (!oldZone || oldZone->getDomain() != zoneName) { - SLOG(g_log<info(Logr::Info, "This policy is no more, stopping the existing RPZ update thread")); return; } @@ -512,21 +518,21 @@ void RPZIXFRTracker(const std::vector& primaries, const boost::opt /* initialize the current serial to the last one */ std::shared_ptr currentSR = sr; - int totremove=0, totadd=0; + int totremove = 0, totadd = 0; bool fullUpdate = false; - for(const auto& delta : deltas) { + for (const auto& delta : deltas) { const auto& remove = delta.first; const auto& add = delta.second; - if(remove.empty()) { - SLOG(g_log<info(Logr::Warning, "IXFR update is a whole new zone")); newZone->clear(); fullUpdate = true; } - for(const auto& rr : remove) { // should always contain the SOA - if(rr.d_type == QType::NS) + for (const auto& rr : remove) { // should always contain the SOA + if (rr.d_type == QType::NS) continue; - if(rr.d_type == QType::SOA) { + if (rr.d_type == QType::SOA) { auto oldsr = getRR(rr); if (oldsr && oldsr->d_st.serial == currentSR->d_st.serial) { // cout<<"Got good removal of SOA serial "<d_st.serial<& primaries, const boost::opt } else { totremove++; - SLOG(g_log<<(g_logRPZChanges ? Logger::Info : Logger::Debug)<<"Had removal of "<info(g_logRPZChanges ? Logr::Info : Logr::Debug, "Remove from RPZ zone", "name", Logging::Loggable(rr.d_name))); RPZRecordToPolicy(rr, newZone, false, defpol, defpolOverrideLocal, maxTTL, logger); } } - for(const auto& rr : add) { // should always contain the new SOA - if(rr.d_type == QType::NS) + for (const auto& rr : add) { // should always contain the new SOA + if (rr.d_type == QType::NS) continue; - if(rr.d_type == QType::SOA) { + if (rr.d_type == QType::SOA) { auto tempSR = getRR(rr); // g_log<d_st.serial<& primaries, const boost::opt } else { totadd++; - SLOG(g_log<<(g_logRPZChanges ? Logger::Info : Logger::Debug)<<"Had addition of "<info(g_logRPZChanges ? Logr::Info : Logr::Debug, "Addition to RPZ zone", "name", Logging::Loggable(rr.d_name))); RPZRecordToPolicy(rr, newZone, true, defpol, defpolOverrideLocal, maxTTL, logger); } @@ -571,8 +577,8 @@ void RPZIXFRTracker(const std::vector& primaries, const boost::opt if (currentSR) { sr = currentSR; } - SLOG(g_log<d_st.serial<info(Logr::Info, "RPZ mutations", "removals", Logging::Loggable(totremove), "additions", Logging::Loggable(totadd), "newserial", Logging::Loggable(sr->d_st.serial))); + SLOG(g_log << Logger::Info << "Had " << totremove << " RPZ removal" << addS(totremove) << ", " << totadd << " addition" << addS(totadd) << " for " << zoneName << " New serial: " << sr->d_st.serial << endl, + logger->info(Logr::Info, "RPZ mutations", "removals", Logging::Loggable(totremove), "additions", Logging::Loggable(totadd), "newserial", Logging::Loggable(sr->d_st.serial))); newZone->setSerial(sr->d_st.serial); newZone->setRefresh(sr->d_st.refresh); setRPZZoneNewState(polName, sr->d_st.serial, newZone->size(), false, fullUpdate); @@ -582,13 +588,13 @@ void RPZIXFRTracker(const std::vector& primaries, const boost::opt since they might have been updated by another RPZ IXFR tracker thread. */ if (luaconfsLocal->generation != configGeneration) { - SLOG(g_log<info(Logr::Info, "A more recent configuration has been found, stopping the existing RPZ update thread")); return; } g_luaconfs.modify([zoneIdx, &newZone](LuaConfigItems& lci) { - lci.dfe.setZone(zoneIdx, newZone); - }); + lci.dfe.setZone(zoneIdx, newZone); + }); if (!dumpZoneFileName.empty()) { dumpZoneToDisk(logger, zoneName, newZone, dumpZoneFileName); @@ -596,11 +602,11 @@ void RPZIXFRTracker(const std::vector& primaries, const boost::opt refresh = std::max(refreshFromConf ? refreshFromConf : newZone->getRefresh(), 1U); } catch (const std::exception& e) { - SLOG(g_log << Logger::Error << "Error while applying the update received over XFR for "<error(Logr::Error, e.what(), "Exception while applying the update received over XFR, skipping", "exception", Logging::Loggable("std::exception"))); } catch (const PDNSException& e) { - SLOG(g_log << Logger::Error << "Error while applying the update received over XFR for "<error(Logr::Error, e.reason, "Exception while applying the update received over XFR, skipping", "exception", Logging::Loggable("PDNSException"))); } } diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 039ae29801..79201e4f0f 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -41,13 +41,15 @@ rec::GlobalCounters g_Counters; thread_local rec::TCounters t_Counters(g_Counters); -template +template class fails_t : public boost::noncopyable { public: typedef uint64_t counter_t; - struct value_t { - value_t(const T &a) : key(a) {} + struct value_t + { + value_t(const T& a) : + key(a) {} T key; mutable counter_t value{0}; time_t last{0}; @@ -56,10 +58,11 @@ public: typedef multi_index_container, member>, - ordered_non_unique, member> - >> cont_t; + ordered_non_unique, member>>> + cont_t; - cont_t getMapCopy() const { + cont_t getMapCopy() const + { return d_cont; } @@ -80,9 +83,9 @@ public: if (i->value < std::numeric_limits::max()) { i->value++; } - auto &ind = d_cont.template get(); + auto& ind = d_cont.template get(); time_t tm = now.tv_sec; - ind.modify(i, [tm](value_t &val) { val.last = tm; }); + ind.modify(i, [tm](value_t& val) { val.last = tm; }); return i->value; } @@ -101,8 +104,9 @@ public: return d_cont.size(); } - void prune(time_t cutoff) { - auto &ind = d_cont.template get(); + void prune(time_t cutoff) + { + auto& ind = d_cont.template get(); ind.erase(ind.begin(), ind.upper_bound(cutoff)); } @@ -157,8 +161,8 @@ private: }; public: - DecayingEwmaCollection(const DNSName& name, const struct timeval ts = {0, 0}) - : d_name(name), d_lastget(ts) + DecayingEwmaCollection(const DNSName& name, const struct timeval ts = {0, 0}) : + d_name(name), d_lastget(ts) { } @@ -167,7 +171,7 @@ public: d_collection[remote].submit(usecs, d_lastget, now); } - float getFactor(const struct timeval &now) const + float getFactor(const struct timeval& now) const { float diff = makeFloat(d_lastget - now); return expf(diff / 60.0f); // is 1.0 or less @@ -180,7 +184,7 @@ public: void purge(const std::map& keep) const { - for (auto iter = d_collection.begin(); iter != d_collection.end(); ) { + for (auto iter = d_collection.begin(); iter != d_collection.end();) { if (keep.find(iter->first) != keep.end()) { ++iter; } @@ -196,12 +200,10 @@ public: struct timeval d_lastget; }; -class nsspeeds_t : - public multi_index_container, member>, - ordered_non_unique, member> - >> +class nsspeeds_t : public multi_index_container, member>, + ordered_non_unique, member>>> { public: const auto& find_or_enter(const DNSName& name, const struct timeval& now) @@ -240,15 +242,16 @@ public: } }; -static LockGuarded s_nsSpeeds; +static LockGuarded s_nsSpeeds; -template class Throttle : public boost::noncopyable +template +class Throttle : public boost::noncopyable { public: - struct entry_t { - entry_t(const Thing& thing_, time_t ttd_, unsigned int count_) : thing(thing_), ttd(ttd_), count(count_) + entry_t(const Thing& thing_, time_t ttd_, unsigned int count_) : + thing(thing_), ttd(ttd_), count(count_) { } Thing thing; @@ -258,10 +261,10 @@ public: typedef multi_index_container, member>, - ordered_non_unique, member> - >> cont_t; + ordered_non_unique, member>>> + cont_t; - bool shouldThrottle(time_t now, const Thing &t) + bool shouldThrottle(time_t now, const Thing& t) { auto i = d_cont.find(t); if (i == d_cont.end()) { @@ -276,17 +279,18 @@ public: return true; // still listed, still blocked } - void throttle(time_t now, const Thing &t, time_t ttl, unsigned int count) + void throttle(time_t now, const Thing& t, time_t ttl, unsigned int count) { auto i = d_cont.find(t); time_t ttd = now + ttl; if (i == d_cont.end()) { d_cont.emplace(t, ttd, count); - } else if (ttd > i->ttd || count > i->count) { + } + else if (ttd > i->ttd || count > i->count) { ttd = std::max(i->ttd, ttd); count = std::max(i->count, count); - auto &ind = d_cont.template get(); - ind.modify(i, [ttd,count](entry_t &e) { e.ttd = ttd; e.count = count; }); + auto& ind = d_cont.template get(); + ind.modify(i, [ttd, count](entry_t& e) { e.ttd = ttd; e.count = count; }); } } @@ -305,8 +309,9 @@ public: d_cont.clear(); } - void prune(time_t now) { - auto &ind = d_cont.template get(); + void prune(time_t now) + { + auto& ind = d_cont.template get(); ind.erase(ind.begin(), ind.upper_bound(now)); } @@ -314,12 +319,12 @@ private: cont_t d_cont; }; -static LockGuarded>> s_throttle; +static LockGuarded>> s_throttle; struct SavedParentEntry { - SavedParentEntry(const DNSName& name, map>&& nsAddresses, time_t ttd) - : d_domain(name), d_nsAddresses(nsAddresses), d_ttd(ttd) + SavedParentEntry(const DNSName& name, map>&& nsAddresses, time_t ttd) : + d_domain(name), d_nsAddresses(nsAddresses), d_ttd(ttd) { } DNSName d_domain; @@ -331,15 +336,15 @@ struct SavedParentEntry typedef multi_index_container< SavedParentEntry, indexed_by, member>, - ordered_non_unique, member> - >> SavedParentNSSetBase; + ordered_non_unique, member>>> + SavedParentNSSetBase; class SavedParentNSSet : public SavedParentNSSetBase { public: void prune(time_t now) { - auto &ind = get(); + auto& ind = get(); ind.erase(ind.begin(), ind.upper_bound(now)); } void inc(const DNSName& name) @@ -355,7 +360,7 @@ public: } }; -static LockGuarded s_savedParentNSSet; +static LockGuarded s_savedParentNSSet; thread_local SyncRes::ThreadLocalStorage SyncRes::t_sstorage; thread_local std::unique_ptr t_timeouts; @@ -377,7 +382,13 @@ struct DoTStatus d_address(ip), d_auth(auth), d_ttd(ttd) { } - enum Status : uint8_t { Unknown, Busy, Bad, Good }; + enum Status : uint8_t + { + Unknown, + Busy, + Bad, + Good + }; const ComboAddress d_address; const DNSName d_auth; time_t d_ttd; @@ -385,7 +396,7 @@ struct DoTStatus mutable Status d_status{Unknown}; std::string toString() const { - const std::array n{ "Unknown", "Busy", "Bad", "Good" }; + const std::array n{"Unknown", "Busy", "Bad", "Good"}; unsigned int v = static_cast(d_status); return v >= n.size() ? "?" : n[v]; } @@ -396,17 +407,17 @@ struct DoTMap multi_index_container, member>, - ordered_non_unique, member> - >> d_map; + ordered_non_unique, member>>> + d_map; uint64_t d_numBusy{0}; - void prune(time_t cutoff) { - auto &ind = d_map.template get(); + void prune(time_t cutoff) + { + auto& ind = d_map.template get(); ind.erase(ind.begin(), ind.upper_bound(cutoff)); } }; - static LockGuarded s_dotMap; static const time_t dotFailWait = 24 * 3600; @@ -457,7 +468,13 @@ int SyncRes::s_event_trace_enabled; bool SyncRes::s_save_parent_ns_set; unsigned int SyncRes::s_max_busy_dot_probes; -#define LOG(x) if(d_lm == Log) { g_log <&start, vector&additionals, std::set>& uniqueCalls, std::set>& uniqueResults, unsigned int depth, unsigned additionaldepth, bool& additionalsNotInCache) +void SyncRes::addAdditionals(QType qtype, const vector& start, vector& additionals, std::set>& uniqueCalls, std::set>& uniqueResults, unsigned int depth, unsigned additionaldepth, bool& additionalsNotInCache) { if (additionaldepth >= 5 || start.empty()) { return; @@ -627,7 +643,7 @@ void SyncRes::addAdditionals(QType qtype, const vector&start, vector< resolveAdditionals(addname, targettype, mode, records, depth, additionalsNotInCache); } if (!records.empty()) { - for (auto r = records.begin(); r != records.end(); ) { + for (auto r = records.begin(); r != records.end();) { QType covered = QType::ENT; if (r->d_type == QType::RRSIG) { if (auto rsig = getRR(*r); rsig != nullptr) { @@ -637,7 +653,8 @@ void SyncRes::addAdditionals(QType qtype, const vector&start, vector< if (uniqueResults.count(std::tuple(r->d_name, QType(r->d_type), covered)) > 0) { // A bit expensive for vectors, but they are small r = records.erase(r); - } else { + } + else { ++r; } } @@ -658,7 +675,7 @@ void SyncRes::addAdditionals(QType qtype, const vector&start, vector< } // The entry point for other code -bool SyncRes::addAdditionals(QType qtype, vector&ret, unsigned int depth) +bool SyncRes::addAdditionals(QType qtype, vector& ret, unsigned int depth) { // The additional records of interest std::vector additionals; @@ -681,27 +698,27 @@ bool SyncRes::addAdditionals(QType qtype, vector&ret, unsigned int de } /** everything begins here - this is the entry point just after receiving a packet */ -int SyncRes::beginResolve(const DNSName &qname, const QType qtype, QClass qclass, vector&ret, unsigned int depth) +int SyncRes::beginResolve(const DNSName& qname, const QType qtype, QClass qclass, vector& ret, unsigned int depth) { d_eventTrace.add(RecEventTrace::SyncRes); vState state = vState::Indeterminate; t_Counters.at(rec::Counter::syncresqueries)++; - d_wasVariable=false; - d_wasOutOfBand=false; + d_wasVariable = false; + d_wasOutOfBand = false; d_cutStates.clear(); if (doSpecialNamesResolve(qname, qtype, qclass, ret)) { d_queryValidationState = vState::Insecure; // this could fool our stats into thinking a validation took place - return 0; // so do check before updating counters (we do now) + return 0; // so do check before updating counters (we do now) } if (isUnsupported(qtype)) { return -1; } - if(qclass==QClass::ANY) - qclass=QClass::IN; - else if(qclass!=QClass::IN) + if (qclass == QClass::ANY) + qclass = QClass::IN; + else if (qclass != QClass::IN) return -1; if (qtype == QType::DS) { @@ -712,7 +729,7 @@ int SyncRes::beginResolve(const DNSName &qname, const QType qtype, QClass qclass } set beenthere; - int res=doResolve(qname, qtype, ret, depth, beenthere, state); + int res = doResolve(qname, qtype, ret, depth, beenthere, state); d_queryValidationState = state; if (shouldValidate()) { @@ -722,7 +739,8 @@ int SyncRes::beginResolve(const DNSName &qname, const QType qtype, QClass qclass auto xdnssec = g_xdnssec.getLocal(); if (xdnssec->check(qname)) { increaseXDNSSECStateCounter(d_queryValidationState); - } else { + } + else { increaseDNSSECStateCounter(d_queryValidationState); } } @@ -754,24 +772,22 @@ int SyncRes::beginResolve(const DNSName &qname, const QType qtype, QClass qclass * - trustanchor.server CH TXT * - negativetrustanchor.server CH TXT */ -bool SyncRes::doSpecialNamesResolve(const DNSName &qname, const QType qtype, const QClass qclass, vector &ret) +bool SyncRes::doSpecialNamesResolve(const DNSName& qname, const QType qtype, const QClass qclass, vector& ret) { static const DNSName arpa("1.0.0.127.in-addr.arpa."), ip6_arpa("1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa."), localhost("localhost."), versionbind("version.bind."), idserver("id.server."), versionpdns("version.pdns."), trustanchorserver("trustanchor.server."), negativetrustanchorserver("negativetrustanchor.server."); bool handled = false; - vector > answers; + vector> answers; - if ((qname == arpa || qname == ip6_arpa) && - qclass == QClass::IN) { + if ((qname == arpa || qname == ip6_arpa) && qclass == QClass::IN) { handled = true; if (qtype == QType::PTR || qtype == QType::ANY) answers.emplace_back(QType::PTR, "localhost."); } - if (qname.isPartOf(localhost) && - qclass == QClass::IN) { + if (qname.isPartOf(localhost) && qclass == QClass::IN) { handled = true; if (qtype == QType::A || qtype == QType::ANY) answers.emplace_back(QType::A, "127.0.0.1"); @@ -779,29 +795,27 @@ bool SyncRes::doSpecialNamesResolve(const DNSName &qname, const QType qtype, con answers.emplace_back(QType::AAAA, "::1"); } - if ((qname == versionbind || qname == idserver || qname == versionpdns) && - qclass == QClass::CHAOS) { + if ((qname == versionbind || qname == idserver || qname == versionpdns) && qclass == QClass::CHAOS) { handled = true; if (qtype == QType::TXT || qtype == QType::ANY) { - if(qname == versionbind || qname == versionpdns) + if (qname == versionbind || qname == versionpdns) answers.emplace_back(QType::TXT, "\"" + ::arg()["version-string"] + "\""); else if (s_serverID != "disabled") answers.emplace_back(QType::TXT, "\"" + s_serverID + "\""); } } - if (qname == trustanchorserver && qclass == QClass::CHAOS && - ::arg().mustDo("allow-trust-anchor-query")) { + if (qname == trustanchorserver && qclass == QClass::CHAOS && ::arg().mustDo("allow-trust-anchor-query")) { handled = true; if (qtype == QType::TXT || qtype == QType::ANY) { auto luaLocal = g_luaconfs.getLocal(); - for (auto const &dsAnchor : luaLocal->dsAnchors) { + for (auto const& dsAnchor : luaLocal->dsAnchors) { ostringstream ans; - ans<<"\""; - ans<negAnchors) { + for (auto const& negAnchor : luaLocal->negAnchors) { ostringstream ans; - ans<<"\""; - ans<& records) const { @@ -898,22 +910,22 @@ int SyncRes::AuthDomain::getRecords(const DNSName& qname, const QType qtype, std records.clear(); // partial lookup - std::pair range = d_records.equal_range(std::tie(qname)); + std::pair range = d_records.equal_range(std::tie(qname)); SyncRes::AuthDomain::records_t::const_iterator ziter; bool somedata = false; - for(ziter = range.first; ziter != range.second; ++ziter) { + for (ziter = range.first; ziter != range.second; ++ziter) { somedata = true; - if(qtype == QType::ANY || ziter->d_type == qtype || ziter->d_type == QType::CNAME) { + if (qtype == QType::ANY || ziter->d_type == qtype || ziter->d_type == QType::CNAME) { // let rest of nameserver do the legwork on this one records.push_back(*ziter); } else if (ziter->d_type == QType::NS && ziter->d_name.countLabels() > getName().countLabels()) { // we hit a delegation point! DNSRecord dr = *ziter; - dr.d_place=DNSResourceRecord::AUTHORITY; + dr.d_place = DNSResourceRecord::AUTHORITY; records.push_back(dr); } } @@ -934,16 +946,16 @@ int SyncRes::AuthDomain::getRecords(const DNSName& qname, const QType qtype, std // cerr<&ret, int& res) +bool SyncRes::doOOBResolve(const AuthDomain& domain, const DNSName& qname, const QType qtype, vector& ret, int& res) { d_authzonequeries++; t_Counters.at(rec::Counter::authzonequeries)++; @@ -990,32 +1002,34 @@ bool SyncRes::doOOBResolve(const AuthDomain& domain, const DNSName &qname, const return true; } -bool SyncRes::doOOBResolve(const DNSName &qname, const QType qtype, vector&ret, unsigned int depth, int& res) +bool SyncRes::doOOBResolve(const DNSName& qname, const QType qtype, vector& ret, unsigned int depth, int& res) { string prefix; - if(doLog()) { - prefix=d_prefix; + if (doLog()) { + prefix = d_prefix; prefix.append(depth, ' '); } DNSName authdomain(qname); - domainmap_t::const_iterator iter=getBestAuthZone(&authdomain); - if(iter==t_sstorage.domainmap->end() || !iter->second.isAuth()) { - LOG(prefix<end() || !iter->second.isAuth()) { + LOG(prefix << qname << ": auth storage has no zone for this query!" << endl); return false; } - LOG(prefix<second, qname, qtype, ret, res); } -bool SyncRes::isRecursiveForwardOrAuth(const DNSName &qname) const { +bool SyncRes::isRecursiveForwardOrAuth(const DNSName& qname) const +{ DNSName authname(qname); domainmap_t::const_iterator iter = getBestAuthZone(&authname); return iter != t_sstorage.domainmap->end() && (iter->second.isAuth() || iter->second.shouldRecurse()); } -bool SyncRes::isForwardOrAuth(const DNSName &qname) const { +bool SyncRes::isForwardOrAuth(const DNSName& qname) const +{ DNSName authname(qname); domainmap_t::const_iterator iter = getBestAuthZone(&authname); return iter != t_sstorage.domainmap->end(); @@ -1063,8 +1077,7 @@ static const char* timestamp(time_t t, char* buf, size_t sz) struct ednsstatus_t : public multi_index_container, member>, - ordered_non_unique, member> - >> + ordered_non_unique, member>>> { // Get a copy ednsstatus_t getMap() const @@ -1072,16 +1085,16 @@ struct ednsstatus_t : public multi_index_container::type &ind, iterator it, SyncRes::EDNSStatus::EDNSMode mode, time_t ts) + void setMode(index::type& ind, iterator it, SyncRes::EDNSStatus::EDNSMode mode, time_t ts) { if (it->mode != mode || it->ttd == 0) { - ind.modify(it, [=](SyncRes::EDNSStatus &s) { s.mode = mode; s.ttd = ts + Expire; }); + ind.modify(it, [=](SyncRes::EDNSStatus& s) { s.mode = mode; s.ttd = ts + Expire; }); } } void prune(time_t now) { - auto &ind = get(); + auto& ind = get(); ind.erase(ind.begin(), ind.upper_bound(now)); } @@ -1121,14 +1134,14 @@ uint64_t SyncRes::doEDNSDump(int fd) if (newfd == -1) { return 0; } - auto fp = std::unique_ptr(fdopen(newfd, "w"), fclose); + auto fp = std::unique_ptr(fdopen(newfd, "w"), fclose); if (!fp) { close(newfd); return 0; } uint64_t count = 0; - fprintf(fp.get(),"; edns dump follows\n; ip\tstatus\tttd\n"); + fprintf(fp.get(), "; edns dump follows\n; ip\tstatus\tttd\n"); const auto copy = s_ednsstatus.lock()->getMap(); for (const auto& eds : copy) { count++; @@ -1141,7 +1154,7 @@ uint64_t SyncRes::doEDNSDump(int fd) void SyncRes::pruneNSSpeeds(time_t limit) { auto lock = s_nsSpeeds.lock(); - auto &ind = lock->get(); + auto& ind = lock->get(); ind.erase(ind.begin(), ind.upper_bound(timeval{limit, 0})); } @@ -1173,7 +1186,7 @@ uint64_t SyncRes::doDumpNSSpeeds(int fd) if (newfd == -1) { return 0; } - auto fp = std::unique_ptr(fdopen(newfd, "w"), fclose); + auto fp = std::unique_ptr(fdopen(newfd, "w"), fclose); if (!fp) { close(newfd); return 0; @@ -1229,7 +1242,7 @@ void SyncRes::doThrottle(time_t now, const ComboAddress& server, time_t duration s_throttle.lock()->throttle(now, std::make_tuple(server, g_rootdnsname, 0), duration, tries); } -void SyncRes::doThrottle(time_t now, const ComboAddress& server, const DNSName&name, QType qtype, time_t duration, unsigned int tries) +void SyncRes::doThrottle(time_t now, const ComboAddress& server, const DNSName& name, QType qtype, time_t duration, unsigned int tries) { s_throttle.lock()->throttle(now, std::make_tuple(server, name, qtype), duration, tries); } @@ -1240,19 +1253,18 @@ uint64_t SyncRes::doDumpThrottleMap(int fd) if (newfd == -1) { return 0; } - auto fp = std::unique_ptr(fdopen(newfd, "w"), fclose); + auto fp = std::unique_ptr(fdopen(newfd, "w"), fclose); if (!fp) { close(newfd); return 0; } fprintf(fp.get(), "; throttle map dump follows\n"); fprintf(fp.get(), "; remote IP\tqname\tqtype\tcount\tttd\n"); - uint64_t count=0; + uint64_t count = 0; // Get a copy to avoid holding the lock while doing I/O const auto throttleMap = s_throttle.lock()->getThrottleMap(); - for(const auto& i : throttleMap) - { + for (const auto& i : throttleMap) { count++; char tmp[26]; // remote IP, dns name, qtype, count, ttd @@ -1288,18 +1300,17 @@ uint64_t SyncRes::doDumpFailedServers(int fd) if (newfd == -1) { return 0; } - auto fp = std::unique_ptr(fdopen(newfd, "w"), fclose); + auto fp = std::unique_ptr(fdopen(newfd, "w"), fclose); if (!fp) { close(newfd); return 0; } fprintf(fp.get(), "; failed servers dump follows\n"); fprintf(fp.get(), "; remote IP\tcount\ttimestamp\n"); - uint64_t count=0; + uint64_t count = 0; // We get a copy, so the I/O does not need to happen while holding the lock - for (const auto& i : s_fails.lock()->getMapCopy()) - { + for (const auto& i : s_fails.lock()->getMapCopy()) { count++; char tmp[26]; fprintf(fp.get(), "%s\t%" PRIu64 "\t%s\n", i.key.toString().c_str(), i.value, timestamp(i.last, tmp, sizeof(tmp))); @@ -1329,18 +1340,17 @@ uint64_t SyncRes::doDumpNonResolvingNS(int fd) if (newfd == -1) { return 0; } - auto fp = std::unique_ptr(fdopen(newfd, "w"), fclose); + auto fp = std::unique_ptr(fdopen(newfd, "w"), fclose); if (!fp) { close(newfd); return 0; } fprintf(fp.get(), "; non-resolving nameserver dump follows\n"); fprintf(fp.get(), "; name\tcount\ttimestamp\n"); - uint64_t count=0; + uint64_t count = 0; // We get a copy, so the I/O does not need to happen while holding the lock - for (const auto& i : s_nonresolving.lock()->getMapCopy()) - { + for (const auto& i : s_nonresolving.lock()->getMapCopy()) { count++; char tmp[26]; fprintf(fp.get(), "%s\t%" PRIu64 "\t%s\n", i.key.toString().c_str(), i.value, timestamp(i.last, tmp, sizeof(tmp))); @@ -1370,7 +1380,7 @@ uint64_t SyncRes::doDumpSavedParentNSSets(int fd) if (newfd == -1) { return 0; } - auto fp = std::unique_ptr(fdopen(newfd, "w"), fclose); + auto fp = std::unique_ptr(fdopen(newfd, "w"), fclose); if (!fp) { close(newfd); return 0; @@ -1378,11 +1388,10 @@ uint64_t SyncRes::doDumpSavedParentNSSets(int fd) fprintf(fp.get(), "; dump of saved parent nameserver sets succesfully used follows\n"); fprintf(fp.get(), "; total entries: %zu\n", s_savedParentNSSet.lock()->size()); fprintf(fp.get(), "; domain\tsuccess\tttd\n"); - uint64_t count=0; + uint64_t count = 0; // We get a copy, so the I/O does not need to happen while holding the lock - for (const auto& i : s_savedParentNSSet.lock()->getMapCopy()) - { + for (const auto& i : s_savedParentNSSet.lock()->getMapCopy()) { if (i.d_count == 0) { continue; } @@ -1398,7 +1407,7 @@ void SyncRes::pruneDoTProbeMap(time_t cutoff) auto lock = s_dotMap.lock(); auto& ind = lock->d_map.get(); - for (auto i = ind.begin(); i != ind.end(); ) { + for (auto i = ind.begin(); i != ind.end();) { if (i->d_ttd >= cutoff) { // We're done as we loop ordered by d_ttd break; @@ -1416,14 +1425,14 @@ uint64_t SyncRes::doDumpDoTProbeMap(int fd) if (newfd == -1) { return 0; } - auto fp = std::unique_ptr(fdopen(newfd, "w"), fclose); + auto fp = std::unique_ptr(fdopen(newfd, "w"), fclose); if (!fp) { close(newfd); return 0; } fprintf(fp.get(), "; DoT probing map follows\n"); fprintf(fp.get(), "; ip\tdomain\tcount\tstatus\tttd\n"); - uint64_t count=0; + uint64_t count = 0; // We get a copy, so the I/O does not need to happen while holding the lock DoTMap copy; @@ -1472,7 +1481,7 @@ LWResult::Result SyncRes::asyncresolveWrapper(const ComboAddress& ip, bool ednsM Everybody starts out assumed to be EDNSOK. If EDNSOK, send out EDNS0 - If you FORMERR us, go to NOEDNS, + If you FORMERR us, go to NOEDNS, If no EDNS in response, go to EDNSIGNORANT If EDNSIGNORANT, keep on including EDNS0, see what happens Same behaviour as EDNSOK @@ -1487,7 +1496,8 @@ LWResult::Result SyncRes::asyncresolveWrapper(const ComboAddress& ip, bool ednsM if (ednsstatus != lock->end()) { if (ednsstatus->ttd && ednsstatus->ttd < d_now.tv_sec) { lock->erase(ednsstatus); - } else { + } + else { mode = ednsstatus->mode; } } @@ -1541,17 +1551,17 @@ LWResult::Result SyncRes::asyncresolveWrapper(const ComboAddress& ip, bool ednsM auto lock = s_ednsstatus.lock(); // all three branches below need a lock // Determine new mode - if (res->d_validpacket && !res->d_haveEDNS && res->d_rcode == RCode::FormErr) { + if (res->d_validpacket && !res->d_haveEDNS && res->d_rcode == RCode::FormErr) { mode = EDNSStatus::NOEDNS; auto ednsstatus = lock->insert(ip).first; - auto &ind = lock->get(); + auto& ind = lock->get(); lock->setMode(ind, ednsstatus, mode, d_now.tv_sec); // This is the only path that re-iterates the loop continue; } else if (!res->d_haveEDNS) { auto ednsstatus = lock->insert(ip).first; - auto &ind = lock->get(); + auto& ind = lock->get(); lock->setMode(ind, ednsstatus, EDNSStatus::EDNSIGNORANT, d_now.tv_sec); } else { @@ -1565,7 +1575,7 @@ LWResult::Result SyncRes::asyncresolveWrapper(const ComboAddress& ip, bool ednsM return ret; } -#define QLOG(x) LOG(prefix << " child=" << child << ": " << x << endl) +#define QLOG(x) LOG(prefix << " child=" << child << ": " << x << endl) /* The parameters from rfc9156. */ /* maximum number of QNAME minimisation iterations */ @@ -1575,20 +1585,23 @@ static const unsigned int s_minimise_one_lab = 4; static unsigned int qmStepLen(unsigned int labels, unsigned int qnamelen, unsigned int i) { - unsigned int step; + unsigned int step; - if (i < s_minimise_one_lab) { - step = 1; - } else if (i < s_max_minimise_count) { - step = std::max(1U, (qnamelen - labels) / (10 - i)); - } else { - step = qnamelen - labels; - } - unsigned int targetlen = std::min(labels + step, qnamelen); - return targetlen; + if (i < s_minimise_one_lab) { + step = 1; + } + else if (i < s_max_minimise_count) { + step = std::max(1U, (qnamelen - labels) / (10 - i)); + } + else { + step = qnamelen - labels; + } + unsigned int targetlen = std::min(labels + step, qnamelen); + return targetlen; } -int SyncRes::doResolve(const DNSName &qname, const QType qtype, vector&ret, unsigned int depth, set& beenthere, vState& state) { +int SyncRes::doResolve(const DNSName& qname, const QType qtype, vector& ret, unsigned int depth, set& beenthere, vState& state) +{ string prefix = d_prefix; prefix.append(depth, ' '); @@ -1662,7 +1675,7 @@ int SyncRes::doResolve(const DNSName &qname, const QType qtype, vector bestns; @@ -1688,12 +1701,14 @@ int SyncRes::doResolve(const DNSName &qname, const QType qtype, vector&ret, unsigned int depth, set& beenthere, vState& state, bool *fromCache, StopAtDelegation *stopAtDelegation, bool considerforwards) +int SyncRes::doResolveNoQNameMinimization(const DNSName& qname, const QType qtype, vector& ret, unsigned int depth, set& beenthere, vState& state, bool* fromCache, StopAtDelegation* stopAtDelegation, bool considerforwards) { string prefix; - if(doLog()) { - prefix=d_prefix; + if (doLog()) { + prefix = d_prefix; prefix.append(depth, ' '); } - LOG(prefix< s_maxdepth) { string msg = "More than " + std::to_string(s_maxdepth) + " (max-recursion-depth) levels of recursion needed while resolving " + qname.toLogString(); LOG(prefix << qname << ": " << msg << endl); throw ImmediateServFailException(msg); } - int res=0; - + int res = 0; const int iterations = !d_refresh && MemRecursorCache::s_maxServedStaleExtensions > 0 ? 2 : 1; for (int loop = 0; loop < iterations; loop++) { @@ -1818,14 +1832,14 @@ int SyncRes::doResolveNoQNameMinimization(const DNSName &qname, const QType qtyp try { // This is a difficult way of expressing "this is a normal query", i.e. not getRootNS. - if(!(d_updatingRootNS && qtype.getCode()==QType::NS && qname.isRoot())) { - if(d_cacheonly) { // very limited OOB support + if (!(d_updatingRootNS && qtype.getCode() == QType::NS && qname.isRoot())) { + if (d_cacheonly) { // very limited OOB support LWResult lwr; - LOG(prefix<end()) { - if(iter->second.isAuth()) { + domainmap_t::const_iterator iter = getBestAuthZone(&authname); + if (iter != t_sstorage.domainmap->end()) { + if (iter->second.isAuth()) { ret.clear(); d_wasOutOfBand = doOOBResolve(qname, qtype, ret, depth, res); if (fromCache) @@ -1835,7 +1849,7 @@ int SyncRes::doResolveNoQNameMinimization(const DNSName &qname, const QType qtyp else if (considerforwards) { const vector& servers = iter->second.d_servers; const ComboAddress remoteIP = servers.front(); - LOG(prefix< nm; bool chained = false; @@ -1850,8 +1864,8 @@ int SyncRes::doResolveNoQNameMinimization(const DNSName &qname, const QType qtyp // filter out the good stuff from lwr.result() if (resolveRet == LWResult::Result::Success) { - for(const auto& rec : lwr.d_records) { - if(rec.d_place == DNSResourceRecord::ANSWER) + for (const auto& rec : lwr.d_records) { + if (rec.d_place == DNSResourceRecord::ANSWER) ret.push_back(rec); } return 0; @@ -1868,13 +1882,14 @@ int SyncRes::doResolveNoQNameMinimization(const DNSName &qname, const QType qtyp bool wasAuthZone = false; bool wasForwardRecurse = false; domainmap_t::const_iterator iter = getBestAuthZone(&authname); - if(iter != t_sstorage.domainmap->end()) { + if (iter != t_sstorage.domainmap->end()) { const auto& domain = iter->second; wasForwardedOrAuthZone = true; if (domain.isAuth()) { wasAuthZone = true; - } else if (domain.shouldRecurse()) { + } + else if (domain.shouldRecurse()) { wasForwardRecurse = true; } } @@ -1966,18 +1981,19 @@ int SyncRes::doResolveNoQNameMinimization(const DNSName &qname, const QType qtyp return 0; } - LOG(prefix<> fallBack; { auto lock = s_savedParentNSSet.lock(); - auto domainData= lock->find(subdomain); + auto domainData = lock->find(subdomain); if (domainData != lock->end() && domainData->d_nsAddresses.size() > 0) { nsset.clear(); // Build the nsset arg and fallBack data for the fallback doResolveAt() attempt @@ -1999,8 +2015,8 @@ int SyncRes::doResolveNoQNameMinimization(const DNSName &qname, const QType qtyp } } if (fallBack.size() > 0) { - LOG(prefix<inc(subdomain); @@ -2021,7 +2037,7 @@ int SyncRes::doResolveNoQNameMinimization(const DNSName &qname, const QType qtyp return 0; } - LOG(prefix<= 0) { break; } @@ -2032,7 +2048,7 @@ int SyncRes::doResolveNoQNameMinimization(const DNSName &qname, const QType qtyp } } } - return res<0 ? RCode::ServFail : res; + return res < 0 ? RCode::ServFail : res; } #if 0 @@ -2045,7 +2061,8 @@ static bool ipv6First(const ComboAddress& a, const ComboAddress& b) struct speedOrderCA { - speedOrderCA(std::map& speeds): d_speeds(speeds) {} + speedOrderCA(std::map& speeds) : + d_speeds(speeds) {} bool operator()(const ComboAddress& a, const ComboAddress& b) const { return d_speeds[a] < d_speeds[b]; @@ -2054,8 +2071,8 @@ struct speedOrderCA }; /** This function explicitly goes out for A or AAAA addresses -*/ -vector SyncRes::getAddrs(const DNSName &qname, unsigned int depth, set& beenthere, bool cacheOnly, unsigned int& addressQueriesForNS) + */ +vector SyncRes::getAddrs(const DNSName& qname, unsigned int depth, set& beenthere, bool cacheOnly, unsigned int& addressQueriesForNS) { typedef vector res_t; typedef vector ret_t; @@ -2079,14 +2096,14 @@ vector SyncRes::getAddrs(const DNSName &qname, unsigned int depth, // First look for both A and AAAA in the cache res_t cset; if (s_doIPv4 && g_recCache->get(d_now.tv_sec, qname, QType::A, flags, &cset, d_cacheRemote, d_routingTag) > 0) { - for (const auto &i : cset) { + for (const auto& i : cset) { if (auto rec = getRR(i)) { ret.push_back(rec->getCA(53)); } } } if (s_doIPv6 && g_recCache->get(d_now.tv_sec, qname, QType::AAAA, flags, &cset, d_cacheRemote, d_routingTag) > 0) { - for (const auto &i : cset) { + for (const auto& i : cset) { if (auto rec = getRR(i)) { seenV6 = true; ret.push_back(rec->getCA(53)); @@ -2098,8 +2115,8 @@ vector SyncRes::getAddrs(const DNSName &qname, unsigned int depth, vState newState = vState::Indeterminate; cset.clear(); // Go out to get A's - if (s_doIPv4 && doResolve(qname, QType::A, cset, depth+1, beenthere, newState) == 0) { // this consults cache, OR goes out - for (auto const &i : cset) { + if (s_doIPv4 && doResolve(qname, QType::A, cset, depth + 1, beenthere, newState) == 0) { // this consults cache, OR goes out + for (auto const& i : cset) { if (i.d_type == QType::A) { if (auto rec = getRR(i)) { ret.push_back(rec->getCA(53)); @@ -2112,8 +2129,8 @@ vector SyncRes::getAddrs(const DNSName &qname, unsigned int depth, // We only go out immediately to find IPv6 records if we did not find any IPv4 ones. newState = vState::Indeterminate; cset.clear(); - if (doResolve(qname, QType::AAAA, cset, depth+1, beenthere, newState) == 0) { // this consults cache, OR goes out - for (const auto &i : cset) { + if (doResolve(qname, QType::AAAA, cset, depth + 1, beenthere, newState) == 0) { // this consults cache, OR goes out + for (const auto& i : cset) { if (i.d_type == QType::AAAA) { if (auto rec = getRR(i)) { seenV6 = true; @@ -2122,11 +2139,12 @@ vector SyncRes::getAddrs(const DNSName &qname, unsigned int depth, } } } - } else { + } + else { // We have some IPv4 records, consult the cache, we might have encountered some IPv6 glue cset.clear(); if (g_recCache->get(d_now.tv_sec, qname, QType::AAAA, flags, &cset, d_cacheRemote, d_routingTag) > 0) { - for (const auto &i : cset) { + for (const auto& i : cset) { if (auto rec = getRR(i)) { seenV6 = true; ret.push_back(rec->getCA(53)); @@ -2176,7 +2194,7 @@ vector SyncRes::getAddrs(const DNSName &qname, unsigned int depth, auto lock = s_nsSpeeds.lock(); auto& collection = lock->find_or_enter(qname, d_now); float factor = collection.getFactor(d_now); - for(const auto& val: ret) { + for (const auto& val : ret) { speeds[val] = collection.d_collection[val].get(factor); } collection.purge(speeds); @@ -2188,19 +2206,19 @@ vector SyncRes::getAddrs(const DNSName &qname, unsigned int depth, stable_sort(ret.begin(), ret.end(), so); } - if(doLog()) { - string prefix=d_prefix; + if (doLog()) { + string prefix = d_prefix; prefix.append(depth, ' '); - LOG(prefix<<"Nameserver "< SyncRes::getAddrs(const DNSName &qname, unsigned int depth, return ret; } -void SyncRes::getBestNSFromCache(const DNSName &qname, const QType qtype, vector& bestns, bool* flawedNSSet, unsigned int depth, set& beenthere, const boost::optional& cutOffDomain) +void SyncRes::getBestNSFromCache(const DNSName& qname, const QType qtype, vector& bestns, bool* flawedNSSet, unsigned int depth, set& beenthere, const boost::optional& cutOffDomain) { string prefix; DNSName subdomain(qname); - if(doLog()) { - prefix=d_prefix; + if (doLog()) { + prefix = d_prefix; prefix.append(depth, ' '); } bestns.clear(); @@ -2226,8 +2244,8 @@ void SyncRes::getBestNSFromCache(const DNSName &qname, const QType qtype, vector if (cutOffDomain && (subdomain == *cutOffDomain || !subdomain.isPartOf(*cutOffDomain))) { break; } - brokeloop=false; - LOG(prefix< ns; *flawedNSSet = false; @@ -2240,78 +2258,78 @@ void SyncRes::getBestNSFromCache(const DNSName &qname, const QType qtype, vector } bestns.reserve(ns.size()); - for(auto k=ns.cbegin();k!=ns.cend(); ++k) { - if(k->d_ttl > (unsigned int)d_now.tv_sec ) { + for (auto k = ns.cbegin(); k != ns.cend(); ++k) { + if (k->d_ttl > (unsigned int)d_now.tv_sec) { vector aset; QType nsqt{QType::ADDR}; if (s_doIPv4 && !s_doIPv6) { nsqt = QType::A; - } else if (!s_doIPv4 && s_doIPv6) { + } + else if (!s_doIPv4 && s_doIPv6) { nsqt = QType::AAAA; } - const DNSRecord& dr=*k; - auto nrr = getRR(dr); - if(nrr && (!nrr->getNS().isPartOf(subdomain) || g_recCache->get(d_now.tv_sec, nrr->getNS(), nsqt, - flags, doLog() ? &aset : 0, d_cacheRemote, d_routingTag) > 0)) { + const DNSRecord& dr = *k; + auto nrr = getRR(dr); + if (nrr && (!nrr->getNS().isPartOf(subdomain) || g_recCache->get(d_now.tv_sec, nrr->getNS(), nsqt, flags, doLog() ? &aset : 0, d_cacheRemote, d_routingTag) > 0)) { bestns.push_back(dr); - LOG(prefix< '"<getNS()<<"'"<getNS().isPartOf(subdomain)); - if(!aset.empty()) { - LOG(", in cache, ttl="<<(unsigned int)(((time_t)aset.begin()->d_ttl- d_now.tv_sec ))< '" << nrr->getNS() << "'" << endl); + LOG(prefix << qname << ": within bailiwick: " << nrr->getNS().isPartOf(subdomain)); + if (!aset.empty()) { + LOG(", in cache, ttl=" << (unsigned int)(((time_t)aset.begin()->d_ttl - d_now.tv_sec)) << endl); } else { - LOG(", not in cache / did not look at cache"<getNS()<<") which we miss or is expired"<getNS() << ") which we miss or is expired" << endl); } } } - if(!bestns.empty()) { + if (!bestns.empty()) { GetBestNSAnswer answer; - answer.qname=qname; - answer.qtype=qtype.getCode(); - for(const auto& dr : bestns) { + answer.qname = qname; + answer.qtype = qtype.getCode(); + for (const auto& dr : bestns) { if (auto nsContent = getRR(dr)) { answer.bestns.emplace(dr.d_name, nsContent->getNS()); } } auto insertionPair = beenthere.insert(std::move(answer)); - if(!insertionPair.second) { - brokeloop=true; - LOG(prefix<::const_iterator j=beenthere.begin();j!=beenthere.end();++j) { - bool neo = (j == insertionPair.first); - LOG(prefix<qname<<"|"<qtype)<<" ("<<(unsigned int)j->bestns.size()<<")"<::const_iterator j = beenthere.begin(); j != beenthere.end(); ++j) { + bool neo = (j == insertionPair.first); + LOG(prefix << qname << ": beenthere" << (neo ? "*" : "") << ": " << j->qname << "|" << DNSRecordContent::NumberToType(j->qtype) << " (" << (unsigned int)j->bestns.size() << ")" << endl); } bestns.clear(); } else { - LOG(prefix<withName("housekeeping"); getRootNS(d_now, d_asyncResolve, depth, log); } } - } while(subdomain.chopOff()); + } while (subdomain.chopOff()); } SyncRes::domainmap_t::const_iterator SyncRes::getBestAuthZone(DNSName* qname) const @@ -2322,15 +2340,15 @@ SyncRes::domainmap_t::const_iterator SyncRes::getBestAuthZone(DNSName* qname) co SyncRes::domainmap_t::const_iterator ret; do { - ret=t_sstorage.domainmap->find(*qname); - if(ret!=t_sstorage.domainmap->end()) + ret = t_sstorage.domainmap->find(*qname); + if (ret != t_sstorage.domainmap->end()) break; - }while(qname->chopOff()); + } while (qname->chopOff()); return ret; } /** doesn't actually do the work, leaves that to getBestNSFromCache */ -DNSName SyncRes::getBestNSNamesFromCache(const DNSName &qname, const QType qtype, NsSet& nsset, bool* flawedNSSet, unsigned int depth, set&beenthere) +DNSName SyncRes::getBestNSNamesFromCache(const DNSName& qname, const QType qtype, NsSet& nsset, bool* flawedNSSet, unsigned int depth, set& beenthere) { string prefix; if (doLog()) { @@ -2353,7 +2371,7 @@ DNSName SyncRes::getBestNSNamesFromCache(const DNSName &qname, const QType qtype // Again, picked up in doResolveAt. An empty DNSName, combined with a // non-empty vector of ComboAddresses means 'this is a forwarded domain' // This is actually picked up in retrieveAddressesForNS called from doResolveAt. - nsset.insert({DNSName(), {iter->second.d_servers, true }}); + nsset.insert({DNSName(), {iter->second.d_servers, true}}); return authOrForwDomain; } } @@ -2385,9 +2403,10 @@ DNSName SyncRes::getBestNSNamesFromCache(const DNSName &qname, const QType qtype if (doLog()) { LOG(prefix << qname << ": using forwarder as NS" << endl); } - nsset.insert({DNSName(), {iter->second.d_servers, false }}); + nsset.insert({DNSName(), {iter->second.d_servers, false}}); return authOrForwDomain; - } else { + } + else { if (doLog()) { LOG(prefix << qname << ": using NS from cache" << endl); } @@ -2403,7 +2422,7 @@ DNSName SyncRes::getBestNSNamesFromCache(const DNSName &qname, const QType qtype return nsFromCacheDomain; } -void SyncRes::updateValidationStatusInCache(const DNSName &qname, const QType qt, bool aa, vState newState) const +void SyncRes::updateValidationStatusInCache(const DNSName& qname, const QType qt, bool aa, vState newState) const { if (qt == QType::ANY || qt == QType::ADDR) { // not doing that @@ -2420,7 +2439,7 @@ void SyncRes::updateValidationStatusInCache(const DNSName &qname, const QType qt static bool scanForCNAMELoop(const DNSName& name, const vector& records) { - for (const auto& record: records) { + for (const auto& record : records) { if (record.d_type == QType::CNAME && record.d_place == DNSResourceRecord::ANSWER) { if (name == record.d_name) { return true; @@ -2430,17 +2449,17 @@ static bool scanForCNAMELoop(const DNSName& name, const vector& recor return false; } -bool SyncRes::doCNAMECacheCheck(const DNSName &qname, const QType qtype, vector& ret, unsigned int depth, int &res, vState& state, bool wasAuthZone, bool wasForwardRecurse) +bool SyncRes::doCNAMECacheCheck(const DNSName& qname, const QType qtype, vector& ret, unsigned int depth, int& res, vState& state, bool wasAuthZone, bool wasForwardRecurse) { string prefix; - if(doLog()) { - prefix=d_prefix; + if (doLog()) { + prefix = d_prefix; prefix.append(depth, ' '); } - if((depth>9 && d_outqueries>10 && d_throttledqueries>5) || depth > 15) { - LOG(prefix< (unsigned int) d_now.tv_sec) { + if (record.d_ttl > (unsigned int)d_now.tv_sec) { if (!wasAuthZone && shouldValidate() && (wasAuth || wasForwardRecurse) && state == vState::Indeterminate && d_requireAuthData) { /* This means we couldn't figure out the state when this entry was cached */ vState recordState = getValidationStatus(foundName, !signatures.empty(), qtype == QType::DS, depth); if (recordState == vState::Secure) { - LOG(prefix<getZoneRepresentation()<<"', validation state is "<getZoneRepresentation() << "', validation state is " << state << endl); DNSRecord dr = record; dr.d_ttl -= d_now.tv_sec; @@ -2532,20 +2551,20 @@ bool SyncRes::doCNAMECacheCheck(const DNSName &qname, const QType qtype, vector< ret.reserve(ret.size() + 2 + signatures.size() + authorityRecs.size()); ret.push_back(dr); - for(const auto& signature : signatures) { + for (const auto& signature : signatures) { DNSRecord sigdr; - sigdr.d_type=QType::RRSIG; - sigdr.d_name=foundName; - sigdr.d_ttl=ttl; - sigdr.d_content=signature; - sigdr.d_place=DNSResourceRecord::ANSWER; - sigdr.d_class=QClass::IN; + sigdr.d_type = QType::RRSIG; + sigdr.d_name = foundName; + sigdr.d_ttl = ttl; + sigdr.d_content = signature; + sigdr.d_place = DNSResourceRecord::ANSWER; + sigdr.d_class = QClass::IN; ret.push_back(sigdr); } - for(const auto& rec : authorityRecs) { + for (const auto& rec : authorityRecs) { DNSRecord authDR(*rec); - authDR.d_ttl=ttl; + authDR.d_ttl = ttl; ret.push_back(authDR); } @@ -2558,7 +2577,7 @@ bool SyncRes::doCNAMECacheCheck(const DNSName &qname, const QType qtype, vector< // Synthesize a CNAME auto dnameRR = getRR(record); if (dnameRR == nullptr) { - throw ImmediateServFailException("Unable to get record content for "+foundName.toLogString()+"|DNAME cache entry"); + throw ImmediateServFailException("Unable to get record content for " + foundName.toLogString() + "|DNAME cache entry"); } const auto& dnameSuffix = dnameRR->getTarget(); DNSName targetPrefix = qname.makeRelative(foundName); @@ -2568,19 +2587,17 @@ bool SyncRes::doCNAMECacheCheck(const DNSName &qname, const QType qtype, vector< newTarget = targetPrefix + dnameSuffix; dr.d_content = std::make_shared(CNAMERecordContent(newTarget)); ret.push_back(dr); - } catch (const std::exception &e) { + } + catch (const std::exception& e) { // We should probably catch an std::range_error here and set the rcode to YXDOMAIN (RFC 6672, section 2.2) // But this is consistent with processRecords - throw ImmediateServFailException("Unable to perform DNAME substitution(DNAME owner: '" + foundName.toLogString() + - "', DNAME target: '" + dnameSuffix.toLogString() + "', substituted name: '" + - targetPrefix.toLogString() + "." + dnameSuffix.toLogString() + - "' : " + e.what()); + throw ImmediateServFailException("Unable to perform DNAME substitution(DNAME owner: '" + foundName.toLogString() + "', DNAME target: '" + dnameSuffix.toLogString() + "', substituted name: '" + targetPrefix.toLogString() + "." + dnameSuffix.toLogString() + "' : " + e.what()); } - LOG(prefix<(record); if (cnameContent == nullptr) { - throw ImmediateServFailException("Unable to get record content for "+foundName.toLogString()+"|CNAME cache entry"); + throw ImmediateServFailException("Unable to get record content for " + foundName.toLogString() + "|CNAME cache entry"); } newTarget = cnameContent->getTarget(); } if (qname == newTarget) { string msg = "got a CNAME referral (from cache) to self"; - LOG(prefix< records; @@ -2651,7 +2669,8 @@ struct CacheKey DNSName name; QType type; DNSResourceRecord::Place place; - bool operator<(const CacheKey& rhs) const { + bool operator<(const CacheKey& rhs) const + { return std::tie(type, place, name) < std::tie(rhs.type, rhs.place, rhs.name); } }; @@ -2666,8 +2685,9 @@ static void reapRecordsFromNegCacheEntryForValidation(tcache_t& tcache, const ve if (rrsig) { tcache[{rec.d_name, rrsig->d_type, rec.d_place}].signatures.push_back(rrsig); } - } else { - tcache[{rec.d_name,rec.d_type,rec.d_place}].records.push_back(rec); + } + else { + tcache[{rec.d_name, rec.d_type, rec.d_place}].records.push_back(rec); } } } @@ -2698,7 +2718,8 @@ static void reapSignaturesForValidation(std::map& entries, co * \param ttl The new TTL for these records * \param ret The vector of DNSRecords that should contain the records with the modified TTL */ -static void addTTLModifiedRecords(vector& records, const uint32_t ttl, vector& ret) { +static void addTTLModifiedRecords(vector& records, const uint32_t ttl, vector& ret) +{ for (auto& rec : records) { rec.d_ttl = ttl; ret.push_back(std::move(rec)); @@ -2754,39 +2775,35 @@ void SyncRes::computeNegCacheValidationStatus(const NegCache::NegCacheEntry& ne, } } -bool SyncRes::doCacheCheck(const DNSName &qname, const DNSName& authname, bool wasForwardedOrAuthZone, bool wasAuthZone, bool wasForwardRecurse, QType qtype, vector&ret, unsigned int depth, int &res, vState& state) +bool SyncRes::doCacheCheck(const DNSName& qname, const DNSName& authname, bool wasForwardedOrAuthZone, bool wasAuthZone, bool wasForwardRecurse, QType qtype, vector& ret, unsigned int depth, int& res, vState& state) { - bool giveNegative=false; + bool giveNegative = false; string prefix; - if(doLog()) { - prefix=d_prefix; + if (doLog()) { + prefix = d_prefix; prefix.append(depth, ' '); } // sqname and sqtype are used contain 'higher' names if we have them (e.g. powerdns.com|SOA when we find a negative entry for doesnotexist.powerdns.com|A) DNSName sqname(qname); QType sqt(qtype); - uint32_t sttl=0; + uint32_t sttl = 0; // cout<<"Lookup for '"< "<getRootNXTrust(qname, d_now, ne, d_serveStale, d_refresh) && - ne.d_auth.isRoot() && - !(wasForwardedOrAuthZone && !authname.isRoot())) { // when forwarding, the root may only neg-cache if it was forwarded to. + if (s_rootNXTrust && g_negCache->getRootNXTrust(qname, d_now, ne, d_serveStale, d_refresh) && ne.d_auth.isRoot() && !(wasForwardedOrAuthZone && !authname.isRoot())) { // when forwarding, the root may only neg-cache if it was forwarded to. sttl = ne.d_ttd - d_now.tv_sec; - LOG(prefix<get(qname, qtype, d_now, ne, false, d_serveStale, d_refresh)) { + } + else if (g_negCache->get(qname, qtype, d_now, ne, false, d_serveStale, d_refresh)) { /* If we are looking for a DS, discard NXD if auth == qname and ask for a specific denial instead */ - if (qtype != QType::DS || ne.d_qtype.getCode() || ne.d_auth != qname || - g_negCache->get(qname, qtype, d_now, ne, true, d_serveStale, d_refresh)) - { + if (qtype != QType::DS || ne.d_qtype.getCode() || ne.d_auth != qname || g_negCache->get(qname, qtype, d_now, ne, true, d_serveStale, d_refresh)) { /* Careful! If the client is asking for a DS that does not exist, we need to provide the SOA along with the NSEC(3) proof and we might not have it if we picked up the proof from a delegation, in which case we need to keep on to do the actual DS query. */ @@ -2799,32 +2816,34 @@ bool SyncRes::doCacheCheck(const DNSName &qname, const DNSName& authname, bool w giveNegative = true; cachedState = ne.d_validationState; if (ne.d_qtype.getCode()) { - LOG(prefix<get(negCacheName, QType::ENT, d_now, ne, true, d_serveStale, d_refresh)) { if (ne.d_validationState == vState::Indeterminate && validationEnabled()) { // LOG(prefix << negCacheName << " negatively cached and vState::Indeterminate, trying to validate NXDOMAIN" << endl); // ... // And get the updated ne struct - //t_sstorage.negcache.get(negCacheName, QType(0), d_now, ne, true); + // t_sstorage.negcache.get(negCacheName, QType(0), d_now, ne, true); } if ((s_hardenNXD == HardenNXD::Yes && !vStateIsBogus(ne.d_validationState)) || ne.d_validationState == vState::Secure) { res = RCode::NXDomain; sttl = ne.d_ttd - d_now.tv_sec; giveNegative = true; cachedState = ne.d_validationState; - LOG(prefix< cset; - bool found=false, expired=false; + bool found = false, expired = false; vector> signatures; vector> authorityRecs; - uint32_t ttl=0; + uint32_t ttl = 0; uint32_t capTTL = std::numeric_limits::max(); bool wasCachedAuth; MemRecursorCache::Flags flags = MemRecursorCache::None; @@ -2875,9 +2894,9 @@ bool SyncRes::doCacheCheck(const DNSName &qname, const DNSName& authname, bool w if (d_refresh) { flags |= MemRecursorCache::Refresh; } - if(g_recCache->get(d_now.tv_sec, sqname, sqt, flags, &cset, d_cacheRemote, d_routingTag, d_doDNSSEC ? &signatures : nullptr, d_doDNSSEC ? &authorityRecs : nullptr, &d_wasVariable, &cachedState, &wasCachedAuth, nullptr, &d_fromAuthIP) > 0) { + if (g_recCache->get(d_now.tv_sec, sqname, sqt, flags, &cset, d_cacheRemote, d_routingTag, d_doDNSSEC ? &signatures : nullptr, d_doDNSSEC ? &authorityRecs : nullptr, &d_wasVariable, &cachedState, &wasCachedAuth, nullptr, &d_fromAuthIP) > 0) { - LOG(prefix<d_content->getZoneRepresentation()); @@ -2934,50 +2953,50 @@ bool SyncRes::doCacheCheck(const DNSName &qname, const DNSName& authname, bool w continue; } - if(j->d_ttl>(unsigned int) d_now.tv_sec) { - DNSRecord dr=*j; + if (j->d_ttl > (unsigned int)d_now.tv_sec) { + DNSRecord dr = *j; dr.d_ttl -= d_now.tv_sec; dr.d_ttl = std::min(dr.d_ttl, capTTL); ttl = dr.d_ttl; ret.push_back(dr); - LOG("[ttl="< b.countLabels()); } struct speedOrder { - bool operator()(const std::pair &a, const std::pair &b) const + bool operator()(const std::pair& a, const std::pair& b) const { return a.second < b.second; } }; -inline std::vector> SyncRes::shuffleInSpeedOrder(NsSet &tnameservers, const string &prefix) +inline std::vector> SyncRes::shuffleInSpeedOrder(NsSet& tnameservers, const string& prefix) { std::vector> rnameservers; rnameservers.reserve(tnameservers.size()); - for(const auto& tns: tnameservers) { + for (const auto& tns : tnameservers) { float speed = s_nsSpeeds.lock()->fastest(tns.first, d_now); rnameservers.emplace_back(tns.first, speed); - if(tns.first.empty()) // this was an authoritative OOB zone, don't pollute the nsSpeeds with that + if (tns.first.empty()) // this was an authoritative OOB zone, don't pollute the nsSpeeds with that return rnameservers; } - shuffle(rnameservers.begin(),rnameservers.end(), pdns::dns_random_engine()); + shuffle(rnameservers.begin(), rnameservers.end(), pdns::dns_random_engine()); speedOrder so; - stable_sort(rnameservers.begin(),rnameservers.end(), so); + stable_sort(rnameservers.begin(), rnameservers.end(), so); - if(doLog()) { - LOG(prefix<<"Nameservers: "); - for(auto i=rnameservers.begin();i!=rnameservers.end();++i) { - if(i!=rnameservers.begin()) { + if (doLog()) { + LOG(prefix << "Nameservers: "); + for (auto i = rnameservers.begin(); i != rnameservers.end(); ++i) { + if (i != rnameservers.begin()) { LOG(", "); - if(!((i-rnameservers.begin())%3)) { - LOG(endl<first.toLogString()<<"(" << fmtfloat("%0.2f", i->second/1000.0) <<"ms)"); + LOG(i->first.toLogString() << "(" << fmtfloat("%0.2f", i->second / 1000.0) << "ms)"); } LOG(endl); } return rnameservers; } -inline vector SyncRes::shuffleForwardSpeed(const vector &rnameservers, const string &prefix, const bool wasRd) +inline vector SyncRes::shuffleForwardSpeed(const vector& rnameservers, const string& prefix, const bool wasRd) { vector nameservers = rnameservers; map speeds; - for(const auto& val: nameservers) { + for (const auto& val : nameservers) { DNSName nsName = DNSName(val.toStringWithPort()); float speed = s_nsSpeeds.lock()->fastest(nsName, d_now); speeds[val] = speed; } - shuffle(nameservers.begin(),nameservers.end(), pdns::dns_random_engine()); + shuffle(nameservers.begin(), nameservers.end(), pdns::dns_random_engine()); speedOrderCA so(speeds); - stable_sort(nameservers.begin(),nameservers.end(), so); + stable_sort(nameservers.begin(), nameservers.end(), so); - if(doLog()) { - LOG(prefix<<"Nameservers: "); - for(vector::const_iterator i=nameservers.cbegin();i!=nameservers.cend();++i) { - if(i!=nameservers.cbegin()) { + if (doLog()) { + LOG(prefix << "Nameservers: "); + for (vector::const_iterator i = nameservers.cbegin(); i != nameservers.cend(); ++i) { + if (i != nameservers.cbegin()) { LOG(", "); - if(!((i-nameservers.cbegin())%3)) { - LOG(endl<toStringWithPort() <<"(" << fmtfloat("%0.2f", speeds[*i]/1000.0) <<"ms)"); + LOG((wasRd ? string("+") : string("-")) << i->toStringWithPort() << "(" << fmtfloat("%0.2f", speeds[*i] / 1000.0) << "ms)"); } LOG(endl); } @@ -3081,7 +3102,8 @@ static const set nsecTypes = {QType::NSEC, QType::NSEC3}; * \param records The records to parse for the authority SOA and NSEC(3) records * \param ne The NegCacheEntry to be filled out (will not be cleared, only appended to */ -static void harvestNXRecords(const vector& records, NegCache::NegCacheEntry& ne, const time_t now, uint32_t* lowestTTL) { +static void harvestNXRecords(const vector& records, NegCache::NegCacheEntry& ne, const time_t now, uint32_t* lowestTTL) +{ for (const auto& rec : records) { if (rec.d_place != DNSResourceRecord::AUTHORITY) { // RFC 4035 section 3.1.3. indicates that NSEC records MUST be placed in @@ -3131,15 +3153,15 @@ static void harvestNXRecords(const vector& records, NegCache::NegCach static cspmap_t harvestCSPFromNE(const NegCache::NegCacheEntry& ne) { cspmap_t cspmap; - for(const auto& rec : ne.DNSSECRecords.signatures) { - if(rec.d_type == QType::RRSIG) { + for (const auto& rec : ne.DNSSECRecords.signatures) { + if (rec.d_type == QType::RRSIG) { auto rrc = getRR(rec); if (rrc) { - cspmap[{rec.d_name,rrc->d_type}].signatures.push_back(rrc); + cspmap[{rec.d_name, rrc->d_type}].signatures.push_back(rrc); } } } - for(const auto& rec : ne.DNSSECRecords.records) { + for (const auto& rec : ne.DNSSECRecords.records) { cspmap[{rec.d_name, rec.d_type}].records.insert(rec.d_content); } return cspmap; @@ -3147,7 +3169,7 @@ static cspmap_t harvestCSPFromNE(const NegCache::NegCacheEntry& ne) // TODO remove after processRecords is fixed! // Adds the RRSIG for the SOA and the NSEC(3) + RRSIGs to ret -static void addNXNSECS(vector&ret, const vector& records) +static void addNXNSECS(vector& ret, const vector& records) { NegCache::NegCacheEntry ne; harvestNXRecords(records, ne, 0, nullptr); @@ -3181,17 +3203,13 @@ static bool rpzHitShouldReplaceContent(const DNSName& qname, const QType qtype, static void removeConflictingRecord(std::vector& records, const DNSName& name, const QType dtype) { - for (auto it = records.begin(); it != records.end(); ) { + for (auto it = records.begin(); it != records.end();) { bool remove = false; - if (it->d_class == QClass::IN && - (it->d_type == QType::CNAME || dtype == QType::CNAME || it->d_type == dtype) && - it->d_name == name) { + if (it->d_class == QClass::IN && (it->d_type == QType::CNAME || dtype == QType::CNAME || it->d_type == dtype) && it->d_name == name) { remove = true; } - else if (it->d_class == QClass::IN && - it->d_type == QType::RRSIG && - it->d_name == name) { + else if (it->d_class == QClass::IN && it->d_type == QType::RRSIG && it->d_name == name) { if (auto rrc = getRR(*it)) { if (rrc->d_type == QType::CNAME || rrc->d_type == dtype) { /* also remove any RRSIG that could conflict */ @@ -3230,7 +3248,7 @@ void SyncRes::handlePolicyHit(const std::string& prefix, const DNSName& qname, c switch (d_appliedPolicy.d_kind) { case DNSFilterEngine::PolicyKind::NoAction: - return; + return; case DNSFilterEngine::PolicyKind::Drop: ++t_Counters.at(rec::Counter::policyDrops); @@ -3256,31 +3274,30 @@ void SyncRes::handlePolicyHit(const std::string& prefix, const DNSName& qname, c } return; - case DNSFilterEngine::PolicyKind::Custom: - { - if (rpzHitShouldReplaceContent(qname, qtype, ret)) { - ret.clear(); - } + case DNSFilterEngine::PolicyKind::Custom: { + if (rpzHitShouldReplaceContent(qname, qtype, ret)) { + ret.clear(); + } - rcode = RCode::NoError; - done = true; - auto spoofed = d_appliedPolicy.getCustomRecords(qname, qtype.getCode()); - for (auto& dr : spoofed) { - removeConflictingRecord(ret, dr.d_name, dr.d_type); - } + rcode = RCode::NoError; + done = true; + auto spoofed = d_appliedPolicy.getCustomRecords(qname, qtype.getCode()); + for (auto& dr : spoofed) { + removeConflictingRecord(ret, dr.d_name, dr.d_type); + } - for (auto& dr : spoofed) { - ret.push_back(dr); + for (auto& dr : spoofed) { + ret.push_back(dr); - if (dr.d_name == qname && dr.d_type == QType::CNAME && qtype != QType::CNAME) { - if (auto content = getRR(dr)) { - vState newTargetState = vState::Indeterminate; - handleNewTarget(prefix, qname, content->getTarget(), qtype.getCode(), ret, rcode, depth, {}, newTargetState); - } + if (dr.d_name == qname && dr.d_type == QType::CNAME && qtype != QType::CNAME) { + if (auto content = getRR(dr)) { + vState newTargetState = vState::Indeterminate; + handleNewTarget(prefix, qname, content->getTarget(), qtype.getCode(), ret, rcode, depth, {}, newTargetState); } } } } + } } bool SyncRes::nameserversBlockedByRPZ(const DNSFilterEngine& dfe, const NsSet& nameservers) @@ -3292,23 +3309,23 @@ bool SyncRes::nameserversBlockedByRPZ(const DNSFilterEngine& dfe, const NsSet& n process any further RPZ rules. Except that we need to process rules of higher priority.. */ if (d_wantsRPZ && !d_appliedPolicy.wasHit()) { - for (auto const &ns : nameservers) { + for (auto const& ns : nameservers) { bool match = dfe.getProcessingPolicy(ns.first, d_discardedPolicies, d_appliedPolicy); if (match) { mergePolicyTags(d_policyTags, d_appliedPolicy.getTags()); if (d_appliedPolicy.d_kind != DNSFilterEngine::PolicyKind::NoAction) { // client query needs an RPZ response - LOG(", however nameserver "< SyncRes::retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, std::vector>::const_iterator& tns, const unsigned int depth, set& beenthere, const vector>& rnameservers, NsSet& nameservers, bool& sendRDQuery, bool& pierceDontQuery, bool& flawedNSSet, bool cacheOnly, unsigned int &nretrieveAddressesForNS) +vector SyncRes::retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, std::vector>::const_iterator& tns, const unsigned int depth, set& beenthere, const vector>& rnameservers, NsSet& nameservers, bool& sendRDQuery, bool& pierceDontQuery, bool& flawedNSSet, bool cacheOnly, unsigned int& nretrieveAddressesForNS) { vector result; @@ -3348,12 +3365,12 @@ vector SyncRes::retrieveAddressesForNS(const std::string& prefix, if (s_nonresolvingnsmaxfails > 0) { nonresolvingfails = s_nonresolving.lock()->value(tns->first); if (nonresolvingfails >= s_nonresolvingnsmaxfails) { - LOG(prefix<first<< " in non-resolving map, skipping"<first << " in non-resolving map, skipping" << endl); return result; } } - LOG(prefix<first<< "' ("<<1+tns-rnameservers.begin()<<"/"<<(unsigned int)rnameservers.size()<<")"<first << "' (" << 1 + tns - rnameservers.begin() << "/" << (unsigned int)rnameservers.size() << ")" << endl); const unsigned int oldOutQueries = d_outqueries; try { result = getAddrs(tns->first, depth, beenthere, cacheOnly, nretrieveAddressesForNS); @@ -3380,19 +3397,19 @@ vector SyncRes::retrieveAddressesForNS(const std::string& prefix, s_nonresolving.lock()->clear(tns->first); } } - pierceDontQuery=false; + pierceDontQuery = false; } else { - LOG(prefix<first].first.size() > 1) { + if (nameservers[tns->first].first.size() > 1) { LOG("s"); } LOG(endl); sendRDQuery = nameservers[tns->first].second; - result = shuffleForwardSpeed(nameservers[tns->first].first, doLog() ? (prefix+qname.toString()+": ") : string(), sendRDQuery); - pierceDontQuery=true; + result = shuffleForwardSpeed(nameservers[tns->first].first, doLog() ? (prefix + qname.toString() + ": ") : string(), sendRDQuery); + pierceDontQuery = true; } return result; } @@ -3407,35 +3424,37 @@ void SyncRes::checkMaxQperQ(const DNSName& qname) const bool SyncRes::throttledOrBlocked(const std::string& prefix, const ComboAddress& remoteIP, const DNSName& qname, const QType qtype, bool pierceDontQuery) { if (isThrottled(d_now.tv_sec, remoteIP)) { - LOG(prefix<match(&remoteIP)) { + else if (!pierceDontQuery && s_dontQuery && s_dontQuery->match(&remoteIP)) { // We could have retrieved an NS from the cache in a forwarding domain // Even in the case of !pierceDontQuery we still want to allow that NS DNSName forwardCandidate(qname); auto it = getBestAuthZone(&forwardCandidate); if (it == t_sstorage.domainmap->end()) { - LOG(prefix<second.d_servers; if (std::find(ips.cbegin(), ips.cend(), remoteIP) == ips.cend()) { - LOG(prefix<& records, const std::vector >& signatures, uint32_t signaturesTTL, const std::vector>& authorityRecs) const +uint32_t SyncRes::computeLowestTTD(const std::vector& records, const std::vector>& signatures, uint32_t signaturesTTL, const std::vector>& authorityRecs) const { uint32_t lowestTTD = std::numeric_limits::max(); for (const auto& record : records) { @@ -3461,7 +3480,7 @@ uint32_t SyncRes::computeLowestTTD(const std::vector& records, const /* records TTL are now TTD, let's add 'now' to the signatures lowest TTL */ lowestTTD = min(lowestTTD, static_cast(signaturesTTL + d_now.tv_sec)); - for(const auto& sig : signatures) { + for (const auto& sig : signatures) { if (isRRSIGNotExpired(d_now.tv_sec, sig)) { // we don't decrement d_sigexpire by 'now' because we actually want a TTD, not a TTL */ lowestTTD = min(lowestTTD, static_cast(sig->d_sigexpire)); @@ -3489,9 +3508,9 @@ uint32_t SyncRes::computeLowestTTD(const std::vector& records, const void SyncRes::updateValidationState(vState& state, const vState stateUpdate) { - LOG(d_prefix<<"validation state was "<dsAnchors.empty()) { - LOG(d_prefix<<": No trust anchors configured, everything is Insecure"<negAnchors, zone, reason)) { - LOG(d_prefix<<": got NTA for '"<dsAnchors, zone, ds)) { - LOG(d_prefix<<": got TA for '"<dsAnchors.size()<dsAnchors.size() << endl); } if (zone.isRoot()) { @@ -3561,8 +3580,7 @@ void SyncRes::initZoneCutsFromTA(const DNSName& from) d_cutStates[zone] = result; } - } - while (zone.chopOff()); + } while (zone.chopOff()); } vState SyncRes::getDSRecords(const DNSName& zone, dsmap_t& ds, bool taOnly, unsigned int depth, bool bogusOnNXD, bool* foundCut) @@ -3631,7 +3649,7 @@ vState SyncRes::getDSRecords(const DNSName& zone, dsmap_t& ds, bool taOnly, unsi * digests if DS RRs with SHA-256 digests are present in the DS RRset." * We interpret that as: do not use SHA-1 if SHA-256 or SHA-384 is available */ - for (auto dsrec = ds.begin(); dsrec != ds.end(); ) { + for (auto dsrec = ds.begin(); dsrec != ds.end();) { if (dsrec->d_digesttype == DNSSECKeeper::DIGEST_SHA1 && dsrec->d_digesttype != bestDigestType) { dsrec = ds.erase(dsrec); } @@ -3666,7 +3684,8 @@ vState SyncRes::getDSRecords(const DNSName& zone, dsmap_t& ds, bool taOnly, unsi - an unsigned zone to another unsigned one (Insecure stays Insecure, Bogus stays Bogus) */ return state == vState::Secure ? vState::Insecure : state; - } else { + } + else { /* we have a DS */ d_cutStates[zone] = state; if (foundCut) { @@ -3678,7 +3697,7 @@ vState SyncRes::getDSRecords(const DNSName& zone, dsmap_t& ds, bool taOnly, unsi return state; } - LOG(d_prefix<<": returning Bogus state from "<<__func__<<"("<second<<" for name "<second << " for name " << subdomain << endl); return it->second; } } @@ -3710,7 +3729,7 @@ vState SyncRes::getValidationStatus(const DNSName& name, bool wouldBeValid, bool if (it != d_cutStates.cend()) { result = it->second; if (vStateIsBogus(result) || result == vState::Insecure) { - LOG(d_prefix<<": got status "< labelsToAdd = subdomain.makeRelative(ds).getRawLabels(); @@ -3731,15 +3750,15 @@ vState SyncRes::getValidationStatus(const DNSName& name, bool wouldBeValid, bool ds.prependRawLabel(labelsToAdd.back()); labelsToAdd.pop_back(); - LOG(d_prefix<<": - Looking for a DS at "<& dnskeys, const std::vector >& signatures, unsigned int depth) +vState SyncRes::validateDNSKeys(const DNSName& zone, const std::vector& dnskeys, const std::vector>& signatures, unsigned int depth) { dsmap_t ds; if (signatures.empty()) { - LOG(d_prefix<<": we have "< records; std::set beenthere; - LOG(d_prefix<<"Retrieving DNSKeys for "<& records, const std::vector >& signatures) +vState SyncRes::validateRecordsWithSigs(unsigned int depth, const DNSName& qname, const QType qtype, const DNSName& name, const QType type, const std::vector& records, const std::vector>& signatures) { skeyset_t keys; if (signatures.empty()) { - LOG(d_prefix<<"Bogus!"<& allowedAdditionals, const DNSRecord& rec) { - switch(rec.d_type) { + switch (rec.d_type) { case QType::MX: if (auto mxContent = getRR(rec)) { allowedAdditionals.insert(mxContent->d_mxname); @@ -4095,12 +4114,12 @@ void SyncRes::sanitizeRecords(const std::string& prefix, LWResult& lwr, const DN const bool wasForwardRecurse = wasForwarded && rdQuery; /* list of names for which we will allow A and AAAA records in the additional section to remain */ - std::unordered_set allowedAdditionals = { qname }; + std::unordered_set allowedAdditionals = {qname}; bool haveAnswers = false; bool isNXDomain = false; bool isNXQType = false; - for(auto rec = lwr.d_records.begin(); rec != lwr.d_records.end(); ) { + for (auto rec = lwr.d_records.begin(); rec != lwr.d_records.end();) { if (rec->d_type == QType::OPT) { ++rec; @@ -4108,19 +4127,19 @@ void SyncRes::sanitizeRecords(const std::string& prefix, LWResult& lwr, const DN } if (rec->d_class != QClass::IN) { - LOG(prefix<<"Removing non internet-classed data received from "<d_type == QType::ANY) { - LOG(prefix<<"Removing 'ANY'-typed data received from "<d_name.isPartOf(auth)) { - LOG(prefix<<"Removing record '"<d_name<<"|"<d_type)<<"|"<d_content->getZoneRepresentation()<<"' in the "<<(int)rec->d_place<<" section received from "<d_name << "|" << DNSRecordContent::NumberToType(rec->d_type) << "|" << rec->d_content->getZoneRepresentation() << "' in the " << (int)rec->d_place << " section received from " << auth << endl); rec = lwr.d_records.erase(rec); continue; } @@ -4130,20 +4149,20 @@ void SyncRes::sanitizeRecords(const std::string& prefix, LWResult& lwr, const DN /* for now we allow a CNAME for the exact qname in ANSWER with AA=0, because Amazon DNS servers are sending such responses */ if (!(rec->d_type == QType::CNAME && qname == rec->d_name)) { - LOG(prefix<<"Removing record '"<d_name<<"|"<d_type)<<"|"<d_content->getZoneRepresentation()<<"' in the answer section without the AA bit set received from "<d_name << "|" << DNSRecordContent::NumberToType(rec->d_type) << "|" << rec->d_content->getZoneRepresentation() << "' in the answer section without the AA bit set received from " << auth << endl); rec = lwr.d_records.erase(rec); continue; } } if (rec->d_type == QType::DNAME && (rec->d_place != DNSResourceRecord::ANSWER || !qname.isPartOf(rec->d_name))) { - LOG(prefix<<"Removing invalid DNAME record '"<d_name<<"|"<d_type)<<"|"<d_content->getZoneRepresentation()<<"' in the "<<(int)rec->d_place<<" section received from "<d_name << "|" << DNSRecordContent::NumberToType(rec->d_type) << "|" << rec->d_content->getZoneRepresentation() << "' in the " << (int)rec->d_place << " section received from " << auth << endl); rec = lwr.d_records.erase(rec); continue; } if (rec->d_place == DNSResourceRecord::ANSWER && (qtype != QType::ANY && rec->d_type != qtype.getCode() && s_redirectionQTypes.count(rec->d_type) == 0 && rec->d_type != QType::SOA && rec->d_type != QType::RRSIG)) { - LOG(prefix<<"Removing irrelevant record '"<d_name<<"|"<d_type)<<"|"<d_content->getZoneRepresentation()<<"' in the ANSWER section received from "<d_name << "|" << DNSRecordContent::NumberToType(rec->d_type) << "|" << rec->d_content->getZoneRepresentation() << "' in the ANSWER section received from " << auth << endl); rec = lwr.d_records.erase(rec); continue; } @@ -4158,20 +4177,20 @@ void SyncRes::sanitizeRecords(const std::string& prefix, LWResult& lwr, const DN /* dealing with the records in authority */ if (rec->d_place == DNSResourceRecord::AUTHORITY && rec->d_type != QType::NS && rec->d_type != QType::DS && rec->d_type != QType::SOA && rec->d_type != QType::RRSIG && rec->d_type != QType::NSEC && rec->d_type != QType::NSEC3) { - LOG(prefix<<"Removing irrelevant record '"<d_name<<"|"<d_type)<<"|"<d_content->getZoneRepresentation()<<"' in the AUTHORITY section received from "<d_name << "|" << DNSRecordContent::NumberToType(rec->d_type) << "|" << rec->d_content->getZoneRepresentation() << "' in the AUTHORITY section received from " << auth << endl); rec = lwr.d_records.erase(rec); continue; } if (rec->d_place == DNSResourceRecord::AUTHORITY && rec->d_type == QType::SOA) { if (!qname.isPartOf(rec->d_name)) { - LOG(prefix<<"Removing irrelevant SOA record '"<d_name<<"|"<d_content->getZoneRepresentation()<<"' in the AUTHORITY section received from "<d_name << "|" << rec->d_content->getZoneRepresentation() << "' in the AUTHORITY section received from " << auth << endl); rec = lwr.d_records.erase(rec); continue; } if (!(lwr.d_aabit || wasForwardRecurse)) { - LOG(prefix<<"Removing irrelevant record '"<d_name<<"|"<d_type)<<"|"<d_content->getZoneRepresentation()<<"' in the AUTHORITY section received from "<d_name << "|" << DNSRecordContent::NumberToType(rec->d_type) << "|" << rec->d_content->getZoneRepresentation() << "' in the AUTHORITY section received from " << auth << endl); rec = lwr.d_records.erase(rec); continue; } @@ -4192,7 +4211,7 @@ void SyncRes::sanitizeRecords(const std::string& prefix, LWResult& lwr, const DN * because they are somewhat easy to insert into a large, fragmented UDP response * for an off-path attacker by injecting spoofed UDP fragments. So do not add these to allowedAdditionals. */ - LOG(prefix<<"Removing NS record '"<d_name<<"|"<d_type)<<"|"<d_content->getZoneRepresentation()<<"' in the "<<(int)rec->d_place<<" section of a "<<(isNXDomain ? "NXD" : "NXQTYPE")<<" response received from "<d_name << "|" << DNSRecordContent::NumberToType(rec->d_type) << "|" << rec->d_content->getZoneRepresentation() << "' in the " << (int)rec->d_place << " section of a " << (isNXDomain ? "NXD" : "NXQTYPE") << " response received from " << auth << endl); rec = lwr.d_records.erase(rec); continue; } @@ -4202,7 +4221,7 @@ void SyncRes::sanitizeRecords(const std::string& prefix, LWResult& lwr, const DN * We don't want to pick up root NS records in AUTHORITY and their associated ADDITIONAL sections of random queries. * So don't add them to allowedAdditionals. */ - LOG(prefix<<"Removing NS record '"<d_name<<"|"<d_type)<<"|"<d_content->getZoneRepresentation()<<"' in the "<<(int)rec->d_place<<" section of a response received from "<d_name << "|" << DNSRecordContent::NumberToType(rec->d_type) << "|" << rec->d_content->getZoneRepresentation() << "' in the " << (int)rec->d_place << " section of a response received from " << auth << endl); rec = lwr.d_records.erase(rec); continue; } @@ -4213,13 +4232,13 @@ void SyncRes::sanitizeRecords(const std::string& prefix, LWResult& lwr, const DN /* dealing with the records in additional */ if (rec->d_place == DNSResourceRecord::ADDITIONAL && rec->d_type != QType::A && rec->d_type != QType::AAAA && rec->d_type != QType::RRSIG) { - LOG(prefix<<"Removing irrelevant record '"<d_name<<"|"<d_type)<<"|"<d_content->getZoneRepresentation()<<"' in the ADDITIONAL section received from "<d_name << "|" << DNSRecordContent::NumberToType(rec->d_type) << "|" << rec->d_content->getZoneRepresentation() << "' in the ADDITIONAL section received from " << auth << endl); rec = lwr.d_records.erase(rec); continue; } if (rec->d_place == DNSResourceRecord::ADDITIONAL && allowedAdditionals.count(rec->d_name) == 0) { - LOG(prefix<<"Removing irrelevant additional record '"<d_name<<"|"<d_type)<<"|"<d_content->getZoneRepresentation()<<"' in the ADDITIONAL section received from "<d_name << "|" << DNSRecordContent::NumberToType(rec->d_type) << "|" << rec->d_content->getZoneRepresentation() << "' in the ADDITIONAL section received from " << auth << endl); rec = lwr.d_records.erase(rec); continue; } @@ -4228,7 +4247,6 @@ void SyncRes::sanitizeRecords(const std::string& prefix, LWResult& lwr, const DN } } - void SyncRes::rememberParentSetIfNeeded(const DNSName& domain, const vector& newRecords, unsigned int depth) { vector existing; @@ -4283,8 +4301,8 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, LWResult& lwr tcache_t tcache; string prefix; - if(doLog()) { - prefix=d_prefix; + if (doLog()) { + prefix = d_prefix; prefix.append(depth, ' '); } @@ -4304,7 +4322,7 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, LWResult& lwr rec.d_ttl = min(s_maxcachettl, rec.d_ttl); - if (!isCNAMEAnswer && rec.d_place == DNSResourceRecord::ANSWER && rec.d_type == QType::CNAME && (!(qtype==QType::CNAME)) && rec.d_name == qname && !isDNAMEAnswer) { + if (!isCNAMEAnswer && rec.d_place == DNSResourceRecord::ANSWER && rec.d_type == QType::CNAME && (!(qtype == QType::CNAME)) && rec.d_name == qname && !isDNAMEAnswer) { isCNAMEAnswer = true; } if (!isDNAMEAnswer && rec.d_place == DNSResourceRecord::ANSWER && rec.d_type == QType::DNAME && qtype != QType::DNAME && qname.isPartOf(rec.d_name)) { @@ -4331,11 +4349,11 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, LWResult& lwr We still want to gather the corresponding NSEC/NSEC3 records to pass them to our client in case it wants to validate by itself. */ - LOG(prefix<d_labels; } @@ -4370,26 +4388,26 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, LWResult& lwr // reap all answers from this packet that are acceptable for (auto& rec : lwr.d_records) { - if(rec.d_type == QType::OPT) { - LOG(prefix<getZoneRepresentation()<<"' from '"<getZoneRepresentation() << "' from '" << auth << "' nameservers? ttl=" << rec.d_ttl << ", place=" << (int)rec.d_place << " "); // We called sanitizeRecords before, so all ANY, non-IN and non-aa/non-forwardrecurse answer records are already removed - if(rec.d_name.isPartOf(auth)) { + if (rec.d_name.isPartOf(auth)) { if (rec.d_type == QType::RRSIG) { - LOG("RRSIG - separate"<empty()) { @@ -4399,17 +4417,18 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, LWResult& lwr if (rec.d_type == QType::DS) { tmp_qname.chopOff(); } - auto auth_domain_iter=getBestAuthZone(&tmp_qname); - if(auth_domain_iter!=t_sstorage.domainmap->end() && - auth.countLabels() <= auth_domain_iter->first.countLabels()) { + auto auth_domain_iter = getBestAuthZone(&tmp_qname); + if (auth_domain_iter != t_sstorage.domainmap->end() && auth.countLabels() <= auth_domain_iter->first.countLabels()) { if (auth_domain_iter->first != auth) { - LOG("NO! - we are authoritative for the zone "<first<first << endl); continue; - } else { + } + else { LOG("YES! - This answer was "); if (!wasForwarded) { LOG("retrieved from the local auth store."); - } else { + } + else { LOG("received from a server we forward to."); } haveLogged = true; @@ -4418,24 +4437,24 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, LWResult& lwr } } if (!haveLogged) { - LOG("YES!"< 1) { // need to group the ttl to be the minimum of the RRSET (RFC 2181, 5.2) + if ((entry.second.records.size() + entry.second.signatures.size() + authorityRecs.size()) > 1) { // need to group the ttl to be the minimum of the RRSET (RFC 2181, 5.2) uint32_t lowestTTD = computeLowestTTD(entry.second.records, entry.second.signatures, entry.second.signaturesTTL, authorityRecs); for (auto& record : entry.second.records) { @@ -4443,11 +4462,11 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, LWResult& lwr } } -// cout<<"Have "<second.records.size()<<" records and "<second.signatures.size()<<" signatures for "<first.name; -// cout<<'|'<first.type)<second.records.size()<<" records and "<second.signatures.size()<<" signatures for "<first.name; + // cout<<'|'<first.type)<second.records.empty()) // this happens when we did store signatures, but passed on the records themselves continue; @@ -4502,7 +4521,7 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, LWResult& lwr even after the delegation is gone from the parent. So let's just do nothing with them, we can fetch them directly if we need them. */ - LOG(d_prefix<<": skipping authority NS from '"<first.name<<"|"<first.type)<first.name << "|" << DNSRecordContent::NumberToType(i->first.type) << endl); continue; } @@ -4526,24 +4545,24 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, LWResult& lwr if (expectSignature && shouldValidate()) { vState initialState = getValidationStatus(i->first.name, !i->second.signatures.empty(), i->first.type == QType::DS, depth); - LOG(d_prefix<<": got initial zone status "<first.name<<"|"<first.type)<first.name << "|" << DNSRecordContent::NumberToType(i->first.type) << endl); if (initialState == vState::Secure) { if (i->first.type == QType::DNSKEY && i->first.place == DNSResourceRecord::ANSWER && i->first.name == getSigner(i->second.signatures)) { - LOG(d_prefix<<"Validating DNSKEY for "<first.name<first.name << endl); recordState = validateDNSKeys(i->first.name, i->second.records, i->second.signatures, depth); } else { - LOG(d_prefix<<"Validating non-additional "<first.type).toString()<<" record for "<first.name<first.type).toString() << " record for " << i->first.name << endl); recordState = validateRecordsWithSigs(depth, qname, qtype, i->first.name, QType(i->first.type), i->second.records, i->second.signatures); } } else { recordState = initialState; - LOG(d_prefix<<"Skipping validation because the current state is "<second.records) { + for (auto& record : i->second.records) { record.d_ttl = std::min(record.d_ttl, static_cast(s_maxbogusttl + d_now.tv_sec)); } } @@ -4575,12 +4594,11 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, LWResult& lwr } // If ednsmask is relevant, we do not want to cache if the scope prefix length is large and TTL is small if (doCache && s_ecscachelimitttl > 0) { - bool manyMaskBits = (isv4 && ednsmask->getBits() > s_ecsipv4cachelimit) || - (!isv4 && ednsmask->getBits() > s_ecsipv6cachelimit); + bool manyMaskBits = (isv4 && ednsmask->getBits() > s_ecsipv4cachelimit) || (!isv4 && ednsmask->getBits() > s_ecsipv6cachelimit); if (manyMaskBits) { uint32_t minttl = UINT32_MAX; - for (const auto &it : i->second.records) { + for (const auto& it : i->second.records) { if (it.d_ttl < minttl) minttl = it.d_ttl; } @@ -4634,7 +4652,7 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, LWResult& lwr } if (i->first.place == DNSResourceRecord::ANSWER && ednsmask) { - d_wasVariable=true; + d_wasVariable = true; } } @@ -4648,7 +4666,7 @@ void SyncRes::updateDenialValidationState(vState& neValidationState, const DNSNa } else { if (denialState == dState::OPTOUT) { - LOG(d_prefix<<"OPT-out denial found for "<(rec)) { newtarget = DNSName(content->getTarget()); } - } else if (rec.d_type == QType::DNAME && qname.isPartOf(rec.d_name)) { // DNAME + } + else if (rec.d_type == QType::DNAME && qname.isPartOf(rec.d_name)) { // DNAME ret.push_back(rec); if (auto content = getRR(rec)) { dnameOwner = rec.d_name; @@ -4795,22 +4813,20 @@ bool SyncRes::processRecords(const std::string& prefix, const DNSName& qname, co dnameTTL = rec.d_ttl; if (!newtarget.empty()) { // We had a CNAME before, remove it from ret so we don't cache it ret.erase(std::remove_if( - ret.begin(), - ret.end(), - [&qname](DNSRecord& rr) { - return (rr.d_place == DNSResourceRecord::ANSWER && rr.d_type == QType::CNAME && rr.d_name == qname); - }), - ret.end()); + ret.begin(), + ret.end(), + [&qname](DNSRecord& rr) { + return (rr.d_place == DNSResourceRecord::ANSWER && rr.d_type == QType::CNAME && rr.d_name == qname); + }), + ret.end()); } try { newtarget = qname.makeRelative(dnameOwner) + dnameTarget; - } catch (const std::exception &e) { + } + catch (const std::exception& e) { // We should probably catch an std::range_error here and set the rcode to YXDOMAIN (RFC 6672, section 2.2) // But there is no way to set the RCODE from this function - throw ImmediateServFailException("Unable to perform DNAME substitution(DNAME owner: '" + dnameOwner.toLogString() + - "', DNAME target: '" + dnameTarget.toLogString() + "', substituted name: '" + - qname.makeRelative(dnameOwner).toLogString() + "." + dnameTarget.toLogString() + - "' : " + e.what()); + throw ImmediateServFailException("Unable to perform DNAME substitution(DNAME owner: '" + dnameOwner.toLogString() + "', DNAME target: '" + dnameTarget.toLogString() + "', substituted name: '" + qname.makeRelative(dnameOwner).toLogString() + "." + dnameTarget.toLogString() + "' : " + e.what()); } } } @@ -4823,13 +4839,8 @@ bool SyncRes::processRecords(const std::string& prefix, const DNSName& qname, co ret.push_back(rec); // enjoy your DNSSEC } // for ANY answers we *must* have an authoritative answer, unless we are forwarding recursively - else if (rec.d_place == DNSResourceRecord::ANSWER && rec.d_name == qname && - ( - rec.d_type == qtype.getCode() || ((lwr.d_aabit || sendRDQuery) && qtype == QType::ANY) - ) - ) - { - LOG(prefix<getZoneRepresentation()<<"|"<getZoneRepresentation() << "|" << DNSRecordContent::NumberToType(rec.d_type) << "'" << endl); done = true; rcode = RCode::NoError; @@ -4861,10 +4872,10 @@ bool SyncRes::processRecords(const std::string& prefix, const DNSName& qname, co /* Some part could not be validated, for example a NSEC3 record with a too large number of iterations, this is not enough to warrant a Bogus, but go Insecure. */ st = vState::Insecure; - LOG(d_prefix<<"Unable to validate denial in wildcard expanded positive response found for "< '"<getZoneRepresentation()<<"'"< '" << rec.d_content->getZoneRepresentation() << "'" << endl); /* check if we have a referral from the parent zone to a child zone for a DS query, which is not right */ if (qtype == QType::DS && (newauth.isPartOf(qname) || qname == newauth)) { @@ -4906,14 +4918,14 @@ bool SyncRes::processRecords(const std::string& prefix, const DNSName& qname, co } } else { - LOG(prefix< '"<getZoneRepresentation()<<"', had '"< '" << rec.d_content->getZoneRepresentation() << "', had '" << auth << "'" << endl); if (auto content = getRR(rec)) { nsset.insert(content->getNS()); } } } - else if (rec.d_place==DNSResourceRecord::AUTHORITY && rec.d_type==QType::DS && qname.isPartOf(rec.d_name)) { - LOG(prefix< '"<getZoneRepresentation()<<"'"< '" << rec.d_content->getZoneRepresentation() << "'" << endl); } else if (realreferral && rec.d_place == DNSResourceRecord::AUTHORITY && (rec.d_type == QType::NSEC || rec.d_type == QType::NSEC3) && newauth.isPartOf(auth)) { /* we might have received a denial of the DS, let's check */ @@ -4939,7 +4951,7 @@ bool SyncRes::processRecords(const std::string& prefix, const DNSName& qname, co if (denialState == dState::OPTOUT) { ne.d_validationState = vState::Insecure; } - LOG(prefix<add(ne); @@ -4956,12 +4968,11 @@ bool SyncRes::processRecords(const std::string& prefix, const DNSName& qname, co } } } - else if (!done && rec.d_place == DNSResourceRecord::AUTHORITY && rec.d_type == QType::SOA && - lwr.d_rcode == RCode::NoError && qname.isPartOf(rec.d_name)) { - LOG(prefix<add(ne); } @@ -5017,12 +5029,12 @@ bool SyncRes::processRecords(const std::string& prefix, const DNSName& qname, co /* If we have seen a proper denial, let's forget that we also had a referral for a DS query. Otherwise we need to deal with it. */ if (referralOnDS && !negindic) { - LOG(prefix<d_map.modify(it, [=] (DoTStatus& st){ st.d_ttd = now + dotFailWait; }); + lock->d_map.modify(it, [=](DoTStatus& st) { st.d_ttd = now + dotFailWait; }); bool pushed = pushTryDoTTask(auth, QType::SOA, address, std::numeric_limits::max(), nsname); if (pushed) { it->d_status = DoTStatus::Busy; @@ -5090,7 +5101,7 @@ static void updateDoTStatus(ComboAddress address, DoTStatus::Status status, time auto it = lock->d_map.find(address); if (it != lock->d_map.end()) { it->d_status = status; - lock->d_map.modify(it, [=] (DoTStatus& st) { st.d_ttd = time; }); + lock->d_map.modify(it, [=](DoTStatus& st) { st.d_ttd = time; }); if (updateBusy) { --lock->d_numBusy; } @@ -5118,19 +5129,19 @@ bool SyncRes::tryDoT(const DNSName& qname, const QType qtype, const DNSName& nsN ok = doResolveAtThisIP("", qname, qtype, lwr, nm, qname, false, false, nsName, address, true, true, truncated, spoofed, true); ok = ok && lwr.d_rcode == RCode::NoError && lwr.d_records.size() > 0; } - catch(const PDNSException& e) { + catch (const PDNSException& e) { logHelper2(e.reason, "PDNSException"); } - catch(const ImmediateServFailException& e) { + catch (const ImmediateServFailException& e) { logHelper2(e.reason, "ImmediateServFailException"); } - catch(const PolicyHitException& e) { + catch (const PolicyHitException& e) { logHelper1("PolicyHitException"); } - catch(const std::exception& e) { + catch (const std::exception& e) { logHelper2(e.what(), "std::exception"); } - catch(...) { + catch (...) { logHelper1("other"); } updateDoTStatus(address, ok ? DoTStatus::Good : DoTStatus::Bad, now + (ok ? dotSuccessWait : dotFailWait), true); @@ -5145,43 +5156,44 @@ bool SyncRes::doResolveAtThisIP(const std::string& prefix, const DNSName& qname, d_outqueries++; checkMaxQperQ(qname); - if(s_maxtotusec && d_totUsec > s_maxtotusec) { - throw ImmediateServFailException("Too much time waiting for "+qname.toLogString()+"|"+qtype.toString()+", timeouts: "+std::to_string(d_timeouts) +", throttles: "+std::to_string(d_throttledqueries) + ", queries: "+std::to_string(d_outqueries)+", "+std::to_string(d_totUsec/1000)+"msec"); + if (s_maxtotusec && d_totUsec > s_maxtotusec) { + throw ImmediateServFailException("Too much time waiting for " + qname.toLogString() + "|" + qtype.toString() + ", timeouts: " + std::to_string(d_timeouts) + ", throttles: " + std::to_string(d_throttledqueries) + ", queries: " + std::to_string(d_outqueries) + ", " + std::to_string(d_totUsec / 1000) + "msec"); } - if(doTCP) { + if (doTCP) { if (doDoT) { - LOG(prefix<preoutquery(remoteIP, d_requestor, qname, qtype, doTCP, lwr.d_records, preOutQueryRet, d_eventTrace, timeval{0, 0})) { - LOG(prefix<preoutquery(remoteIP, d_requestor, qname, qtype, doTCP, lwr.d_records, preOutQueryRet, d_eventTrace, timeval{0, 0})) { + LOG(prefix << qname << ": query handled by Lua" << endl); } else { - ednsmask=getEDNSSubnetMask(qname, remoteIP); - if(ednsmask) { - LOG(prefix<toString()<<" to query"<toString() << " to query" << endl); s_ecsqueries++; } resolveret = asyncresolveWrapper(remoteIP, d_doDNSSEC, qname, auth, qtype.getCode(), - doTCP, sendRDQuery, &d_now, ednsmask, &lwr, &chained, nsName); // <- we go out on the wire! - if(ednsmask) { + doTCP, sendRDQuery, &d_now, ednsmask, &lwr, &chained, nsName); // <- we go out on the wire! + if (ednsmask) { s_ecsresponses++; - LOG(prefix<toString()<<" on response"<toString() << " on response" << endl); if (ednsmask->getBits() > 0) { if (ednsmask->isIPv4()) { - ++SyncRes::s_ecsResponsesBySubnetSize4.at(ednsmask->getBits()-1); + ++SyncRes::s_ecsResponsesBySubnetSize4.at(ednsmask->getBits() - 1); } else { - ++SyncRes::s_ecsResponsesBySubnetSize6.at(ednsmask->getBits()-1); + ++SyncRes::s_ecsResponsesBySubnetSize6.at(ednsmask->getBits() - 1); } } } @@ -5207,21 +5219,21 @@ bool SyncRes::doResolveAtThisIP(const std::string& prefix, const DNSName& qname, if (resolveret == LWResult::Result::Timeout) { /* Time out */ - LOG(prefix<push_back(remoteIP); } else if (resolveret == LWResult::Result::OSLimitError) { /* OS resource limit reached */ - LOG(prefix<find_or_enter(nsName.empty()? DNSName(remoteIP.toStringWithPort()) : nsName, d_now).submit(remoteIP, 1000000, d_now); // 1 sec + s_nsSpeeds.lock()->find_or_enter(nsName.empty() ? DNSName(remoteIP.toStringWithPort()) : nsName, d_now).submit(remoteIP, 1000000, d_now); // 1 sec // code below makes sure we don't filter COM or the root if (s_serverdownmaxfails > 0 && (auth != g_rootdnsname) && s_fails.lock()->incr(remoteIP, d_now) >= s_serverdownmaxfails) { - LOG(prefix<find_or_enter(nsName.empty()? DNSName(remoteIP.toStringWithPort()) : nsName, d_now).submit(remoteIP, 1000000, d_now); // 1 sec + s_nsSpeeds.lock()->find_or_enter(nsName.empty() ? DNSName(remoteIP.toStringWithPort()) : nsName, d_now).submit(remoteIP, 1000000, d_now); // 1 sec if (doTCP) { // we can be more heavy-handed over TCP @@ -5279,13 +5291,13 @@ bool SyncRes::doResolveAtThisIP(const std::string& prefix, const DNSName& qname, else { /* we got an answer */ if (lwr.d_rcode != RCode::NoError && lwr.d_rcode != RCode::NXDomain) { - LOG(prefix<find_or_enter(nsName.empty()? DNSName(remoteIP.toStringWithPort()) : nsName, d_now).submit(remoteIP, 1000000, d_now); // 1 sec + s_nsSpeeds.lock()->find_or_enter(nsName.empty() ? DNSName(remoteIP.toStringWithPort()) : nsName, d_now).submit(remoteIP, 1000000, d_now); // 1 sec } else { doThrottle(d_now.tv_sec, remoteIP, qname, qtype, 60, 3); @@ -5296,7 +5308,7 @@ bool SyncRes::doResolveAtThisIP(const std::string& prefix, const DNSName& qname, } /* this server sent a valid answer, mark it backup up if it was down */ - if(s_serverdownmaxfails > 0) { + if (s_serverdownmaxfails > 0) { s_fails.lock()->clear(remoteIP); } @@ -5304,14 +5316,14 @@ bool SyncRes::doResolveAtThisIP(const std::string& prefix, const DNSName& qname, truncated = true; if (doTCP) { - LOG(prefix<& ret, int& rcode, int depth, const std::vector& recordsFromAnswer, vState& state) { if (newtarget == qname) { - LOG(prefix< 10) { - LOG(prefix< beenthere; vState cnameState = vState::Indeterminate; rcode = doResolve(newtarget, qtype, ret, depth + 1, beenthere, cnameState); - LOG(prefix< ednsmask, bool sendRDQuery, NsSet &nameservers, std::vector& ret, const DNSFilterEngine& dfe, bool* gotNewServers, int* rcode, vState& state, const ComboAddress& remoteIP) +bool SyncRes::processAnswer(unsigned int depth, LWResult& lwr, const DNSName& qname, const QType qtype, DNSName& auth, bool wasForwarded, const boost::optional ednsmask, bool sendRDQuery, NsSet& nameservers, std::vector& ret, const DNSFilterEngine& dfe, bool* gotNewServers, int* rcode, vState& state, const ComboAddress& remoteIP) { string prefix; - if(doLog()) { - prefix=d_prefix; + if (doLog()) { + prefix = d_prefix; prefix.append(depth, ' '); } - if(s_minimumTTL) { - for(auto& rec : lwr.d_records) { + if (s_minimumTTL) { + for (auto& rec : lwr.d_records) { rec.d_ttl = max(rec.d_ttl, s_minimumTTL); } } @@ -5389,7 +5401,7 @@ bool SyncRes::processAnswer(unsigned int depth, LWResult& lwr, const DNSName& qn /* if the answer is ECS-specific, a minimum TTL is set for this kind of answers and it's higher than the global minimum TTL */ if (ednsmask && s_minimumECSTTL > 0 && (s_minimumTTL == 0 || s_minimumECSTTL > s_minimumTTL)) { - for(auto& rec : lwr.d_records) { + for (auto& rec : lwr.d_records) { if (rec.d_place == DNSResourceRecord::ANSWER) { rec.d_ttl = max(rec.d_ttl, s_minimumECSTTL); } @@ -5404,7 +5416,7 @@ bool SyncRes::processAnswer(unsigned int depth, LWResult& lwr, const DNSName& qn return true; } - LOG(prefix< nsset; bool realreferral = false; @@ -5415,9 +5427,9 @@ bool SyncRes::processAnswer(unsigned int depth, LWResult& lwr, const DNSName& qn bool done = processRecords(prefix, qname, qtype, auth, lwr, sendRDQuery, ret, nsset, newtarget, newauth, realreferral, negindic, state, needWildcardProof, gatherWildcardProof, wildcardLabelsCount, *rcode, negIndicHasSignatures, depth); - if (done){ - LOG(prefix<&ret, - unsigned int depth, set&beenthere, vState& state, StopAtDelegation* stopAtDelegation, +int SyncRes::doResolveAt(NsSet& nameservers, DNSName auth, bool flawedNSSet, const DNSName& qname, const QType qtype, + vector& ret, + unsigned int depth, set& beenthere, vState& state, StopAtDelegation* stopAtDelegation, map>* fallBack) { auto luaconfsLocal = g_luaconfs.getLocal(); string prefix; - if(doLog()) { - prefix=d_prefix; + if (doLog()) { + prefix = d_prefix; prefix.append(depth, ' '); } - LOG(prefix<dfe, nameservers)) { /* RPZ hit */ @@ -5540,8 +5552,8 @@ int SyncRes::doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, con LOG(endl); unsigned int addressQueriesForNS = 0; - for(;;) { // we may get more specific nameservers - auto rnameservers = shuffleInSpeedOrder(nameservers, doLog() ? (prefix+qname.toString()+": ") : string() ); + for (;;) { // we may get more specific nameservers + auto rnameservers = shuffleInSpeedOrder(nameservers, doLog() ? (prefix + qname.toString() + ": ") : string()); // We allow s_maxnsaddressqperq (default 10) queries with empty responses when resolving NS names. // If a zone publishes many (more than s_maxnsaddressqperq) NS records, we allow less. @@ -5553,16 +5565,16 @@ int SyncRes::doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, con nsLimit = std::max(5, newLimit); } - for(auto tns=rnameservers.cbegin();;++tns) { + for (auto tns = rnameservers.cbegin();; ++tns) { if (addressQueriesForNS >= nsLimit) { - throw ImmediateServFailException(std::to_string(nsLimit)+" (adjusted max-ns-address-qperq) or more queries with empty results for NS addresses sent resolving "+qname.toLogString()); + throw ImmediateServFailException(std::to_string(nsLimit) + " (adjusted max-ns-address-qperq) or more queries with empty results for NS addresses sent resolving " + qname.toLogString()); } - if(tns==rnameservers.cend()) { - LOG(prefix<doAgeCache(d_now.tv_sec, auth, QType::NS, 10)) + if (g_recCache->doAgeCache(d_now.tv_sec, auth, QType::NS, 10)) t_Counters.at(rec::Counter::nsSetInvalidations)++; } return -1; @@ -5570,18 +5582,18 @@ int SyncRes::doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, con bool cacheOnly = false; // this line needs to identify the 'self-resolving' behaviour - if(qname == tns->first && (qtype.getCode() == QType::A || qtype.getCode() == QType::AAAA)) { + if (qname == tns->first && (qtype.getCode() == QType::A || qtype.getCode() == QType::AAAA)) { /* we might have a glue entry in cache so let's try this NS but only if we have enough in the cache to know how to reach it */ - LOG(prefix< remoteIPs_t; remoteIPs_t remoteIPs; remoteIPs_t::iterator remoteIP; - bool pierceDontQuery=false; - bool sendRDQuery=false; + bool pierceDontQuery = false; + bool sendRDQuery = false; boost::optional ednsmask; LWResult lwr; const bool wasForwarded = tns->first.empty() && (!nameservers[tns->first].first.empty()); @@ -5590,13 +5602,13 @@ int SyncRes::doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, con if (tns->first.empty() && !wasForwarded) { static ComboAddress const s_oobRemote("255.255.255.255"); - LOG(prefix<dfe, &gotNewServers, &rcode, state, s_oobRemote); @@ -5621,25 +5633,25 @@ int SyncRes::doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, con remoteIPs = retrieveAddressesForNS(prefix, qname, tns, depth, beenthere, rnameservers, nameservers, sendRDQuery, pierceDontQuery, flawedNSSet, cacheOnly, addressQueriesForNS); } - if(remoteIPs.empty()) { - LOG(prefix<first<<", trying next if available"<first << ", trying next if available" << endl); + flawedNSSet = true; continue; } else { bool hitPolicy{false}; - LOG(prefix<first<<" to: "); - for(remoteIP = remoteIPs.begin(); remoteIP != remoteIPs.end(); ++remoteIP) { - if(remoteIP != remoteIPs.begin()) { + LOG(prefix << qname << ": Resolved '" << auth << "' NS " << tns->first << " to: "); + for (remoteIP = remoteIPs.begin(); remoteIP != remoteIPs.end(); ++remoteIP) { + if (remoteIP != remoteIPs.begin()) { LOG(", "); } LOG(remoteIP->toString()); - if(nameserverIPBlockedByRPZ(luaconfsLocal->dfe, *remoteIP)) { + if (nameserverIPBlockedByRPZ(luaconfsLocal->dfe, *remoteIP)) { hitPolicy = true; } } LOG(endl); - if (hitPolicy) { //implies d_wantsRPZ + if (hitPolicy) { // implies d_wantsRPZ /* RPZ hit */ if (d_pdl && d_pdl->policyHitEventFilter(d_requestor, qname, qtype, d_queryReceivedOverTCP, d_appliedPolicy, d_policyTags, d_discardedPolicies)) { /* reset to no match */ @@ -5651,8 +5663,8 @@ int SyncRes::doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, con } } - for(remoteIP = remoteIPs.begin(); remoteIP != remoteIPs.end(); ++remoteIP) { - LOG(prefix<toStringWithPort() <<", asking '"<toStringWithPort() << ", asking '" << qname << "|" << qtype << "'" << endl); if (throttledOrBlocked(prefix, *remoteIP, qname, qtype, pierceDontQuery)) { // As d_throttledqueries might be increased, check the max-qperq condition @@ -5695,7 +5707,7 @@ int SyncRes::doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, con continue; } - LOG(prefix<first<<" ("<< remoteIP->toString() <<"), rcode="<first << " (" << remoteIP->toString() << "), rcode=" << lwr.d_rcode << " (" << RCode::to_s(lwr.d_rcode) << "), aa=" << lwr.d_aabit << ", in " << lwr.d_usec / 1000 << "ms" << endl); if (doDoT && s_max_busy_dot_probes > 0) { updateDoTStatus(*remoteIP, DoTStatus::Good, d_now.tv_sec + dotSuccessWait); @@ -5706,7 +5718,7 @@ int SyncRes::doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, con */ // cout<<"msec: "<find_or_enter(tns->first.empty()? DNSName(remoteIP->toStringWithPort()) : tns->first, d_now).submit(*remoteIP, lwr.d_usec, d_now); + s_nsSpeeds.lock()->find_or_enter(tns->first.empty() ? DNSName(remoteIP->toStringWithPort()) : tns->first, d_now).submit(*remoteIP, lwr.d_usec, d_now); /* we have received an answer, are we done ? */ bool done = processAnswer(depth, lwr, qname, qtype, auth, wasForwarded, ednsmask, sendRDQuery, nameservers, ret, luaconfsLocal->dfe, &gotNewServers, &rcode, state, *remoteIP); @@ -5728,9 +5740,8 @@ int SyncRes::doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, con break; } - if(remoteIP == remoteIPs.cend()) // we tried all IP addresses, none worked + if (remoteIP == remoteIPs.cend()) // we tried all IP addresses, none worked continue; - } } } @@ -5757,15 +5768,17 @@ void SyncRes::setQuerySource(const ComboAddress& requestor, boost::optionalsource.getNetwork(); trunc.truncate(bits); d_outgoingECSNetwork = boost::optional(Netmask(trunc, bits)); - } else { + } + else { d_cacheRemote = d_requestor; - if(!incomingECS && s_ednslocalsubnets.match(d_requestor)) { + if (!incomingECS && s_ednslocalsubnets.match(d_requestor)) { ComboAddress trunc = d_requestor; uint8_t bits = d_requestor.isIPv4() ? 32 : 128; bits = std::min(bits, (trunc.isIPv4() ? s_ecsipv4limit : s_ecsipv6limit)); trunc.truncate(bits); d_outgoingECSNetwork = boost::optional(Netmask(trunc, bits)); - } else if (s_ecsScopeZero.source.getBits() > 0) { + } + else if (s_ecsScopeZero.source.getBits() > 0) { /* RFC7871 says we MUST NOT send any ECS if the source scope is 0. But using an empty ECS in that case would mean inserting a non ECS-specific entry into the cache, preventing any further @@ -5782,7 +5795,8 @@ void SyncRes::setQuerySource(const ComboAddress& requestor, boost::optional(s_ecsScopeZero.source.getMaskedNetwork()); d_cacheRemote = s_ecsScopeZero.source.getNetwork(); - } else { + } + else { // ECS disabled because no scope-zero address could be derived. d_outgoingECSNetwork = boost::none; } @@ -5791,7 +5805,7 @@ void SyncRes::setQuerySource(const ComboAddress& requestor, boost::optional SyncRes::getEDNSSubnetMask(const DNSName& dn, const ComboAddress& rem) { - if(d_outgoingECSNetwork && (s_ednsdomains.check(dn) || s_ednsremotesubnets.match(rem))) { + if (d_outgoingECSNetwork && (s_ednsdomains.check(dn) || s_ednsremotesubnets.match(rem))) { return d_outgoingECSNetwork; } return boost::none; @@ -5801,11 +5815,11 @@ void SyncRes::parseEDNSSubnetAllowlist(const std::string& alist) { vector parts; stringtok(parts, alist, ",; "); - for(const auto& a : parts) { + for (const auto& a : parts) { try { s_ednsremotesubnets.addMask(Netmask(a)); } - catch(...) { + catch (...) { s_ednsdomains.add(DNSName(a)); } } @@ -5815,7 +5829,7 @@ void SyncRes::parseEDNSSubnetAddFor(const std::string& subnetlist) { vector parts; stringtok(parts, subnetlist, ",; "); - for(const auto& a : parts) { + for (const auto& a : parts) { s_ednslocalsubnets.addMask(a); } } @@ -5844,28 +5858,28 @@ int directResolve(const DNSName& qname, const QType qtype, const QClass qclass, try { res = sr.beginResolve(qname, qtype, qclass, ret, 0); } - catch(const PDNSException& e) { - SLOG(g_log<error(Logr::Error, e.reason, msg, "exception", Logging::Loggable("PDNSException"))); ret.clear(); } - catch(const ImmediateServFailException& e) { - SLOG(g_log<error(Logr::Error, e.reason, msg, "exception", Logging::Loggable("ImmediateServFailException"))); ret.clear(); } - catch(const PolicyHitException& e) { - SLOG(g_log<info(Logr::Error, msg, "exception", Logging::Loggable("PolicyHitException"))); ret.clear(); } - catch(const std::exception& e) { - SLOG(g_log<error(Logr::Error, e.what(), msg, "exception", Logging::Loggable("std::exception"))); ret.clear(); } - catch(...) { - SLOG(g_log<info(Logr::Error, msg)); ret.clear(); } @@ -5873,7 +5887,8 @@ int directResolve(const DNSName& qname, const QType qtype, const QClass qclass, return res; } -int SyncRes::getRootNS(struct timeval now, asyncresolve_t asyncCallback, unsigned int depth, Logr::log_t log) { +int SyncRes::getRootNS(struct timeval now, asyncresolve_t asyncCallback, unsigned int depth, Logr::log_t log) +{ SyncRes sr(now); sr.setDoEDNS0(true); sr.setUpdatingRootNS(); @@ -5895,33 +5910,33 @@ int SyncRes::getRootNS(struct timeval now, asyncresolve_t asyncCallback, unsigne } } catch (const PDNSException& e) { - SLOG(g_log<error(Logr::Error, e.reason, msg, "exception", Logging::Loggable("PDNSException"))); } catch (const ImmediateServFailException& e) { - SLOG(g_log<error(Logr::Error, e.reason, msg, "exception", Logging::Loggable("ImmediateServFailException"))); } catch (const PolicyHitException& e) { - SLOG(g_log<info(Logr::Error, msg, "exception", Logging::Loggable("PolicyHitException"))); ret.clear(); } catch (const std::exception& e) { - SLOG(g_log<error(Logr::Error, e.what(), msg, "exception", Logging::Loggable("std::exception"))); } catch (...) { - SLOG(g_log<info(Logr::Error, msg)); } if (res == 0) { - SLOG(g_log<info(Logr::Debug, "Refreshed . records")); } else { - SLOG(g_log<, - bool - > -> NsSet; - + bool>> + NsSet; extern std::unique_ptr g_negCache; class SyncRes : public boost::noncopyable { public: - enum LogMode { LogNone, Log, Store}; - typedef std::function& srcmask, boost::optional context, LWResult *lwr, bool* chained)> asyncresolve_t; + enum LogMode + { + LogNone, + Log, + Store + }; + typedef std::function& srcmask, boost::optional context, LWResult* lwr, bool* chained)> asyncresolve_t; - enum class HardenNXD { No, DNSSEC, Yes }; + enum class HardenNXD + { + No, + DNSSEC, + Yes + }; - vState getDSRecords(const DNSName& zone, dsmap_t& ds, bool onlyTA, unsigned int depth, bool bogusOnNXD=true, bool* foundCut=nullptr); + vState getDSRecords(const DNSName& zone, dsmap_t& ds, bool onlyTA, unsigned int depth, bool bogusOnNXD = true, bool* foundCut = nullptr); class AuthDomain { public: - typedef multi_index_container < + typedef multi_index_container< DNSRecord, - indexed_by < + indexed_by< ordered_non_unique< - composite_key< DNSRecord, - member, - member - >, - composite_key_compare, std::less > - > - > - > records_t; + composite_key, + member>, + composite_key_compare, std::less>>>> + records_t; records_t d_records; vector d_servers; @@ -117,9 +122,8 @@ public: bool operator==(const AuthDomain& rhs) const; - [[nodiscard]] - std::string print(const std::string& indent = "", - const std::string& indentLevel = " ") const; + [[nodiscard]] std::string print(const std::string& indent = "", + const std::string& indentLevel = " ") const; int getRecords(const DNSName& qname, QType qtype, std::vector& records) const; bool isAuth() const @@ -145,7 +149,8 @@ public: typedef std::unordered_map domainmap_t; - struct ThreadLocalStorage { + struct ThreadLocalStorage + { std::shared_ptr domainmap; }; @@ -214,15 +219,22 @@ public: static void clearNSSpeeds(); static float getNSSpeed(const DNSName& server, const ComboAddress& ca); - struct EDNSStatus { - EDNSStatus(const ComboAddress &arg) : address(arg) {} + struct EDNSStatus + { + EDNSStatus(const ComboAddress& arg) : + address(arg) {} ComboAddress address; time_t ttd{0}; - enum EDNSMode : uint8_t { EDNSOK = 0, EDNSIGNORANT = 1, NOEDNS = 2 } mode{EDNSOK}; + enum EDNSMode : uint8_t + { + EDNSOK = 0, + EDNSIGNORANT = 1, + NOEDNS = 2 + } mode{EDNSOK}; std::string toString() const { - const std::array modes = { "OK", "Ignorant", "No" }; + const std::array modes = {"OK", "Ignorant", "No"}; unsigned int m = static_cast(mode); if (m >= modes.size()) { return "?"; @@ -289,13 +301,13 @@ public: explicit SyncRes(const struct timeval& now); - int beginResolve(const DNSName &qname, QType qtype, QClass qclass, vector&ret, unsigned int depth = 0); + int beginResolve(const DNSName& qname, QType qtype, QClass qclass, vector& ret, unsigned int depth = 0); bool tryDoT(const DNSName& qname, QType qtype, const DNSName& nsName, ComboAddress address, time_t); void setId(int id) { - if(doLog()) - d_prefix="["+std::to_string(id)+"] "; + if (doLog()) + d_prefix = "[" + std::to_string(id) + "] "; } void setLogMode(LogMode lm) @@ -329,17 +341,17 @@ public: return old; } - void setDoEDNS0(bool state=true) + void setDoEDNS0(bool state = true) { - d_doEDNS0=state; + d_doEDNS0 = state; } - void setDoDNSSEC(bool state=true) + void setDoDNSSEC(bool state = true) { - d_doDNSSEC=state; + d_doDNSSEC = state; } - void setDNSSECValidationRequested(bool requested=true) + void setDNSSECValidationRequested(bool requested = true) { d_DNSSECValidationRequested = requested; } @@ -354,9 +366,9 @@ public: return d_DNSSECValidationRequested && !d_wasOutOfBand; } - void setWantsRPZ(bool state=true) + void setWantsRPZ(bool state = true) { - d_wantsRPZ=state; + d_wantsRPZ = state; } bool getWantsRPZ() const @@ -509,7 +521,7 @@ public: static int s_event_trace_enabled; static bool s_save_parent_ns_set; - std::unordered_map d_discardedPolicies; + std::unordered_map d_discardedPolicies; DNSFilterEngine::Policy d_appliedPolicy; std::unordered_set d_policyTags; boost::optional d_routingTag; @@ -541,45 +553,49 @@ private: struct GetBestNSAnswer { DNSName qname; - set > bestns; + set> bestns; uint8_t qtype; - bool operator<(const GetBestNSAnswer &b) const + bool operator<(const GetBestNSAnswer& b) const { - return std::tie(qtype, qname, bestns) < - std::tie(b.qtype, b.qname, b.bestns); + return std::tie(qtype, qname, bestns) < std::tie(b.qtype, b.qname, b.bestns); } }; - typedef std::map zonesStates_t; - enum StopAtDelegation { DontStop, Stop, Stopped }; + typedef std::map zonesStates_t; + enum StopAtDelegation + { + DontStop, + Stop, + Stopped + }; void resolveAdditionals(const DNSName& qname, QType qtype, AdditionalMode, std::vector& additionals, unsigned int depth, bool& pushed); - void addAdditionals(QType qtype, const vector&start, vector&addditionals, std::set>& uniqueCalls, std::set>& uniqueResults, unsigned int depth, unsigned int adddepth, bool& pushed); - bool addAdditionals(QType qtype, vector&ret, unsigned int depth); + void addAdditionals(QType qtype, const vector& start, vector& addditionals, std::set>& uniqueCalls, std::set>& uniqueResults, unsigned int depth, unsigned int adddepth, bool& pushed); + bool addAdditionals(QType qtype, vector& ret, unsigned int depth); bool doDoTtoAuth(const DNSName& ns) const; - int doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, const DNSName &qname, QType qtype, vector&ret, - unsigned int depth, set&beenthere, vState& state, StopAtDelegation* stopAtDelegation, + int doResolveAt(NsSet& nameservers, DNSName auth, bool flawedNSSet, const DNSName& qname, QType qtype, vector& ret, + unsigned int depth, set& beenthere, vState& state, StopAtDelegation* stopAtDelegation, std::map>* fallback); bool doResolveAtThisIP(const std::string& prefix, const DNSName& qname, const QType qtype, LWResult& lwr, boost::optional& ednsmask, const DNSName& auth, bool const sendRDQuery, const bool wasForwarded, const DNSName& nsName, const ComboAddress& remoteIP, bool doTCP, bool doDoT, bool& truncated, bool& spoofed, bool dontThrottle = false); - bool processAnswer(unsigned int depth, LWResult& lwr, const DNSName& qname, const QType qtype, DNSName& auth, bool wasForwarded, const boost::optional ednsmask, bool sendRDQuery, NsSet &nameservers, std::vector& ret, const DNSFilterEngine& dfe, bool* gotNewServers, int* rcode, vState& state, const ComboAddress& remoteIP); - - int doResolve(const DNSName &qname, QType qtype, vector&ret, unsigned int depth, set& beenthere, vState& state); - int doResolveNoQNameMinimization(const DNSName &qname, QType qtype, vector&ret, unsigned int depth, set& beenthere, vState& state, bool* fromCache = NULL, StopAtDelegation* stopAtDelegation = NULL, bool considerforwards = true); - bool doOOBResolve(const AuthDomain& domain, const DNSName &qname, QType qtype, vector&ret, int& res); - bool doOOBResolve(const DNSName &qname, QType qtype, vector&ret, unsigned int depth, int &res); - bool isRecursiveForwardOrAuth(const DNSName &qname) const; - bool isForwardOrAuth(const DNSName &qname) const; + bool processAnswer(unsigned int depth, LWResult& lwr, const DNSName& qname, const QType qtype, DNSName& auth, bool wasForwarded, const boost::optional ednsmask, bool sendRDQuery, NsSet& nameservers, std::vector& ret, const DNSFilterEngine& dfe, bool* gotNewServers, int* rcode, vState& state, const ComboAddress& remoteIP); + + int doResolve(const DNSName& qname, QType qtype, vector& ret, unsigned int depth, set& beenthere, vState& state); + int doResolveNoQNameMinimization(const DNSName& qname, QType qtype, vector& ret, unsigned int depth, set& beenthere, vState& state, bool* fromCache = NULL, StopAtDelegation* stopAtDelegation = NULL, bool considerforwards = true); + bool doOOBResolve(const AuthDomain& domain, const DNSName& qname, QType qtype, vector& ret, int& res); + bool doOOBResolve(const DNSName& qname, QType qtype, vector& ret, unsigned int depth, int& res); + bool isRecursiveForwardOrAuth(const DNSName& qname) const; + bool isForwardOrAuth(const DNSName& qname) const; domainmap_t::const_iterator getBestAuthZone(DNSName* qname) const; - bool doCNAMECacheCheck(const DNSName &qname, QType qtype, vector&ret, unsigned int depth, int &res, vState& state, bool wasAuthZone, bool wasForwardRecurse); - bool doCacheCheck(const DNSName &qname, const DNSName& authname, bool wasForwardedOrAuthZone, bool wasAuthZone, bool wasForwardRecurse, QType qtype, vector&ret, unsigned int depth, int &res, vState& state); - void getBestNSFromCache(const DNSName &qname, QType qtype, vector&bestns, bool* flawedNSSet, unsigned int depth, set& beenthere, const boost::optional& cutOffDomain = boost::none); - DNSName getBestNSNamesFromCache(const DNSName &qname, QType qtype, NsSet& nsset, bool* flawedNSSet, unsigned int depth, set&beenthere); + bool doCNAMECacheCheck(const DNSName& qname, QType qtype, vector& ret, unsigned int depth, int& res, vState& state, bool wasAuthZone, bool wasForwardRecurse); + bool doCacheCheck(const DNSName& qname, const DNSName& authname, bool wasForwardedOrAuthZone, bool wasAuthZone, bool wasForwardRecurse, QType qtype, vector& ret, unsigned int depth, int& res, vState& state); + void getBestNSFromCache(const DNSName& qname, QType qtype, vector& bestns, bool* flawedNSSet, unsigned int depth, set& beenthere, const boost::optional& cutOffDomain = boost::none); + DNSName getBestNSNamesFromCache(const DNSName& qname, QType qtype, NsSet& nsset, bool* flawedNSSet, unsigned int depth, set& beenthere); - inline vector> shuffleInSpeedOrder(NsSet &nameservers, const string &prefix); - inline vector shuffleForwardSpeed(const vector &rnameservers, const string &prefix, const bool wasRd); - bool moreSpecificThan(const DNSName& a, const DNSName &b) const; - vector getAddrs(const DNSName &qname, unsigned int depth, set& beenthere, bool cacheOnly, unsigned int& addressQueriesForNS); + inline vector> shuffleInSpeedOrder(NsSet& nameservers, const string& prefix); + inline vector shuffleForwardSpeed(const vector& rnameservers, const string& prefix, const bool wasRd); + bool moreSpecificThan(const DNSName& a, const DNSName& b) const; + vector getAddrs(const DNSName& qname, unsigned int depth, set& beenthere, bool cacheOnly, unsigned int& addressQueriesForNS); bool nameserversBlockedByRPZ(const DNSFilterEngine& dfe, const NsSet& nameservers); bool nameserverIPBlockedByRPZ(const DNSFilterEngine& dfe, const ComboAddress&); @@ -589,31 +605,31 @@ private: vector retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, vector>::const_iterator& tns, const unsigned int depth, set& beenthere, const vector>& rnameservers, NsSet& nameservers, bool& sendRDQuery, bool& pierceDontQuery, bool& flawedNSSet, bool cacheOnly, unsigned int& addressQueriesForNS); void sanitizeRecords(const std::string& prefix, LWResult& lwr, const DNSName& qname, const QType qtype, const DNSName& auth, bool wasForwarded, bool rdQuery); -/* This function will check whether the answer should have the AA bit set, and will set if it should be set and isn't. - This is unfortunately needed to deal with very crappy so-called DNS servers */ + /* This function will check whether the answer should have the AA bit set, and will set if it should be set and isn't. + This is unfortunately needed to deal with very crappy so-called DNS servers */ void fixupAnswer(const std::string& prefix, LWResult& lwr, const DNSName& qname, const QType qtype, const DNSName& auth, bool wasForwarded, bool rdQuery); void rememberParentSetIfNeeded(const DNSName& domain, const vector& newRecords, unsigned int depth); RCode::rcodes_ updateCacheFromRecords(unsigned int depth, LWResult& lwr, const DNSName& qname, const QType qtype, const DNSName& auth, bool wasForwarded, const boost::optional, vState& state, bool& needWildcardProof, bool& gatherWildcardProof, unsigned int& wildcardLabelsCount, bool sendRDQuery, const ComboAddress& remoteIP); bool processRecords(const std::string& prefix, const DNSName& qname, const QType qtype, const DNSName& auth, LWResult& lwr, const bool sendRDQuery, vector& ret, set& nsset, DNSName& newtarget, DNSName& newauth, bool& realreferral, bool& negindic, vState& state, const bool needWildcardProof, const bool gatherwildcardProof, const unsigned int wildcardLabelsCount, int& rcode, bool& negIndicHasSignatures, unsigned int depth); - bool doSpecialNamesResolve(const DNSName &qname, QType qtype, const QClass qclass, vector &ret); + bool doSpecialNamesResolve(const DNSName& qname, QType qtype, const QClass qclass, vector& ret); LWResult::Result asyncresolveWrapper(const ComboAddress& ip, bool ednsMANDATORY, const DNSName& domain, const DNSName& auth, int type, bool doTCP, bool sendRDQuery, struct timeval* now, boost::optional& srcmask, LWResult* res, bool* chained, const DNSName& nsName) const; - boost::optional getEDNSSubnetMask(const DNSName&dn, const ComboAddress& rem); + boost::optional getEDNSSubnetMask(const DNSName& dn, const ComboAddress& rem); bool validationEnabled() const; - uint32_t computeLowestTTD(const std::vector& records, const std::vector >& signatures, uint32_t signaturesTTL, const std::vector>& authorityRecs) const; + uint32_t computeLowestTTD(const std::vector& records, const std::vector>& signatures, uint32_t signaturesTTL, const std::vector>& authorityRecs) const; void updateValidationState(vState& state, const vState stateUpdate); - vState validateRecordsWithSigs(unsigned int depth, const DNSName& qname, const QType qtype, const DNSName& name, const QType type, const std::vector& records, const std::vector >& signatures); - vState validateDNSKeys(const DNSName& zone, const std::vector& dnskeys, const std::vector >& signatures, unsigned int depth); + vState validateRecordsWithSigs(unsigned int depth, const DNSName& qname, const QType qtype, const DNSName& name, const QType type, const std::vector& records, const std::vector>& signatures); + vState validateDNSKeys(const DNSName& zone, const std::vector& dnskeys, const std::vector>& signatures, unsigned int depth); vState getDNSKeys(const DNSName& signer, skeyset_t& keys, bool& servFailOccurred, unsigned int depth); dState getDenialValidationState(const NegCache::NegCacheEntry& ne, const dState expectedState, bool referralToUnsigned); void updateDenialValidationState(vState& neValidationState, const DNSName& neName, vState& state, const dState denialState, const dState expectedState, bool isDS, unsigned int depth); void computeNegCacheValidationStatus(const NegCache::NegCacheEntry& ne, const DNSName& qname, QType qtype, const int res, vState& state, unsigned int depth); vState getTA(const DNSName& zone, dsmap_t& ds); vState getValidationStatus(const DNSName& subdomain, bool wouldBeValid, bool typeIsDS, unsigned int depth); - void updateValidationStatusInCache(const DNSName &qname, QType qt, bool aa, vState newState) const; + void updateValidationStatusInCache(const DNSName& qname, QType qt, bool aa, vState newState) const; void initZoneCutsFromTA(const DNSName& from); void handleNewTarget(const std::string& prefix, const DNSName& qname, const DNSName& newtarget, QType qtype, std::vector& ret, int& rcode, int depth, const std::vector& recordsFromAnswer, vState& state); @@ -657,7 +673,7 @@ private: bool d_followCNAME{true}; bool d_refresh{false}; bool d_serveStale{false}; - + LogMode d_lm; }; @@ -665,7 +681,11 @@ private: LWResult::Result asendtcp(const PacketBuffer& data, shared_ptr&); LWResult::Result arecvtcp(PacketBuffer& data, size_t len, shared_ptr&, bool incompleteOkay); -enum TCPAction : uint8_t { DoingRead, DoingWrite }; +enum TCPAction : uint8_t +{ + DoingRead, + DoingWrite +}; struct PacketID { @@ -674,25 +694,25 @@ struct PacketID remote.reset(); } - ComboAddress remote; // this is the remote - DNSName domain; // this is the question + ComboAddress remote; // this is the remote + DNSName domain; // this is the question PacketBuffer inMSG; // they'll go here PacketBuffer outMSG; // the outgoing message that needs to be sent - typedef set chain_t; + typedef set chain_t; mutable chain_t chain; shared_ptr tcphandler{nullptr}; - string::size_type inPos{0}; // how far are we along in the inMSG + string::size_type inPos{0}; // how far are we along in the inMSG size_t inWanted{0}; // if this is set, we'll read until inWanted bytes are read - string::size_type outPos{0}; // how far we are along in the outMSG + string::size_type outPos{0}; // how far we are along in the outMSG mutable uint32_t nearMisses{0}; // number of near misses - host correct, id wrong int fd{-1}; - int tcpsock{0}; // or wait for an event on a TCP fd + int tcpsock{0}; // or wait for an event on a TCP fd mutable bool closed{false}; // Processing already started, don't accept new chained ids bool inIncompleteOkay{false}; - uint16_t id{0}; // wait for a specific id/remote pair - uint16_t type{0}; // and this is its type + uint16_t id{0}; // wait for a specific id/remote pair + uint16_t type{0}; // and this is its type TCPAction highState{TCPAction::DoingRead}; IOState lowState{IOState::NeedRead}; @@ -703,13 +723,12 @@ struct PacketID } }; -inline ostream& operator<<(ostream & os, const PacketID& pid) +inline ostream& operator<<(ostream& os, const PacketID& pid) { - return os << "PacketID(id=" << pid.id << ",remote=" << pid.remote.toString() << ",type=" << pid.type << ",tcpsock=" << - pid.tcpsock << ",fd=" << pid.fd << ',' << pid.domain << ')'; + return os << "PacketID(id=" << pid.id << ",remote=" << pid.remote.toString() << ",type=" << pid.type << ",tcpsock=" << pid.tcpsock << ",fd=" << pid.fd << ',' << pid.domain << ')'; } -inline ostream& operator<<(ostream & os, const shared_ptr& pid) +inline ostream& operator<<(ostream& os, const shared_ptr& pid) { return os << *pid; } @@ -756,9 +775,9 @@ struct RecursorStats { time_t startupTime{time(nullptr)}; // XXX Convert counter below to be part of rec::Counters - std::map dnssecResults; - std::map xdnssecResults; - std::map policyResults; + std::map dnssecResults; + std::map xdnssecResults; + std::map policyResults; LockGuarded> policyHits; }; @@ -790,13 +809,21 @@ public: size_t queriesCount{0}; size_t proxyProtocolGot{0}; ssize_t proxyProtocolNeed{0}; - enum stateenum {PROXYPROTOCOLHEADER, BYTE0, BYTE1, GETQUESTION, DONE} state{BYTE0}; + enum stateenum + { + PROXYPROTOCOLHEADER, + BYTE0, + BYTE1, + GETQUESTION, + DONE + } state{BYTE0}; uint16_t qlen{0}; uint16_t bytesread{0}; uint16_t d_requestsInFlight{0}; // number of mthreads spawned for this connection // The max number of concurrent TCP requests we're willing to process static uint16_t s_maxInFlight; static unsigned int getCurrentConnections() { return s_currentConnections; } + private: const int d_fd; static std::atomic s_currentConnections; //!< total number of current TCP connections @@ -806,7 +833,8 @@ private: class ImmediateServFailException { public: - ImmediateServFailException(string r) : reason(r) {}; + ImmediateServFailException(string r) : + reason(r){}; string reason; //! Print this to tell the user what went wrong }; @@ -826,7 +854,7 @@ class SendTruncatedAnswerException typedef boost::circular_buffer addrringbuf_t; extern thread_local std::unique_ptr t_servfailremotes, t_largeanswerremotes, t_remotes, t_bogusremotes, t_timeouts; -extern thread_local std::unique_ptr > > t_queryring, t_servfailqueryring, t_bogusqueryring; +extern thread_local std::unique_ptr>> t_queryring, t_servfailqueryring, t_bogusqueryring; extern thread_local std::shared_ptr t_allowFrom; extern thread_local std::shared_ptr t_allowNotifyFrom; string doTraceRegex(vector::const_iterator begin, vector::const_iterator end); @@ -836,7 +864,6 @@ extern uint16_t g_outgoingEDNSBufsize; extern std::atomic g_maxCacheEntries, g_maxPacketCacheEntries; extern bool g_lowercaseOutgoing; - std::string reloadZoneConfiguration(); typedef std::function pipefunc_t; void broadcastFunction(const pipefunc_t& func); @@ -848,7 +875,8 @@ int followCNAMERecords(std::vector& ret, const QType qtype, int oldre int getFakeAAAARecords(const DNSName& qname, ComboAddress prefix, vector& ret); int getFakePTRRecords(const DNSName& qname, vector& ret); -template T broadcastAccFunction(const std::function& func); +template +T broadcastAccFunction(const std::function& func); typedef std::unordered_set notifyset_t; std::tuple, std::shared_ptr> parseZoneConfiguration(); -- 2.47.2