}
}
else {
- if (iter->d_name != name)
+ if (iter->d_name != name) {
break;
+ }
}
if (qtype == 0xffff || iter->d_type == qtype) {
iter = idx.erase(iter);
count++;
}
- else
+ else {
++iter;
+ }
}
return count;
}
if (now < iter->d_ttd) { // it is right, it is fresh!
*age = static_cast<uint32_t>(now - iter->d_creation);
// we know ttl is > 0
- uint32_t ttl = static_cast<uint32_t>(iter->d_ttd - now);
+ auto ttl = static_cast<uint32_t>(iter->d_ttd - now);
if (s_refresh_ttlperc > 0 && !iter->d_submitted) {
const uint32_t deadline = iter->getOrigTTL() * s_refresh_ttlperc / 100;
const bool almostExpired = ttl <= deadline;
return true;
}
- else {
- // We used to move the item to the front of "the to be deleted" sequence,
- // but we very likely will update the entry very soon, so leave it
- d_misses++;
- break;
- }
+ // We used to move the item to the front of "the to be deleted" sequence,
+ // but we very likely will update the entry very soon, so leave it
+ d_misses++;
+ break;
}
return false;
}
-bool RecursorPacketCache::getResponsePacket(unsigned int tag, const std::string& queryPacket, time_t now,
- std::string* responsePacket, uint32_t* age, uint32_t* qhash)
-{
- DNSName qname;
- uint16_t qtype, qclass;
- vState valState;
- return getResponsePacket(tag, queryPacket, qname, &qtype, &qclass, now, responsePacket, age, &valState, qhash, nullptr, false);
-}
-
-bool RecursorPacketCache::getResponsePacket(unsigned int tag, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now,
- std::string* responsePacket, uint32_t* age, uint32_t* qhash)
-{
- vState valState;
- return getResponsePacket(tag, queryPacket, qname, qtype, qclass, now, responsePacket, age, &valState, qhash, nullptr, false);
-}
-
static const std::unordered_set<uint16_t> s_skipOptions = {EDNSOptionCode::ECS, EDNSOptionCode::COOKIE};
bool RecursorPacketCache::getResponsePacket(unsigned int tag, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now,
return false;
}
- qname = DNSName(queryPacket.c_str(), queryPacket.length(), sizeof(dnsheader), false, qtype, qclass, 0);
+ qname = DNSName(queryPacket.c_str(), static_cast<int>(queryPacket.length()), sizeof(dnsheader), false, qtype, qclass);
return checkResponseMatches(range, queryPacket, qname, *qtype, *qclass, now, responsePacket, age, valState, pbdata);
}
return;
}
- struct Entry e(qname, qtype, qclass, std::move(responsePacket), std::move(query), tcp, qhash, now + ttl, now, tag, valState);
+ struct Entry entry(qname, qtype, qclass, std::move(responsePacket), std::move(query), tcp, qhash, now + ttl, now, tag, valState);
if (pbdata) {
- e.d_pbdata = std::move(*pbdata);
+ entry.d_pbdata = std::move(*pbdata);
}
- d_packetCache.insert(e);
+ d_packetCache.insert(entry);
if (d_packetCache.size() > d_maxSize) {
auto& seq_idx = d_packetCache.get<SequencedTag>();
uint64_t RecursorPacketCache::bytes() const
{
uint64_t sum = 0;
- for (const auto& e : d_packetCache) {
- sum += sizeof(e) + e.d_packet.length() + 4;
+ for (const auto& entry : d_packetCache) {
+ sum += sizeof(entry) + entry.d_packet.length() + 4;
}
return sum;
}
-void RecursorPacketCache::doPruneTo(size_t maxCached)
+void RecursorPacketCache::doPruneTo(size_t maxSize)
{
- pruneCollection<SequencedTag>(d_packetCache, maxCached);
+ pruneCollection<SequencedTag>(d_packetCache, maxSize);
}
-uint64_t RecursorPacketCache::doDump(int fd)
+uint64_t RecursorPacketCache::doDump(int file)
{
- auto fp = std::unique_ptr<FILE, int (*)(FILE*)>(fdopen(dup(fd), "w"), fclose);
- if (!fp) { // dup probably failed
+ int fdupped = dup(file);
+ if (fdupped == -1) {
+ return 0;
+ }
+ auto filePtr = std::unique_ptr<FILE, decltype(&fclose)>(fdopen(fdupped, "w"), fclose);
+ if (!filePtr) {
+ close(fdupped);
return 0;
}
- fprintf(fp.get(), "; main packet cache dump from thread follows\n;\n");
+ fprintf(filePtr.get(), "; main packet cache dump from thread follows\n;\n");
const auto& sidx = d_packetCache.get<SequencedTag>();
uint64_t count = 0;
time_t now = time(nullptr);
- for (const auto& i : sidx) {
+ for (const auto& entry : sidx) {
count++;
try {
- fprintf(fp.get(), "%s %" PRId64 " %s ; tag %d %s\n", i.d_name.toString().c_str(), static_cast<int64_t>(i.d_ttd - now), DNSRecordContent::NumberToType(i.d_type).c_str(), i.d_tag, i.d_tcp ? "tcp" : "udp");
+ fprintf(filePtr.get(), "%s %" PRId64 " %s ; tag %d %s\n", entry.d_name.toString().c_str(), static_cast<int64_t>(entry.d_ttd - now), DNSRecordContent::NumberToType(entry.d_type).c_str(), entry.d_tag, entry.d_tcp ? "tcp" : "udp");
}
catch (...) {
- fprintf(fp.get(), "; error printing '%s'\n", i.d_name.empty() ? "EMPTY" : i.d_name.toString().c_str());
+ fprintf(filePtr.get(), "; error printing '%s'\n", entry.d_name.empty() ? "EMPTY" : entry.d_name.toString().c_str());
}
}
return count;
//! Stores whole packets, ready for lobbing back at the client. Not threadsafe.
/* Note: we store answers as value AND KEY, and with careful work, we make sure that
- you can use a query as a key too. But query and answer must compare as identical!
-
+ you can use a query as a key too. But query and answer must compare as identical!
+
This precludes doing anything smart with EDNS directly from the packet */
class RecursorPacketCache : public PacketCache
{
std::string d_response;
bool d_tagged;
};
- typedef boost::optional<PBData> OptPBData;
+ using OptPBData = boost::optional<PBData>;
RecursorPacketCache(size_t maxsize) :
d_maxSize(maxsize)
{
}
- bool getResponsePacket(unsigned int tag, const std::string& queryPacket, time_t now, std::string* responsePacket, uint32_t* age, uint32_t* qhash);
- bool getResponsePacket(unsigned int tag, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, uint32_t* qhash);
+ bool getResponsePacket(unsigned int tag, const std::string& queryPacket, time_t now,
+ std::string* responsePacket, uint32_t* age, uint32_t* qhash)
+ {
+ DNSName qname;
+ uint16_t qtype{0};
+ uint16_t qclass{0};
+ vState valState{vState::Indeterminate};
+ return getResponsePacket(tag, queryPacket, qname, &qtype, &qclass, now, responsePacket, age, &valState, qhash, nullptr, false);
+ }
+
+ bool getResponsePacket(unsigned int tag, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now,
+ std::string* responsePacket, uint32_t* age, uint32_t* qhash)
+ {
+ vState valState{vState::Indeterminate};
+ return getResponsePacket(tag, queryPacket, qname, qtype, qclass, now, responsePacket, age, &valState, qhash, nullptr, false);
+ }
+
bool getResponsePacket(unsigned int tag, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, OptPBData* pbdata, bool tcp);
bool getResponsePacket(unsigned int tag, const std::string& queryPacket, DNSName& qname, uint16_t* qtype, uint16_t* qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, OptPBData* pbdata, bool tcp);
void insertResponsePacket(unsigned int tag, uint32_t qhash, std::string&& query, const DNSName& qname, uint16_t qtype, uint16_t qclass, std::string&& responsePacket, time_t now, uint32_t ttl, const vState& valState, OptPBData&& pbdata, bool tcp);
void doPruneTo(size_t maxSize = 250000);
- uint64_t doDump(int fd);
+ uint64_t doDump(int file);
int doWipePacketCache(const DNSName& name, uint16_t qtype = 0xffff, bool subtree = false);
- void setMaxSize(size_t sz)
+ void setMaxSize(size_t size)
{
- d_maxSize = sz;
+ d_maxSize = size;
}
- uint64_t size() const
+ [[nodiscard]] uint64_t size() const
{
return d_packetCache.size();
}
- uint64_t bytes() const;
+ [[nodiscard]] uint64_t bytes() const;
uint64_t d_hits{0};
uint64_t d_misses{0};
private:
- struct HashTag
- {
- };
- struct NameTag
- {
- };
struct Entry
{
Entry(const DNSName& qname, uint16_t qtype, uint16_t qclass, std::string&& packet, std::string&& query, bool tcp,
}
};
+ struct HashTag
+ {
+ };
+ struct NameTag
+ {
+ };
struct SequencedTag
{
};
- typedef multi_index_container<
- Entry,
- indexed_by<
- hashed_non_unique<tag<HashTag>,
- composite_key<Entry,
- member<Entry, uint32_t, &Entry::d_tag>,
- member<Entry, uint32_t, &Entry::d_qhash>,
- member<Entry, bool, &Entry::d_tcp>>>,
- sequenced<tag<SequencedTag>>,
- ordered_non_unique<tag<NameTag>, member<Entry, DNSName, &Entry::d_name>, CanonDNSNameCompare>>>
- packetCache_t;
+ using packetCache_t = multi_index_container<Entry,
+ indexed_by<hashed_non_unique<tag<HashTag>,
+ composite_key<Entry,
+ member<Entry, uint32_t, &Entry::d_tag>,
+ member<Entry, uint32_t, &Entry::d_qhash>,
+ member<Entry, bool, &Entry::d_tcp>>>,
+ sequenced<tag<SequencedTag>>,
+ ordered_non_unique<tag<NameTag>, member<Entry, DNSName, &Entry::d_name>, CanonDNSNameCompare>>>;
packetCache_t d_packetCache;
size_t d_maxSize;