for (int loop = 0; loop < iterations; loop++) {
// First try a regular resolve
- const bool serveStale = loop == 1;
+ d_serveStale = loop == 1;
// When we're not on the last iteration, a timeout is not fatal
const bool exceptionOnTimeout = loop == iterations - 1;
/* When we are looking for a DS, we want to the non-CNAME cache check first
because we can actually have a DS (from the parent zone) AND a CNAME (from
the child zone), and what we really want is the DS */
- if (qtype != QType::DS && doCNAMECacheCheck(qname, qtype, ret, depth, res, state, wasAuthZone, wasForwardRecurse, serveStale)) { // will reroute us if needed
+ if (qtype != QType::DS && doCNAMECacheCheck(qname, qtype, ret, depth, res, state, wasAuthZone, wasForwardRecurse)) { // will reroute us if needed
d_wasOutOfBand = wasAuthZone;
// Here we have an issue. If we were prevented from going out to the network (cache-only was set, possibly because we
// are in QM Step0) we might have a CNAME but not the corresponding target.
return res;
}
- if (doCacheCheck(qname, authname, wasForwardedOrAuthZone, wasAuthZone, wasForwardRecurse, qtype, ret, depth, res, state, serveStale)) {
+ if (doCacheCheck(qname, authname, wasForwardedOrAuthZone, wasAuthZone, wasForwardRecurse, qtype, ret, depth, res, state)) {
// we done
d_wasOutOfBand = wasAuthZone;
if (fromCache) {
}
/* if we have not found a cached DS (or denial of), now is the time to look for a CNAME */
- if (qtype == QType::DS && doCNAMECacheCheck(qname, qtype, ret, depth, res, state, wasAuthZone, wasForwardRecurse, serveStale)) { // will reroute us if needed
+ if (qtype == QType::DS && doCNAMECacheCheck(qname, qtype, ret, depth, res, state, wasAuthZone, wasForwardRecurse)) { // will reroute us if needed
d_wasOutOfBand = wasAuthZone;
// Here we have an issue. If we were prevented from going out to the network (cache-only was set, possibly because we
// are in QM Step0) we might have a CNAME but not the corresponding target.
subdomain=getBestNSNamesFromCache(subdomain, qtype, nsset, &flawedNSSet, depth, beenthere); // pass beenthere to both occasions
}
- res = doResolveAt(nsset, subdomain, flawedNSSet, qname, qtype, ret, depth, beenthere, state, stopAtDelegation, nullptr, serveStale);
+ res = doResolveAt(nsset, subdomain, flawedNSSet, qname, qtype, ret, depth, beenthere, state, stopAtDelegation, nullptr);
if (res == -1 && s_save_parent_ns_set) {
// It did not work out, lets check if we have a saved parent NS set
}
if (fallBack.size() > 0) {
LOG(prefix<<qname<<": Failure, but we have a saved parent NS set, trying that one"<< endl)
- res = doResolveAt(nsset, subdomain, flawedNSSet, qname, qtype, ret, depth, beenthere, state, stopAtDelegation, &fallBack, serveStale);
+ res = doResolveAt(nsset, subdomain, flawedNSSet, qname, qtype, ret, depth, beenthere, state, stopAtDelegation, &fallBack);
if (res == 0) {
// It did work out
s_savedParentNSSet.lock()->inc(subdomain);
/** This function explicitly goes out for A or AAAA addresses
*/
-vector<ComboAddress> SyncRes::getAddrs(const DNSName &qname, unsigned int depth, set<GetBestNSAnswer>& beenthere, bool cacheOnly, unsigned int& addressQueriesForNS, bool serveStale)
+vector<ComboAddress> SyncRes::getAddrs(const DNSName &qname, unsigned int depth, set<GetBestNSAnswer>& beenthere, bool cacheOnly, unsigned int& addressQueriesForNS)
{
typedef vector<DNSRecord> res_t;
typedef vector<ComboAddress> ret_t;
d_followCNAME = true;
MemRecursorCache::Flags flags = MemRecursorCache::None;
- if (serveStale) {
+ if (d_serveStale) {
flags |= MemRecursorCache::ServeStale;
}
try {
}
bestns.clear();
bool brokeloop;
+ MemRecursorCache::Flags flags = MemRecursorCache::None;
+ if (d_serveStale) {
+ flags |= MemRecursorCache::ServeStale;
+ }
do {
if (cutOffDomain && (subdomain == *cutOffDomain || !subdomain.isPartOf(*cutOffDomain))) {
break;
vector<DNSRecord> ns;
*flawedNSSet = false;
- if(g_recCache->get(d_now.tv_sec, subdomain, QType::NS, MemRecursorCache::None, &ns, d_cacheRemote, d_routingTag) > 0) {
+ if (g_recCache->get(d_now.tv_sec, subdomain, QType::NS, flags, &ns, d_cacheRemote, d_routingTag) > 0) {
if (s_maxnsperresolve > 0 && ns.size() > s_maxnsperresolve) {
vector<DNSRecord> selected;
selected.reserve(s_maxnsperresolve);
return false;
}
-bool SyncRes::doCNAMECacheCheck(const DNSName &qname, const QType qtype, vector<DNSRecord>& ret, unsigned int depth, int &res, vState& state, bool wasAuthZone, bool wasForwardRecurse, bool serveStale)
+bool SyncRes::doCNAMECacheCheck(const DNSName &qname, const QType qtype, vector<DNSRecord>& ret, unsigned int depth, int &res, vState& state, bool wasAuthZone, bool wasForwardRecurse)
{
string prefix;
if(doLog()) {
if (d_refresh) {
flags |= MemRecursorCache::Refresh;
}
- if (serveStale) {
+ if (d_serveStale) {
flags |= MemRecursorCache::ServeStale;
}
if (g_recCache->get(d_now.tv_sec, qname, QType::CNAME, flags, &cset, d_cacheRemote, d_routingTag, d_doDNSSEC ? &signatures : nullptr, d_doDNSSEC ? &authorityRecs : nullptr, &d_wasVariable, &state, &wasAuth, &authZone, &d_fromAuthIP) > 0) {
}
}
-bool SyncRes::doCacheCheck(const DNSName &qname, const DNSName& authname, bool wasForwardedOrAuthZone, bool wasAuthZone, bool wasForwardRecurse, QType qtype, vector<DNSRecord>&ret, unsigned int depth, int &res, vState& state, bool serveStale)
+bool SyncRes::doCacheCheck(const DNSName &qname, const DNSName& authname, bool wasForwardedOrAuthZone, bool wasAuthZone, bool wasForwardRecurse, QType qtype, vector<DNSRecord>&ret, unsigned int depth, int &res, vState& state)
{
bool giveNegative=false;
if (d_refresh) {
flags |= MemRecursorCache::Refresh;
}
- if (serveStale) {
+ if (d_serveStale) {
flags |= MemRecursorCache::ServeStale;
}
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) {
return false;
}
-vector<ComboAddress> SyncRes::retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, std::vector<std::pair<DNSName, float>>::const_iterator& tns, const unsigned int depth, set<GetBestNSAnswer>& beenthere, const vector<std::pair<DNSName, float>>& rnameservers, NsSet& nameservers, bool& sendRDQuery, bool& pierceDontQuery, bool& flawedNSSet, bool cacheOnly, unsigned int &nretrieveAddressesForNS, bool serveStale)
+vector<ComboAddress> SyncRes::retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, std::vector<std::pair<DNSName, float>>::const_iterator& tns, const unsigned int depth, set<GetBestNSAnswer>& beenthere, const vector<std::pair<DNSName, float>>& rnameservers, NsSet& nameservers, bool& sendRDQuery, bool& pierceDontQuery, bool& flawedNSSet, bool cacheOnly, unsigned int &nretrieveAddressesForNS)
{
vector<ComboAddress> result;
LOG(prefix<<qname<<": Trying to resolve NS '"<<tns->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, serveStale);
+ result = getAddrs(tns->first, depth, beenthere, cacheOnly, nretrieveAddressesForNS);
}
// Other exceptions should likely not throttle...
catch (const ImmediateServFailException& ex) {
const DNSName& name = content->getNS();
set<GetBestNSAnswer> beenthereIgnored;
unsigned int nretrieveAddressesForNSIgnored;
- auto addresses = getAddrs(name, depth, beenthereIgnored, true, nretrieveAddressesForNSIgnored, false);
+ auto addresses = getAddrs(name, depth, beenthereIgnored, true, nretrieveAddressesForNSIgnored);
entries.emplace(name, addresses);
}
s_savedParentNSSet.lock()->emplace(domain, std::move(entries), d_now.tv_sec + ttl);
int SyncRes::doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, const DNSName &qname, const QType qtype,
vector<DNSRecord>&ret,
unsigned int depth, set<GetBestNSAnswer>&beenthere, vState& state, StopAtDelegation* stopAtDelegation,
- map<DNSName, vector<ComboAddress>>* fallBack, bool serveStale)
+ map<DNSName, vector<ComboAddress>>* fallBack)
{
auto luaconfsLocal = g_luaconfs.getLocal();
string prefix;
}
}
if (remoteIPs.size() == 0) {
- remoteIPs = retrieveAddressesForNS(prefix, qname, tns, depth, beenthere, rnameservers, nameservers, sendRDQuery, pierceDontQuery, flawedNSSet, cacheOnly, addressQueriesForNS, serveStale);
+ remoteIPs = retrieveAddressesForNS(prefix, qname, tns, depth, beenthere, rnameservers, nameservers, sendRDQuery, pierceDontQuery, flawedNSSet, cacheOnly, addressQueriesForNS);
}
if(remoteIPs.empty()) {
bool doDoTtoAuth(const DNSName& ns) const;
int doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, const DNSName &qname, QType qtype, vector<DNSRecord>&ret,
unsigned int depth, set<GetBestNSAnswer>&beenthere, vState& state, StopAtDelegation* stopAtDelegation,
- std::map<DNSName, std::vector<ComboAddress>>* fallback, bool serveStale);
+ std::map<DNSName, std::vector<ComboAddress>>* fallback);
bool doResolveAtThisIP(const std::string& prefix, const DNSName& qname, const QType qtype, LWResult& lwr, boost::optional<Netmask>& 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<Netmask> ednsmask, bool sendRDQuery, NsSet &nameservers, std::vector<DNSRecord>& ret, const DNSFilterEngine& dfe, bool* gotNewServers, int* rcode, vState& state, const ComboAddress& remoteIP);
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<DNSRecord>&ret, unsigned int depth, int &res, vState& state, bool wasAuthZone, bool wasForwardRecurse, bool serveStale);
- bool doCacheCheck(const DNSName &qname, const DNSName& authname, bool wasForwardedOrAuthZone, bool wasAuthZone, bool wasForwardRecurse, QType qtype, vector<DNSRecord>&ret, unsigned int depth, int &res, vState& state, bool serveStale);
+ bool doCNAMECacheCheck(const DNSName &qname, QType qtype, vector<DNSRecord>&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<DNSRecord>&ret, unsigned int depth, int &res, vState& state);
void getBestNSFromCache(const DNSName &qname, QType qtype, vector<DNSRecord>&bestns, bool* flawedNSSet, unsigned int depth, set<GetBestNSAnswer>& beenthere, const boost::optional<DNSName>& cutOffDomain = boost::none);
DNSName getBestNSNamesFromCache(const DNSName &qname, QType qtype, NsSet& nsset, bool* flawedNSSet, unsigned int depth, set<GetBestNSAnswer>&beenthere);
inline vector<std::pair<DNSName, float>> shuffleInSpeedOrder(NsSet &nameservers, const string &prefix);
inline vector<ComboAddress> shuffleForwardSpeed(const vector<ComboAddress> &rnameservers, const string &prefix, const bool wasRd);
bool moreSpecificThan(const DNSName& a, const DNSName &b) const;
- vector<ComboAddress> getAddrs(const DNSName &qname, unsigned int depth, set<GetBestNSAnswer>& beenthere, bool cacheOnly, unsigned int& addressQueriesForNS, bool serveStale);
+ vector<ComboAddress> getAddrs(const DNSName &qname, unsigned int depth, set<GetBestNSAnswer>& beenthere, bool cacheOnly, unsigned int& addressQueriesForNS);
bool nameserversBlockedByRPZ(const DNSFilterEngine& dfe, const NsSet& nameservers);
bool nameserverIPBlockedByRPZ(const DNSFilterEngine& dfe, const ComboAddress&);
void checkMaxQperQ(const DNSName& qname) const;
bool throttledOrBlocked(const std::string& prefix, const ComboAddress& remoteIP, const DNSName& qname, QType qtype, bool pierceDontQuery);
- vector<ComboAddress> retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, vector<std::pair<DNSName, float>>::const_iterator& tns, const unsigned int depth, set<GetBestNSAnswer>& beenthere, const vector<std::pair<DNSName, float>>& rnameservers, NsSet& nameservers, bool& sendRDQuery, bool& pierceDontQuery, bool& flawedNSSet, bool cacheOnly, unsigned int& addressQueriesForNS, bool serveStale);
+ vector<ComboAddress> retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, vector<std::pair<DNSName, float>>::const_iterator& tns, const unsigned int depth, set<GetBestNSAnswer>& beenthere, const vector<std::pair<DNSName, float>>& 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.
bool d_queryReceivedOverTCP{false};
bool d_followCNAME{true};
bool d_refresh{false};
-
+ bool d_serveStale{false};
+
LogMode d_lm;
};