From: Otto Moerbeek Date: Mon, 7 Feb 2022 11:38:33 +0000 (+0100) Subject: Initial version, showing some working functionality X-Git-Tag: rec-4.7.0-alpha1~8^2~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d1667072dc141555c5c86972bea5400a15d8e039;p=thirdparty%2Fpdns.git Initial version, showing some working functionality --- diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 9aad7e01ee..66802f84cf 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -1268,7 +1268,7 @@ void startDoResolve(void* p) bool needCommit = false; for (auto i = ret.cbegin(); i != ret.cend(); ++i) { - if (!DNSSECOK && (i->d_type == QType::NSEC3 || ((i->d_type == QType::RRSIG || i->d_type == QType::NSEC) && ((dc->d_mdp.d_qtype != i->d_type && dc->d_mdp.d_qtype != QType::ANY) || i->d_place != DNSResourceRecord::ANSWER)))) { + if (!DNSSECOK && (i->d_type == QType::NSEC3 || ((i->d_type == QType::RRSIG || i->d_type == QType::NSEC) && ((dc->d_mdp.d_qtype != i->d_type && dc->d_mdp.d_qtype != QType::ANY) || (i->d_place != DNSResourceRecord::ANSWER && i->d_place != DNSResourceRecord::ADDITIONAL))))) { continue; } diff --git a/pdns/syncres.cc b/pdns/syncres.cc index b61f183029..af82a278cd 100644 --- a/pdns/syncres.cc +++ b/pdns/syncres.cc @@ -140,6 +140,35 @@ SyncRes::SyncRes(const struct timeval& now) : d_authzonequeries(0), d_outquerie { } +static bool allowAdditionalEntry(std::unordered_set& allowedAdditionals, const DNSRecord& rec); + +void SyncRes::getAdditionals(const DNSName& qname, QType qtype, bool requireAuth, std::set& additionals, unsigned int depth) +{ + vector addRecords; + + vState state = vState::Indeterminate; + if (requireAuth) { + 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) { + return; + } + } + if (vStateIsBogus(state)) { + return; + } + for (const auto& rec : addRecords) { + if (rec.d_place == DNSResourceRecord::ANSWER) { + additionals.insert(rec); + } + } +} + /** 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) { @@ -189,6 +218,40 @@ 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, {{}, false}}, + {QType::HTTPS, {{}, false}}, + {QType::NAPTR, {{}, false}} + }; + + const auto it = additionalTypes.find(qtype); + if (it != additionalTypes.end()) { + std::unordered_set addnames; + for (const auto& rec : ret) { + if (rec.d_place == DNSResourceRecord::ANSWER) { + allowAdditionalEntry(addnames, rec); + } + } + std::set additionals; + bool requireAuth = 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); + } + } + for (auto rec : additionals) { + rec.d_place = DNSResourceRecord::ADDITIONAL; + rec.d_ttl -= d_now.tv_sec; + ret.push_back(rec); + } + } d_eventTrace.add(RecEventTrace::SyncRes, res, false); return res; } @@ -3068,6 +3131,10 @@ static bool allowAdditionalEntry(std::unordered_set& allowedAdditionals } return true; } + // Record ttypes below are candidates for this + case QType::SVCB: + case QType::HTTPS: + case QType::NAPTR: default: return false; } diff --git a/pdns/syncres.hh b/pdns/syncres.hh index 3537bd0e70..93d8a5b6d2 100644 --- a/pdns/syncres.hh +++ b/pdns/syncres.hh @@ -598,6 +598,7 @@ public: explicit SyncRes(const struct timeval& now); + void getAdditionals(const DNSName& qname, QType qtype, bool requireAuth, 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)