From: Otto Moerbeek Date: Mon, 7 Feb 2022 13:53:26 +0000 (+0100) Subject: Basic NAPTR handling plys different modes: Ignore, CacheOnly, CacheOnlyRequireAuth... X-Git-Tag: rec-4.7.0-alpha1~8^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dcc074fb54b9f3d7483eba48c41f5d85be1da002;p=thirdparty%2Fpdns.git Basic NAPTR handling plys different modes: Ignore, CacheOnly, CacheOnlyRequireAuth, ResolveImmediately, ResolveDeferred --- diff --git a/pdns/dnsrecords.hh b/pdns/dnsrecords.hh index 7d5b2272bd..3d1e348011 100644 --- a/pdns/dnsrecords.hh +++ b/pdns/dnsrecords.hh @@ -51,6 +51,14 @@ public: includeboilerplate(NAPTR) template void xfrRecordContent(Convertor& conv); + string getFlags() const + { + return d_flags; + } + DNSName getReplacement() const + { + return d_replacement; + } private: uint16_t d_order, d_preference; string d_flags, d_services, d_regexp; diff --git a/pdns/syncres.cc b/pdns/syncres.cc index 1f0b3ae5fc..0ea779c416 100644 --- a/pdns/syncres.cc +++ b/pdns/syncres.cc @@ -140,32 +140,62 @@ SyncRes::SyncRes(const struct timeval& now) : d_authzonequeries(0), d_outquerie { } -static bool allowAdditionalEntry(std::unordered_set& allowedAdditionals, const DNSRecord& rec); +static void allowAdditionalEntry(std::unordered_set& allowedAdditionals, const DNSRecord& rec); + +static const std::map, SyncRes::AddtionalMode>> additionalTypes = { + {QType::MX, {{QType::A, QType::AAAA}, SyncRes::AddtionalMode::CacheOnlyRequireAuth}}, + {QType::SRV, {{QType::A, QType::AAAA}, SyncRes::AddtionalMode::ResolveImmediately}}, + {QType::SVCB, {{QType::A, QType::AAAA}, SyncRes::AddtionalMode::CacheOnly}}, + {QType::HTTPS, {{QType::A, QType::AAAA}, SyncRes::AddtionalMode::CacheOnly}}, + {QType::NAPTR, {{QType::A, QType::AAAA, QType::SRV}, SyncRes::AddtionalMode::ResolveImmediately}} +}; -void SyncRes::getAdditionals(const DNSName& qname, QType qtype, bool requireAuth, std::set& additionals, unsigned int depth) +void SyncRes::getAdditionals(const DNSName& qname, QType qtype, AddtionalMode mode, std::set& additionals, unsigned int depth) { vector addRecords; vState state = vState::Indeterminate; - if (requireAuth) { + switch (mode) { + case AddtionalMode::ResolveImmediately: { set lbeenthere; int res = doResolve(qname, qtype, addRecords, depth, lbeenthere, state); if (res != 0) { return; } - } else { - // Peek into cache for non-auth data - if (g_recCache->get(d_now.tv_sec, qname, qtype, false, &addRecords, d_cacheRemote, false, d_routingTag, nullptr, nullptr, nullptr, &state) <= 0) { + if (vStateIsBogus(state)) { return; } + for (auto rec : addRecords) { + if (rec.d_place == DNSResourceRecord::ANSWER) { + rec.d_place = DNSResourceRecord::ADDITIONAL; + additionals.insert(rec); + } + } + break; } - if (vStateIsBogus(state)) { - return; - } - for (const auto& rec : addRecords) { - if (rec.d_place == DNSResourceRecord::ANSWER) { - additionals.insert(rec); + case AddtionalMode::CacheOnly: + case AddtionalMode::CacheOnlyRequireAuth: { + // Peek into cache + if (g_recCache->get(d_now.tv_sec, qname, qtype, mode == AddtionalMode::CacheOnlyRequireAuth, &addRecords, d_cacheRemote, false, d_routingTag, nullptr, nullptr, nullptr, &state) <= 0) { + return; } + if (vStateIsBogus(state)) { + return; + } + for (auto rec : addRecords) { + if (rec.d_place == DNSResourceRecord::ANSWER) { + rec.d_place = DNSResourceRecord::ADDITIONAL; + rec.d_ttl -= d_now.tv_sec ; + additionals.insert(rec); + } + } + break; + } + case AddtionalMode::ResolveDeferred: + // Not yet implemented + break; + case AddtionalMode::Ignore: + break; } } @@ -218,15 +248,6 @@ int SyncRes::beginResolve(const DNSName &qname, const QType qtype, QClass qclass } } - const std::map, bool>> additionalTypes = { - {QType::MX, {{QType::A, QType::AAAA}, false}}, - //{QType::NS, {{QType::A, QType::AAAA}, false}}, - {QType::SRV, {{QType::A, QType::AAAA}, false}}, - {QType::SVCB, {{QType::A, QType::AAAA}, false}}, - {QType::HTTPS, {{QType::A, QType::AAAA}, false}}, - {QType::NAPTR, {{}, false}} - }; - const auto it = additionalTypes.find(qtype); if (it != additionalTypes.end()) { std::unordered_set addnames; @@ -236,19 +257,17 @@ int SyncRes::beginResolve(const DNSName &qname, const QType qtype, QClass qclass } } std::set additionals; - bool requireAuth = it->second.second; + auto mode = it->second.second; for (const auto& targettype : it->second.first) { for (const auto& addname : addnames) { vector addRecords; if ((targettype == QType::A && !s_doIPv4) || (targettype == QType::AAAA && !s_doIPv6)) { continue; } - getAdditionals(addname, targettype, requireAuth, additionals, depth); + getAdditionals(addname, targettype, mode, additionals, depth); } } - for (auto rec : additionals) { - rec.d_place = DNSResourceRecord::ADDITIONAL; - rec.d_ttl -= d_now.tv_sec; + for (const auto& rec : additionals) { ret.push_back(rec); } } @@ -3107,30 +3126,24 @@ void SyncRes::fixupAnswer(const std::string& prefix, LWResult& lwr, const DNSNam } } -static bool allowAdditionalEntry(std::unordered_set& allowedAdditionals, const DNSRecord& rec) +static void allowAdditionalEntry(std::unordered_set& allowedAdditionals, const DNSRecord& rec) { switch(rec.d_type) { case QType::MX: - { if (auto mxContent = getRR(rec)) { allowedAdditionals.insert(mxContent->d_mxname); } - return true; - } + break; case QType::NS: - { if (auto nsContent = getRR(rec)) { allowedAdditionals.insert(nsContent->getNS()); } - return true; - } + break; case QType::SRV: - { if (auto srvContent = getRR(rec)) { allowedAdditionals.insert(srvContent->d_target); } - return true; - } + break; case QType::SVCB: /* fall-through */ case QType::HTTPS: if (auto svcbContent = getRR(rec)) { @@ -3140,18 +3153,23 @@ static bool allowAdditionalEntry(std::unordered_set& allowedAdditionals target = rec.d_name; } allowedAdditionals.insert(target); - return true; } else { // Alias mode not implemented yet - return false; } } break; case QType::NAPTR: - // To be done + if (auto naptrContent = getRR(rec)) { + auto flags = naptrContent->getFlags(); + toLowerInPlace(flags); + if (flags.find('a') || flags.find('s')) { + allowedAdditionals.insert(naptrContent->getReplacement()); + } + } + break; default: - return false; + break; } } diff --git a/pdns/syncres.hh b/pdns/syncres.hh index 93d8a5b6d2..1cb0b9d5f8 100644 --- a/pdns/syncres.hh +++ b/pdns/syncres.hh @@ -598,7 +598,15 @@ public: explicit SyncRes(const struct timeval& now); - void getAdditionals(const DNSName& qname, QType qtype, bool requireAuth, std::set& additionals, unsigned int depth); + enum class AddtionalMode : uint8_t { + Ignore, + CacheOnly, + CacheOnlyRequireAuth, + ResolveImmediately, + ResolveDeferred + }; + + void getAdditionals(const DNSName& qname, QType qtype, AddtionalMode, std::set& additionals, unsigned int depth); int beginResolve(const DNSName &qname, QType qtype, QClass qclass, vector&ret, unsigned int depth = 0); void setId(int id)