the default one being represented by the empty string:
```
-pc = newPacketCache(10000, 86400, 600)
+pc = newPacketCache(10000, 86400, 600, 60)
getPool(""):setCache(pc)
```
The first parameter is the maximum number of entries stored in the cache, the
second one, optional, is the maximum lifetime of an entry in the cache, in seconds,
-and the last one, optional too, is the minimum TTL an entry should have to be considered
-for insertion in the cache.
+the third one, optional too, is the minimum TTL an entry should have to be considered
+for insertion in the cache, and the last one, still optional, is the TTL used for a
+Server Failure response.
Performance tuning
* `expunge(n)`: remove entries from the cache, leaving at most `n` entries
* `expungeByName(DNSName [, qtype=ANY])`: remove entries matching the supplied DNSName and type from the cache
* `isFull()`: return true if the cache has reached the maximum number of entries
- * `newPacketCache(maxEntries, maxTTL=86400, minTTL=60)`: return a new PacketCache
+ * `newPacketCache(maxEntries[, maxTTL=86400, minTTL=60, servFailTTL=60])`: return a new PacketCache
* `printStats()`: print the cache stats (hits, misses, deferred lookups and deferred inserts)
* `purgeExpired(n)`: remove expired entries from the cache until there is at most `n` entries remaining in the cache
* `toString()`: return the number of entries in the Packet Cache, and the maximum number of entries
#include "dnsdist-cache.hh"
#include "dnsparser.hh"
-DNSDistPacketCache::DNSDistPacketCache(size_t maxEntries, uint32_t maxTTL, uint32_t minTTL): d_maxEntries(maxEntries), d_maxTTL(maxTTL), d_minTTL(minTTL)
+DNSDistPacketCache::DNSDistPacketCache(size_t maxEntries, uint32_t maxTTL, uint32_t minTTL, uint32_t servFailTTL): d_maxEntries(maxEntries), d_maxTTL(maxTTL), d_servFailTTL(servFailTTL), d_minTTL(minTTL)
{
pthread_rwlock_init(&d_lock, 0);
/* we reserve maxEntries + 1 to avoid rehashing from occuring
return true;
}
-void DNSDistPacketCache::insert(uint32_t key, const DNSName& qname, uint16_t qtype, uint16_t qclass, const char* response, uint16_t responseLen, bool tcp)
+void DNSDistPacketCache::insert(uint32_t key, const DNSName& qname, uint16_t qtype, uint16_t qclass, const char* response, uint16_t responseLen, bool tcp, bool servFail)
{
if (responseLen == 0)
return;
- uint32_t minTTL = getMinTTL(response, responseLen);
- if (minTTL > d_maxTTL)
- minTTL = d_maxTTL;
+ uint32_t minTTL;
- if (minTTL < d_minTTL)
- return;
+ if (servFail) {
+ minTTL = d_servFailTTL;
+ }
+ else {
+ minTTL = getMinTTL(response, responseLen);
+ if (minTTL > d_maxTTL)
+ minTTL = d_maxTTL;
+
+ if (minTTL < d_minTTL)
+ return;
+ }
{
TryReadLock r(&d_lock);
class DNSDistPacketCache : boost::noncopyable
{
public:
- DNSDistPacketCache(size_t maxEntries, uint32_t maxTTL=86400, uint32_t minTTL=60);
+ DNSDistPacketCache(size_t maxEntries, uint32_t maxTTL=86400, uint32_t minTTL=60, uint32_t servFailTTL=60);
~DNSDistPacketCache();
- void insert(uint32_t key, const DNSName& qname, uint16_t qtype, uint16_t qclass, const char* response, uint16_t responseLen, bool tcp);
+ void insert(uint32_t key, const DNSName& qname, uint16_t qtype, uint16_t qclass, const char* response, uint16_t responseLen, bool tcp, bool servFail=false);
bool get(const unsigned char* query, uint16_t queryLen, const DNSName& qname, uint16_t qtype, uint16_t qclass, uint16_t consumed, uint16_t queryId, char* response, uint16_t* responseLen, bool tcp, uint32_t* keyOut, bool skipAging=false);
void purgeExpired(size_t upTo=0);
void expunge(size_t upTo=0);
std::atomic<uint64_t> d_lookupCollisions{0};
size_t d_maxEntries;
uint32_t d_maxTTL;
+ uint32_t d_servFailTTL;
uint32_t d_minTTL;
};
});
g_lua.registerFunction("getCache", &ServerPool::getCache);
- g_lua.writeFunction("newPacketCache", [client](size_t maxEntries, boost::optional<uint32_t> maxTTL, boost::optional<uint32_t> minTTL) {
- return std::make_shared<DNSDistPacketCache>(maxEntries, maxTTL ? *maxTTL : 86400, minTTL ? *minTTL : 60);
+ g_lua.writeFunction("newPacketCache", [client](size_t maxEntries, boost::optional<uint32_t> maxTTL, boost::optional<uint32_t> minTTL, boost::optional<uint32_t> servFailTTL) {
+ return std::make_shared<DNSDistPacketCache>(maxEntries, maxTTL ? *maxTTL : 86400, minTTL ? *minTTL : 60, servFailTTL ? *servFailTTL : 60);
});
g_lua.registerFunction("toString", &DNSDistPacketCache::toString);
g_lua.registerFunction("isFull", &DNSDistPacketCache::isFull);
}
if (packetCache && !dq.skipCache) {
- packetCache->insert(cacheKey, qname, qtype, qclass, response, responseLen, true);
+ packetCache->insert(cacheKey, qname, qtype, qclass, response, responseLen, true, dh->rcode == RCode::ServFail);
}
#ifdef HAVE_DNSCRYPT
g_stats.responses++;
if (ids->packetCache && !ids->skipCache) {
- ids->packetCache->insert(ids->cacheKey, qname, qtype, qclass, response, responseLen, false);
+ ids->packetCache->insert(ids->cacheKey, qname, qtype, qclass, response, responseLen, false, dh->rcode == RCode::ServFail);
}
#ifdef HAVE_DNSCRYPT