}
}
- void remove(const DNSName &name) const
+ void remove(const DNSName &name, bool subtree=false) const
{
auto labels = name.getRawLabels();
- remove(labels);
+ remove(labels, subtree);
}
/* Removes the node at `labels`, also make sure that no empty
* children will be left behind in memory
*/
- void remove(std::vector<std::string>& labels) const
+ void remove(std::vector<std::string>& labels, bool subtree = false) const
{
if (labels.empty()) { // this allows removal of the root
endNode = false;
+ if (subtree) {
+ children.clear();
+ }
return;
}
// The child is no longer an endnode
child->endNode = false;
+ if (subtree) {
+ child->children.clear();
+ }
+
// If the child has no further children, just remove it from the set.
if (child->children.empty()) {
children.erase(child);
count += g_recCache->doWipeCache(wipe.first, wipe.second, qtype);
pcount += broadcastAccFunction<uint64_t>([=]{ return pleaseWipePacketCache(wipe.first, wipe.second, qtype);});
countNeg += g_negCache->wipe(wipe.first, wipe.second);
+ if (g_aggressiveNSECCache) {
+ g_aggressiveNSECCache->removeZoneInfo(wipe.first, wipe.second);
+ }
}
catch (const std::exception& e) {
g_log<<Logger::Warning<<", failed: "<<e.what()<<endl;
g_recCache->doWipeCache(who, true, 0xffff);
broadcastAccFunction<uint64_t>([=]{return pleaseWipePacketCache(who, true, 0xffff);});
g_negCache->wipe(who, true);
+ if (g_aggressiveNSECCache) {
+ g_aggressiveNSECCache->removeZoneInfo(who, true);
+ }
}
catch (std::exception& e) {
g_log<<Logger::Warning<<", failed: "<<e.what()<<endl;
g_recCache->doWipeCache(entry, true, 0xffff);
broadcastAccFunction<uint64_t>([=]{return pleaseWipePacketCache(entry, true, 0xffff);});
g_negCache->wipe(entry, true);
+ if (g_aggressiveNSECCache) {
+ g_aggressiveNSECCache->removeZoneInfo(entry, true);
+ }
if (!first) {
first = false;
removed += ",";
g_recCache->doWipeCache(who, true, 0xffff);
broadcastAccFunction<uint64_t>([=]{return pleaseWipePacketCache(who, true, 0xffff);});
g_negCache->wipe(who, true);
+ if (g_aggressiveNSECCache) {
+ g_aggressiveNSECCache->removeZoneInfo(who, true);
+ }
g_log<<Logger::Warning<<endl;
return "Added Trust Anchor for " + who.toStringRootDot() + " with data " + what + "\n";
}
g_recCache->doWipeCache(entry, true, 0xffff);
broadcastAccFunction<uint64_t>([=]{return pleaseWipePacketCache(entry, true, 0xffff);});
g_negCache->wipe(entry, true);
+ if (g_aggressiveNSECCache) {
+ g_aggressiveNSECCache->removeZoneInfo(entry, true);
+ }
if (!first) {
first = false;
removed += ",";
}
}
+void AggressiveNSECCache::updateEntriesCount()
+{
+ /* need to be called while holding a write lock */
+ uint64_t counter = 0;
+ d_zones.visit([&counter](const SuffixMatchTree<std::shared_ptr<ZoneEntry>>& node) {
+ counter += node.d_value->d_entries.size();
+ });
+ d_entriesCount = counter;
+}
+
+void AggressiveNSECCache::removeZoneInfo(const DNSName& zone, bool subzones)
+{
+ WriteLock rl(d_lock);
+ auto got = d_zones.lookup(zone);
+ if (!got || !*got || (*got)->d_zone != zone) {
+ return;
+ }
+
+ if (subzones) {
+ d_zones.remove(zone, true);
+ updateEntriesCount();
+ }
+ else {
+ std::lock_guard<std::mutex> lock((*got)->d_lock);
+ auto removed = (*got)->d_entries.size();
+ d_zones.remove(zone, false);
+ d_entriesCount -= removed;
+ }
+}
+
static bool isMinimallyCoveringNSEC(const DNSName& owner, const std::shared_ptr<NSECRecordContent>& nsec)
{
/* this test only covers Cloudflare's ones (https://blog.cloudflare.com/black-lies/),
}
if (it->d_ttd <= now) {
- idx.erase(it);
- --d_entriesCount;
+ moveCacheItemToFront<ZoneEntry::SequencedTag>(zoneEntry->d_entries, it);
+ //idx.erase(it);
+ //--d_entriesCount;
return false;
}
continue;
}
+ auto firstIndexIterator = zoneEntry->d_entries.project<ZoneEntry::OrderedTag>(it);
if (it->d_ttd <= now) {
- idx.erase(it);
- --d_entriesCount;
+ moveCacheItemToBack<ZoneEntry::SequencedTag>(zoneEntry->d_entries, firstIndexIterator);
+ //idx.erase(it);
+ //--d_entriesCount;
return false;
}
entry = *it;
- auto firstIndexIterator = zoneEntry->d_entries.project<ZoneEntry::OrderedTag>(it);
moveCacheItemToBack<ZoneEntry::SequencedTag>(zoneEntry->d_entries, firstIndexIterator);
return true;
}
void insertNSEC(const DNSName& zone, const DNSName& owner, const DNSRecord& record, const std::vector<std::shared_ptr<RRSIGRecordContent>>& signatures, bool nsec3);
bool getDenial(time_t, const DNSName& name, const QType& type, std::vector<DNSRecord>& ret, int& res, const ComboAddress& who, const boost::optional<std::string>& routingTag, bool doDNSSEC);
- //void removeZoneInfo(const DNSName& zone);
+ void removeZoneInfo(const DNSName& zone, bool subzones);
uint64_t getEntriesCount() const
{
bool synthesizeFromNSEC3Wildcard(time_t now, const DNSName& name, const QType& type, std::vector<DNSRecord>& ret, int& res, bool doDNSSEC, ZoneEntry::CacheEntry& nextCloser, const DNSName& wildcardName);
bool synthesizeFromNSECWildcard(time_t now, const DNSName& name, const QType& type, std::vector<DNSRecord>& ret, int& res, bool doDNSSEC, ZoneEntry::CacheEntry& nsec, const DNSName& wildcardName);
+ /* slowly updates d_entriesCount */
+ void updateEntriesCount();
+
SuffixMatchTree<std::shared_ptr<ZoneEntry>> d_zones;
ReadWriteLock d_lock;
- std::atomic<uint64_t> d_entriesCount{0};
std::atomic<uint64_t> d_nsecHits{0};
std::atomic<uint64_t> d_nsec3Hits{0};
std::atomic<uint64_t> d_nsecWildcardHits{0};
std::atomic<uint64_t> d_nsec3WildcardHits{0};
+ std::atomic<uint64_t> d_entriesCount{0};
};