bool auth = isRRSetAuth(qname, qtype);
// Same decision as updateCacheFromRecords() (we do not test for NSEC since we skip those completely)
if (auth || (qtype == QType::NS || qtype == QType::A || qtype == QType::AAAA || qtype == QType::DS)) {
- g_recCache->replace(d_now, qname, qtype, v, sigsrr, nullptr,
+ g_recCache->replace(d_now, qname, qtype, v, sigsrr, {},
auth, d_zone);
}
break;
uint16_t MemRecursorCache::s_maxRRSetSize = 256;
bool MemRecursorCache::s_limitQTypeAny = true;
+const MemRecursorCache::AuthRecs MemRecursorCache::s_emptyAuthRecs = std::make_shared<MemRecursorCache::AuthRecsVec>();
+
void MemRecursorCache::resetStaticsForTests()
{
s_maxServedStaleExtensions = 0;
}
}
-time_t MemRecursorCache::handleHit(time_t now, MapCombo::LockedContent& content, MemRecursorCache::OrderedTagIterator_t& entry, const DNSName& qname, uint32_t& origTTL, vector<DNSRecord>* res, vector<std::shared_ptr<const RRSIGRecordContent>>* signatures, std::shared_ptr<std::vector<DNSRecord>>* authorityRecs, bool* variable, boost::optional<vState>& state, bool* wasAuth, DNSName* fromAuthZone, ComboAddress* fromAuthIP)
+time_t MemRecursorCache::handleHit(time_t now, MapCombo::LockedContent& content, MemRecursorCache::OrderedTagIterator_t& entry, const DNSName& qname, uint32_t& origTTL, vector<DNSRecord>* res, vector<std::shared_ptr<const RRSIGRecordContent>>* signatures, AuthRecs* authorityRecs, bool* variable, boost::optional<vState>& state, bool* wasAuth, DNSName* fromAuthZone, ComboAddress* fromAuthIP)
{
// MUTEX SHOULD BE ACQUIRED (as indicated by the reference to the content which is protected by a lock)
if (entry->d_tooBig) {
}
if (authorityRecs != nullptr) {
- *authorityRecs = entry->d_authorityRecs ? entry->d_authorityRecs : std::make_shared<vector<DNSRecord>>();
+ *authorityRecs = entry->d_authorityRecs ? entry->d_authorityRecs : s_emptyAuthRecs;
}
updateDNSSECValidationStateFromCache(state, entry->d_state);
}
// returns -1 for no hits
-time_t MemRecursorCache::get(time_t now, const DNSName& qname, const QType qtype, Flags flags, vector<DNSRecord>* res, const ComboAddress& who, const OptTag& routingTag, vector<std::shared_ptr<const RRSIGRecordContent>>* signatures, std::shared_ptr<std::vector<DNSRecord>>* authorityRecs, bool* variable, vState* state, bool* wasAuth, DNSName* fromAuthZone, ComboAddress* fromAuthIP) // NOLINT(readability-function-cognitive-complexity)
+time_t MemRecursorCache::get(time_t now, const DNSName& qname, const QType qtype, Flags flags, vector<DNSRecord>* res, const ComboAddress& who, const OptTag& routingTag, vector<std::shared_ptr<const RRSIGRecordContent>>* signatures, AuthRecs* authorityRecs, bool* variable, vState* state, bool* wasAuth, DNSName* fromAuthZone, ComboAddress* fromAuthIP) // NOLINT(readability-function-cognitive-complexity)
{
bool requireAuth = (flags & RequireAuth) != 0;
bool refresh = (flags & Refresh) != 0;
return false;
}
-void MemRecursorCache::replace(time_t now, const DNSName& qname, const QType qtype, const vector<DNSRecord>& content, const vector<shared_ptr<const RRSIGRecordContent>>& signatures, const std::shared_ptr<std::vector<DNSRecord>>& authorityRecs, bool auth, const DNSName& authZone, boost::optional<Netmask> ednsmask, const OptTag& routingTag, vState state, boost::optional<ComboAddress> from, bool refresh, time_t ttl_time)
+void MemRecursorCache::replace(time_t now, const DNSName& qname, const QType qtype, const vector<DNSRecord>& content, const vector<shared_ptr<const RRSIGRecordContent>>& signatures, const AuthRecsVec& authorityRecs, bool auth, const DNSName& authZone, boost::optional<Netmask> ednsmask, const OptTag& routingTag, vState state, boost::optional<ComboAddress> from, bool refresh, time_t ttl_time)
{
auto& shard = getMap(qname);
auto lockedShard = shard.lock();
}
cacheEntry.d_signatures = signatures;
- if (authorityRecs && !authorityRecs->empty()) {
- cacheEntry.d_authorityRecs = authorityRecs;
+ if (!authorityRecs.empty()) {
+ cacheEntry.d_authorityRecs = std::make_shared<const AuthRecsVec>(authorityRecs);
}
else {
cacheEntry.d_authorityRecs = nullptr;
return count;
}
-static void putAuthRecord(protozero::pbf_message<PBCacheEntry>& message, const DNSName& qname, std::shared_ptr<std::vector<DNSRecord>>& authRecs)
+static void putAuthRecord(protozero::pbf_message<PBCacheEntry>& message, const DNSName& qname, std::vector<DNSRecord>& authRecs)
{
protozero::pbf_message<PBAuthRecord> auth = message.get_message();
DNSRecord authRecord;
break;
}
}
- authRecs->emplace_back(authRecord);
+ authRecs.emplace_back(authRecord);
}
template <typename T>
bool MemRecursorCache::putRecordSet(T& message)
{
+ std::vector<DNSRecord> authRecs;
CacheEntry cacheEntry{{g_rootdnsname, QType::A, boost::none, Netmask()}, false};
while (message.next()) {
switch (message.tag()) {
if (!cacheEntry.d_authorityRecs) {
cacheEntry.d_authorityRecs = std::make_shared<std::vector<DNSRecord>>();
}
- putAuthRecord(message, cacheEntry.d_qname, cacheEntry.d_authorityRecs);
+ putAuthRecord(message, cacheEntry.d_qname, authRecs);
break;
case PBCacheEntry::required_bytes_name:
cacheEntry.d_qname = DNSName(message.get_bytes());
break;
}
}
+ if (!authRecs.empty()) {
+ cacheEntry.d_authorityRecs = std::make_shared<const std::vector<DNSRecord>>(authRecs);
+ }
return replace(std::move(cacheEntry));
}
static constexpr Flags Refresh = 1 << 1;
static constexpr Flags ServeStale = 1 << 2;
- [[nodiscard]] time_t get(time_t, const DNSName& qname, QType qtype, Flags flags, vector<DNSRecord>* res, const ComboAddress& who, const OptTag& routingTag = boost::none, vector<std::shared_ptr<const RRSIGRecordContent>>* signatures = nullptr, std::shared_ptr<std::vector<DNSRecord>>* authorityRecs = nullptr, bool* variable = nullptr, vState* state = nullptr, bool* wasAuth = nullptr, DNSName* fromAuthZone = nullptr, ComboAddress* fromAuthIP = nullptr);
+ // The type used to pass auth record data to replace(); If the vector is non-empty, the cache will
+ // store a shared pointer to the copied data. The shared pointer will be returned by get(). There
+ // are optimizations: an empty vector will be stored as a nullptr, but get() will return a pointer
+ // to an already existing empty vector in that case, this is more convenient for the caller, since
+ // it avoid checking for nullptr, just iterate as for the non-empty case.
+ using AuthRecsVec = std::vector<DNSRecord>;
+ using AuthRecs = std::shared_ptr<const AuthRecsVec>; // const to avoid modifying the vector, which would be bad for shared data
+ const static AuthRecs s_emptyAuthRecs;
- void replace(time_t, const DNSName& qname, QType qtype, const vector<DNSRecord>& content, const vector<shared_ptr<const RRSIGRecordContent>>& signatures, const std::shared_ptr<std::vector<DNSRecord>>& authorityRecs, bool auth, const DNSName& authZone, boost::optional<Netmask> ednsmask = boost::none, const OptTag& routingTag = boost::none, vState state = vState::Indeterminate, boost::optional<ComboAddress> from = boost::none, bool refresh = false, time_t ttl_time = time(nullptr));
+ [[nodiscard]] time_t get(time_t, const DNSName& qname, QType qtype, Flags flags, vector<DNSRecord>* res, const ComboAddress& who, const OptTag& routingTag = boost::none, vector<std::shared_ptr<const RRSIGRecordContent>>* signatures = nullptr, AuthRecs* authorityRecs = nullptr, bool* variable = nullptr, vState* state = nullptr, bool* wasAuth = nullptr, DNSName* fromAuthZone = nullptr, ComboAddress* fromAuthIP = nullptr);
+
+ void replace(time_t, const DNSName& qname, QType qtype, const vector<DNSRecord>& content, const vector<shared_ptr<const RRSIGRecordContent>>& signatures, const AuthRecsVec& authorityRecs, bool auth, const DNSName& authZone, boost::optional<Netmask> ednsmask = boost::none, const OptTag& routingTag = boost::none, vState state = vState::Indeterminate, boost::optional<ComboAddress> from = boost::none, bool refresh = false, time_t ttl_time = time(nullptr));
void doPrune(time_t now, size_t keep);
uint64_t doDump(int fileDesc, size_t maxCacheEntries);
records_t d_records;
std::vector<std::shared_ptr<const RRSIGRecordContent>> d_signatures;
- std::shared_ptr<std::vector<DNSRecord>> d_authorityRecs;
+ AuthRecs d_authorityRecs;
DNSName d_qname;
DNSName d_authZone;
ComboAddress d_from;
static Entries getEntries(MapCombo::LockedContent& map, const DNSName& qname, QType qtype, const OptTag& rtag);
static cache_t::const_iterator getEntryUsingECSIndex(MapCombo::LockedContent& map, time_t now, const DNSName& qname, QType qtype, bool requireAuth, const ComboAddress& who, bool serveStale);
- static time_t handleHit(time_t now, MapCombo::LockedContent& content, OrderedTagIterator_t& entry, const DNSName& qname, uint32_t& origTTL, vector<DNSRecord>* res, vector<std::shared_ptr<const RRSIGRecordContent>>* signatures, std::shared_ptr<std::vector<DNSRecord>>* authorityRecs, bool* variable, boost::optional<vState>& state, bool* wasAuth, DNSName* authZone, ComboAddress* fromAuthIP);
+ static time_t handleHit(time_t now, MapCombo::LockedContent& content, OrderedTagIterator_t& entry, const DNSName& qname, uint32_t& origTTL, vector<DNSRecord>* res, vector<std::shared_ptr<const RRSIGRecordContent>>* signatures, AuthRecs* authorityRecs, bool* variable, boost::optional<vState>& state, bool* wasAuth, DNSName* authZone, ComboAddress* fromAuthIP);
static void updateStaleEntry(time_t now, OrderedTagIterator_t& entry);
static void handleServeStaleBookkeeping(time_t, bool, OrderedTagIterator_t&);
};
// Put non-default root hints into cache as authoritative. As argued below in
// putDefaultHintsIntoCache, this is actually wrong, but people might depend on it by having
// root-hints that refer to servers that aren't actually capable or willing to serve root data.
- g_recCache->replace(now, name, qtype, aset, {}, nullptr, true, g_rootdnsname, boost::none, boost::none, state, from);
+ g_recCache->replace(now, name, qtype, aset, {}, {}, true, g_rootdnsname, boost::none, boost::none, state, from);
}
}
{
vector<DNSRecord> cset;
vector<std::shared_ptr<const RRSIGRecordContent>> signatures;
- std::shared_ptr<vector<DNSRecord>> authorityRecs = std::make_shared<vector<DNSRecord>>();
+ MemRecursorCache::AuthRecs authorityRecs = MemRecursorCache::s_emptyAuthRecs;
bool wasAuth = false;
uint32_t capTTL = std::numeric_limits<uint32_t>::max();
DNSName foundName;
bool found = false;
bool expired = false;
vector<std::shared_ptr<const RRSIGRecordContent>> signatures;
- std::shared_ptr<vector<DNSRecord>> authorityRecs = std::make_shared<vector<DNSRecord>>();
+ MemRecursorCache::AuthRecs authorityRecs = MemRecursorCache::s_emptyAuthRecs;
uint32_t ttl = 0;
uint32_t capTTL = std::numeric_limits<uint32_t>::max();
bool wasCachedAuth{};
return g_dnssecmode != DNSSECMode::Off && g_dnssecmode != DNSSECMode::ProcessNoValidate;
}
-uint32_t SyncRes::computeLowestTTD(const std::vector<DNSRecord>& records, const std::vector<std::shared_ptr<const RRSIGRecordContent>>& signatures, uint32_t signaturesTTL, const std::shared_ptr<std::vector<DNSRecord>>& authorityRecs) const
+uint32_t SyncRes::computeLowestTTD(const std::vector<DNSRecord>& records, const std::vector<std::shared_ptr<const RRSIGRecordContent>>& signatures, uint32_t signaturesTTL, const MemRecursorCache::AuthRecsVec& authorityRecs) const
{
uint32_t lowestTTD = std::numeric_limits<uint32_t>::max();
for (const auto& record : records) {
}
}
- for (const auto& entry : *authorityRecs) {
+ for (const auto& entry : authorityRecs) {
/* be careful, this is still a TTL here */
lowestTTD = min(lowestTTD, static_cast<uint32_t>(entry.d_ttl + d_now.tv_sec));
fixupAnswer(prefix, lwr, qname, qtype, auth, wasForwarded, rdQuery);
sanitizeRecords(prefix, lwr, qname, qtype, auth, wasForwarded, rdQuery);
- std::shared_ptr<std::vector<DNSRecord>> authorityRecs = std::make_shared<std::vector<DNSRecord>>();
+ MemRecursorCache::AuthRecsVec authorityRecs;
bool isCNAMEAnswer = false;
bool isDNAMEAnswer = false;
DNSName seenAuth;
}
if (nsecTypes.count(rec.d_type) != 0) {
- authorityRecs->emplace_back(rec);
+ authorityRecs.emplace_back(rec);
}
else if (rec.d_type == QType::RRSIG) {
auto rrsig = getRR<RRSIGRecordContent>(rec);
if (rrsig && nsecTypes.count(rrsig->d_type) != 0) {
- authorityRecs->emplace_back(rec);
+ authorityRecs.emplace_back(rec);
}
}
}
// supplant
for (auto& entry : tcache) {
- 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)
+ 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) {
thisRRNeedsWildcardProof = true;
}
}
- g_recCache->replace(d_now.tv_sec, tCacheEntry->first.name, tCacheEntry->first.type, tCacheEntry->second.records, tCacheEntry->second.signatures, thisRRNeedsWildcardProof ? authorityRecs : nullptr, tCacheEntry->first.type == QType::DS ? true : isAA, auth, tCacheEntry->first.place == DNSResourceRecord::ANSWER ? ednsmask : boost::none, d_routingTag, recordState, remoteIP, d_refresh, tCacheEntry->second.d_ttl_time);
+ g_recCache->replace(d_now.tv_sec, tCacheEntry->first.name, tCacheEntry->first.type, tCacheEntry->second.records, tCacheEntry->second.signatures, thisRRNeedsWildcardProof ? authorityRecs : *MemRecursorCache::s_emptyAuthRecs, tCacheEntry->first.type == QType::DS ? true : isAA, auth, tCacheEntry->first.place == DNSResourceRecord::ANSWER ? ednsmask : boost::none, d_routingTag, recordState, remoteIP, d_refresh, tCacheEntry->second.d_ttl_time);
// Delete potential negcache entry. When a record recovers with serve-stale the negcache entry can cause the wrong entry to
// be served, as negcache entries are checked before record cache entries
boost::optional<Netmask> getEDNSSubnetMask(const DNSName& name, const ComboAddress& rem);
static bool validationEnabled();
- uint32_t computeLowestTTD(const std::vector<DNSRecord>& records, const std::vector<std::shared_ptr<const RRSIGRecordContent>>& signatures, uint32_t signaturesTTL, const std::shared_ptr<std::vector<DNSRecord>>& authorityRecs) const;
+ uint32_t computeLowestTTD(const std::vector<DNSRecord>& records, const std::vector<std::shared_ptr<const RRSIGRecordContent>>& signatures, uint32_t signaturesTTL, const MemRecursorCache::AuthRecsVec& authorityRecs) const;
void updateValidationState(const DNSName& qname, vState& state, vState stateUpdate, const string& prefix);
vState validateRecordsWithSigs(unsigned int depth, const string& prefix, const DNSName& qname, QType qtype, const DNSName& name, QType type, const std::vector<DNSRecord>& records, const std::vector<std::shared_ptr<const RRSIGRecordContent>>& signatures);
vState validateDNSKeys(const DNSName& zone, const std::vector<DNSRecord>& dnskeys, const std::vector<std::shared_ptr<const RRSIGRecordContent>>& signatures, unsigned int depth, const string& prefix);
MemRecursorCache MRC;
std::vector<DNSRecord> records;
- std::shared_ptr<std::vector<DNSRecord>> authRecords;
+ MemRecursorCache::AuthRecsVec authRecords;
std::vector<std::shared_ptr<const RRSIGRecordContent>> signatures;
const DNSName authZone(".");
MemRecursorCache MRC;
std::vector<DNSRecord> records;
- std::shared_ptr<std::vector<DNSRecord>> authRecords;
+ MemRecursorCache::AuthRecsVec authRecords;
std::vector<std::shared_ptr<const RRSIGRecordContent>> signatures;
time_t now = time(nullptr);
MemRecursorCache MRC;
std::vector<DNSRecord> records;
- std::shared_ptr<std::vector<DNSRecord>> authRecords;
+ MemRecursorCache::AuthRecsVec authRecords;
std::vector<std::shared_ptr<const RRSIGRecordContent>> signatures;
time_t now = time(nullptr);
std::vector<DNSRecord> records;
std::vector<std::shared_ptr<const RRSIGRecordContent>> signatures;
- std::shared_ptr<std::vector<DNSRecord>> authRecs;
+ MemRecursorCache::AuthRecsVec authRecs;
const DNSName authZone(".");
BOOST_CHECK_EQUAL(MRC.size(), 0U);
time_t now = time(nullptr);
std::vector<DNSRecord> records;
std::vector<std::shared_ptr<const RRSIGRecordContent>> signatures;
- std::shared_ptr<std::vector<DNSRecord>> authRecs;
+ MemRecursorCache::AuthRecsVec authRecs;
const DNSName authZone(".");
BOOST_CHECK_EQUAL(MRC.size(), 0U);
time_t now = time(nullptr);
const DNSName power("powerdns.com.");
const DNSName authZone(".");
std::vector<DNSRecord> records;
- std::shared_ptr<std::vector<DNSRecord>> authRecords;
+ MemRecursorCache::AuthRecsVec authRecords;
std::vector<std::shared_ptr<const RRSIGRecordContent>> signatures;
time_t now = time(nullptr);
std::vector<DNSRecord> retrieved;
const DNSName power("powerdns.com.");
const DNSName authZone(".");
std::vector<DNSRecord> records;
- std::shared_ptr<std::vector<DNSRecord>> authRecords;
+ MemRecursorCache::AuthRecsVec authRecords;
std::vector<std::shared_ptr<const RRSIGRecordContent>> signatures;
time_t now = time(nullptr);
std::vector<DNSRecord> retrieved;
MemRecursorCache MRC;
const DNSName authZone(".");
- std::shared_ptr<std::vector<DNSRecord>> authRecords;
+ MemRecursorCache::AuthRecsVec authRecords;
std::vector<std::shared_ptr<const RRSIGRecordContent>> signatures;
time_t now = time(nullptr);
time_t ttd = now + 30;
MemRecursorCache MRC;
const DNSName authZone(".");
- std::shared_ptr<std::vector<DNSRecord>> authRecords = std::make_shared<std::vector<DNSRecord>>();
+ MemRecursorCache::AuthRecsVec authRecords;
DNSRecord dr;
dr.d_place = DNSResourceRecord::ANSWER;
dr.d_name = DNSName("hi");
dr.d_type = QType::AAAA;
dr.d_ttl = 3600;
dr.setContent(std::make_shared<ARecordContent>(ComboAddress("1::2:3:4")));
- authRecords->emplace_back(dr);
+ authRecords.emplace_back(dr);
std::vector<std::shared_ptr<const RRSIGRecordContent>> signatures;
signatures.emplace_back(std::dynamic_pointer_cast<RRSIGRecordContent>(RRSIGRecordContent::make("DNSKEY 8 0 172800 20241111000000 20241021000000 20326 . alCFgDZS+0l5zcpQ/7R+5OFeCrk9KGkNP2F9ynXIXG6QigPj/9qjm0xx ItRJUUim+SrJywAmLKe+48oTUeSRyDKVVg3LGDekLKcIVz0EBqTL2y44 usDlUlxqx5O0LQVHy4h/hm9+dCXFiSBWoV0LcAplV9OYWhxi+CxmxZU5 8vK6eVAde8E2JHdeDuy23WF5lxYEg1q7ehEt5EdRvZ7hZzfawEFR3Qv3 WMootO2eBAAneIe94daJP/i1iwQJ4p+bGVCZ4sJk+Pk9J7lwEQq6Ghkd SpLsRxArUhvoVgtnh0LkAV7TsajYk8K2JRt7wHNDbBV6+Vdq2bh7ZPGv LiGkIQ==")));
for (size_t counter = 0; counter < expected + 10; counter++) {
std::vector<DNSRecord> retrieved;
- std::shared_ptr<std::vector<DNSRecord>> authRecs;
+ MemRecursorCache::AuthRecs authRecs;
std::vector<std::shared_ptr<const RRSIGRecordContent>> sigs;
bool variable = false;
vState state = vState::Indeterminate;
BOOST_CHECK_EQUAL(sigs.at(0)->getZoneRepresentation(), signatures.at(0)->getZoneRepresentation());
BOOST_CHECK_EQUAL(authRecs->size(), 1U);
- BOOST_CHECK_EQUAL(authRecs->at(0).toString(), authRecords->at(0).toString());
+ BOOST_CHECK_EQUAL(authRecs->at(0).toString(), authRecords.at(0).toString());
BOOST_CHECK_EQUAL(state, vState::Insecure);
BOOST_CHECK_EQUAL(wasAuth, true);
BOOST_CHECK_EQUAL(fromZone, authZone);
arr.setContent(std::make_shared<ARecordContent>(ComboAddress(rootIps4[c - 'a'])));
vector<DNSRecord> aset;
aset.push_back(arr);
- g_recCache->replace(now, DNSName(templ), QType(QType::A), aset, vector<std::shared_ptr<const RRSIGRecordContent>>(), nullptr, false, g_rootdnsname);
+ g_recCache->replace(now, DNSName(templ), QType(QType::A), aset, vector<std::shared_ptr<const RRSIGRecordContent>>(), {}, false, g_rootdnsname);
if (!rootIps6[c - 'a'].empty()) {
aaaarr.setContent(std::make_shared<AAAARecordContent>(ComboAddress(rootIps6[c - 'a'])));
vector<DNSRecord> aaaaset;
aaaaset.push_back(aaaarr);
- g_recCache->replace(now, DNSName(templ), QType(QType::AAAA), aaaaset, vector<std::shared_ptr<const RRSIGRecordContent>>(), nullptr, false, g_rootdnsname);
+ g_recCache->replace(now, DNSName(templ), QType(QType::AAAA), aaaaset, vector<std::shared_ptr<const RRSIGRecordContent>>(), {}, false, g_rootdnsname);
}
nsset.push_back(nsrr);
}
- g_recCache->replace(now, g_rootdnsname, QType(QType::NS), nsset, vector<std::shared_ptr<const RRSIGRecordContent>>(), nullptr, false, g_rootdnsname); // and stuff in the cache
+ g_recCache->replace(now, g_rootdnsname, QType(QType::NS), nsset, vector<std::shared_ptr<const RRSIGRecordContent>>(), {}, false, g_rootdnsname); // and stuff in the cache
return true;
}
std::vector<shared_ptr<const RRSIGRecordContent>> sigs;
addRecordToList(records, target, QType::NS, "pdns-public-ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, now + 3600);
- g_recCache->replace(now, target, QType(QType::NS), records, sigs, nullptr, true, g_rootdnsname, boost::optional<Netmask>());
+ g_recCache->replace(now, target, QType(QType::NS), records, sigs, {}, true, g_rootdnsname, boost::optional<Netmask>());
vector<DNSRecord> ret;
int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
std::vector<shared_ptr<const RRSIGRecordContent>> sigs;
addRecordToList(records, target, QType::A, "192.0.2.1", DNSResourceRecord::ANSWER, now + 3600);
- g_recCache->replace(now, target, QType(QType::A), records, sigs, nullptr, true, g_rootdnsname, boost::optional<Netmask>());
+ g_recCache->replace(now, target, QType(QType::A), records, sigs, {}, true, g_rootdnsname, boost::optional<Netmask>());
vector<DNSRecord> ret;
int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
std::vector<shared_ptr<const RRSIGRecordContent>> sigs;
addRecordToList(records, target, QType::A, "192.0.2.42", DNSResourceRecord::ANSWER, now - 60);
- g_recCache->replace(now - 3600, target, QType(QType::A), records, sigs, nullptr, true, g_rootdnsname, boost::optional<Netmask>());
+ g_recCache->replace(now - 3600, target, QType(QType::A), records, sigs, {}, true, g_rootdnsname, boost::optional<Netmask>());
vector<DNSRecord> ret;
int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
res = testSR->beginResolve(target, QType(QType::A), QClass::IN, ret);
BOOST_CHECK_EQUAL(res, RCode::NoError);
BOOST_CHECK_EQUAL(testSR->getValidationState(), vState::Insecure);
+ BOOST_CHECK(MemRecursorCache::s_emptyAuthRecs->empty());
BOOST_REQUIRE_EQUAL(ret.size(), 5U);
BOOST_CHECK_EQUAL(queriesCount, 5U);
}