class TestCaching(DNSDistTest):
_config_template = """
- -- maxTTL=86400, minTTL=1
- pc = newPacketCache(100, 86400, 1)
+ pc = newPacketCache(100, {maxTTL=86400, minTTL=1})
getPool(""):setCache(pc)
addAction(makeRule("nocache.cache.tests.powerdns.com."), SkipCacheAction())
function skipViaLua(dq)
response.answer.append(rrset)
for _ in range(numberOfQueries):
- (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
- self.assertTrue(receivedQuery)
- self.assertTrue(receivedResponse)
- receivedQuery.id = query.id
- self.assertEquals(query, receivedQuery)
- self.assertEquals(receivedResponse, response)
-
- (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
- self.assertTrue(receivedQuery)
- self.assertTrue(receivedResponse)
- receivedQuery.id = query.id
- self.assertEquals(query, receivedQuery)
- self.assertEquals(receivedResponse, response)
+ for method in ("sendUDPQuery", "sendTCPQuery"):
+ sender = getattr(self, method)
+ (receivedQuery, receivedResponse) = sender(query, response)
+ self.assertTrue(receivedQuery)
+ self.assertTrue(receivedResponse)
+ receivedQuery.id = query.id
+ self.assertEquals(query, receivedQuery)
+ self.assertEquals(receivedResponse, response)
for key in self._responsesCounter:
value = self._responsesCounter[key]
response.answer.append(rrset)
for _ in range(numberOfQueries):
- (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
- self.assertTrue(receivedQuery)
- self.assertTrue(receivedResponse)
- receivedQuery.id = query.id
- self.assertEquals(query, receivedQuery)
- self.assertEquals(receivedResponse, response)
-
- (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
- self.assertTrue(receivedQuery)
- self.assertTrue(receivedResponse)
- receivedQuery.id = query.id
- self.assertEquals(query, receivedQuery)
- self.assertEquals(receivedResponse, response)
+ for method in ("sendUDPQuery", "sendTCPQuery"):
+ sender = getattr(self, method)
+ (receivedQuery, receivedResponse) = sender(query, response)
+ self.assertTrue(receivedQuery)
+ self.assertTrue(receivedResponse)
+ receivedQuery.id = query.id
+ self.assertEquals(query, receivedQuery)
+ self.assertEquals(receivedResponse, response)
for key in self._responsesCounter:
value = self._responsesCounter[key]
(_, receivedResponse) = self.sendUDPQuery(differentCaseQuery, response=None, useQueue=False)
self.assertEquals(receivedResponse, differentCaseResponse)
+ def testLargeAnswer(self):
+ """
+ Cache: Check that we can cache (and retrieve) large answers
+
+ We should be able to get answers as large as 4096 bytes
+ """
+ numberOfQueries = 10
+ name = 'large-answer.cache.tests.powerdns.com.'
+ query = dns.message.make_query(name, 'TXT', 'IN')
+ response = dns.message.make_response(query)
+ # we prepare a large answer
+ content = ""
+ for i in range(44):
+ if len(content) > 0:
+ content = content + ', '
+ content = content + (str(i)*50)
+ # pad up to 4096
+ content = content + 'A'*42
+
+ rrset = dns.rrset.from_text(name,
+ 3600,
+ dns.rdataclass.IN,
+ dns.rdatatype.TXT,
+ content)
+ response.answer.append(rrset)
+ self.assertEquals(len(response.to_wire()), 4096)
+
+ # first query to fill the cache
+ (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
+ self.assertTrue(receivedQuery)
+ self.assertTrue(receivedResponse)
+ receivedQuery.id = query.id
+ self.assertEquals(query, receivedQuery)
+ self.assertEquals(receivedResponse, response)
+
+ for _ in range(numberOfQueries):
+ (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
+ self.assertEquals(receivedResponse, response)
+
+ total = 0
+ for key in self._responsesCounter:
+ total += self._responsesCounter[key]
+ TestCaching._responsesCounter[key] = 0
+
+ self.assertEquals(total, 1)
+
+ # TCP should not be cached
+ # first query to fill the cache
+ (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
+ self.assertTrue(receivedQuery)
+ self.assertTrue(receivedResponse)
+ receivedQuery.id = query.id
+ self.assertEquals(query, receivedQuery)
+ self.assertEquals(receivedResponse, response)
+
+ for _ in range(numberOfQueries):
+ (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
+ self.assertEquals(receivedResponse, response)
+
+ total = 0
+ for key in self._responsesCounter:
+ total += self._responsesCounter[key]
+ TestCaching._responsesCounter[key] = 0
+
+ self.assertEquals(total, 1)
class TestTempFailureCacheTTLAction(DNSDistTest):
_config_template = """
- -- maxTTL=86400, minTTL=1
- pc = newPacketCache(100, 86400, 1)
+ pc = newPacketCache(100, {maxTTL=86400, minTTL=1})
getPool(""):setCache(pc)
addAction("servfail.cache.tests.powerdns.com.", TempFailureCacheTTLAction(1))
newServer{address="127.0.0.1:%d"}
class TestCachingWithExistingEDNS(DNSDistTest):
_config_template = """
- -- maxTTL=86400, minTTL=1
- pc = newPacketCache(5, 86400, 1)
+ pc = newPacketCache(5, {maxTTL=86400, minTTL=1})
getPool(""):setCache(pc)
newServer{address="127.0.0.1:%d"}
"""
class TestCachingCacheFull(DNSDistTest):
_config_template = """
- -- maxTTL=86400, minTTL=1
- pc = newPacketCache(1, 86400, 1)
+ pc = newPacketCache(1, {maxTTL=86400, minTTL=1})
getPool(""):setCache(pc)
newServer{address="127.0.0.1:%d"}
"""
_consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
_config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort']
_config_template = """
- -- maxTTL=86400, minTTL=1
- pc = newPacketCache(100, 86400, 1)
+ pc = newPacketCache(100, {maxTTL=86400, minTTL=1})
getPool(""):setCache(pc)
setKey("%s")
controlSocket("127.0.0.1:%d")
_staleCacheTTL = 60
_config_params = ['_staleCacheTTL', '_consoleKeyB64', '_consolePort', '_testServerPort']
_config_template = """
- -- maxTTL=86400, minTTL=1, temporaryFailureTTL=0, staleTTL=XX
- pc = newPacketCache(100, 86400, 1, 0, %d)
+ pc = newPacketCache(100, {maxTTL=86400, minTTL=1, temporaryFailureTTL=0, staleTTL=%d})
getPool(""):setCache(pc)
setStaleCacheEntriesTTL(600)
setKey("%s")
_staleCacheTTL = 60
_config_params = ['_staleCacheTTL', '_consoleKeyB64', '_consolePort', '_testServerPort']
_config_template = """
- -- maxTTL=86400, minTTL=1, temporaryFailureTTL=0, staleTTL=XX
- pc = newPacketCache(100, 86400, 1, 0, %d)
+ pc = newPacketCache(100, {maxTTL=86400, minTTL=1, temporaryFailureTTL=0, staleTTL=%d})
getPool(""):setCache(pc)
setStaleCacheEntriesTTL(600)
-- try to remove all expired entries
_consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
_config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort']
_config_template = """
- -- maxTTL=86400, minTTL=1, temporaryFailureTTL=0, staleTTL=60, dontAge=false, numberOfShards=1, deferrableInsertLock=true, maxNegativeTTL=3600, ecsParsing=false, keepStaleData=true
- pc = newPacketCache(100, 86400, 1, 0, 60, false, 1, true, 3600, false, { keepStaleData=true})
+ pc = newPacketCache(100, {maxTTL=86400, minTTL=1, temporaryFailureTTL=0, staleTTL=60, dontAge=false, numberOfShards=1, deferrableInsertLock=true, maxNegativeTTL=3600, ecsParsing=false, keepStaleData=true})
getPool(""):setCache(pc)
setStaleCacheEntriesTTL(600)
-- try to remove all expired entries
_consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
_config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort']
_config_template = """
- -- maxTTL=86400, minTTL=1
- pc = newPacketCache(100, 86400, 1)
+ pc = newPacketCache(100, {maxTTL=86400, minTTL=1})
getPool(""):setCache(pc)
setKey("%s")
controlSocket("127.0.0.1:%d")
self.assertEquals(receivedResponse, response2)
# remove cached entries from name A
- self.sendConsoleCommand("getPool(\"\"):getCache():expungeByName(newDNSName(\"" + name + "\"), dnsdist.A)")
+ self.sendConsoleCommand("getPool(\"\"):getCache():expungeByName(newDNSName(\"" + name + "\"), DNSQType.A)")
# Miss for name A
(receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
self.assertEquals(receivedResponse, response2)
# remove cached entries from name
- self.sendConsoleCommand("getPool(\"\"):getCache():expungeByName(newDNSName(\"suffix.cache.tests.powerdns.com.\"), dnsdist.ANY, true)")
+ self.sendConsoleCommand("getPool(\"\"):getCache():expungeByName(newDNSName(\"suffix.cache.tests.powerdns.com.\"), DNSQType.ANY, true)")
# Miss for name
(receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
self.assertEquals(receivedResponse, response2)
# remove cached entries from name A
- self.sendConsoleCommand("getPool(\"\"):getCache():expungeByName(newDNSName(\"suffixtype.cache.tests.powerdns.com.\"), dnsdist.A, true)")
+ self.sendConsoleCommand("getPool(\"\"):getCache():expungeByName(newDNSName(\"suffixtype.cache.tests.powerdns.com.\"), DNSQType.A, true)")
# Miss for name A
(receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
_minCacheTTL = 600
_config_params = ['_maxCacheTTL', '_minCacheTTL', '_testServerPort']
_config_template = """
- -- maxTTL=XX, minTTL=XX
- pc = newPacketCache(1000, %d, %d)
+ pc = newPacketCache(1000, {maxTTL=%d, minTTL=%d})
getPool(""):setCache(pc)
newServer{address="127.0.0.1:%d"}
"""
_maxCacheTTL = 2
_config_params = ['_maxCacheTTL', '_testServerPort']
_config_template = """
- -- maxTTL=XX
- pc = newPacketCache(1000, %d)
+ pc = newPacketCache(1000, {maxTTL=%d})
getPool(""):setCache(pc)
newServer{address="127.0.0.1:%d"}
"""
_failureCacheTTL = 2
_config_params = ['_failureCacheTTL', '_testServerPort']
_config_template = """
- -- maxTTL=86400, minTTL=0, temporaryFailureTTL=XX, staleTTL=60
- pc = newPacketCache(1000, 86400, 0, %d, 60)
+ pc = newPacketCache(1000, {maxTTL=86400, minTTL=0, temporaryFailureTTL=%d, staleTTL=60})
getPool(""):setCache(pc)
newServer{address="127.0.0.1:%d"}
"""
_negCacheTTL = 1
_config_params = ['_negCacheTTL', '_testServerPort']
_config_template = """
- -- maxTTL=86400, minTTL=0, temporaryFailureTTL=60, staleTTL=60, dontAge=false, numberOfShards=1, deferrableInsertLock=true, maxNegativeTTL=XX
- pc = newPacketCache(1000, 86400, 0, 60, 60, false, 1, true, %d)
+ pc = newPacketCache(1000, {maxTTL=86400, minTTL=0, temporaryFailureTTL=60, staleTTL=60, dontAge=false, numberOfShards=1, deferrableInsertLock=true, maxNegativeTTL=%d})
getPool(""):setCache(pc)
newServer{address="127.0.0.1:%d"}
"""
class TestCachingDontAge(DNSDistTest):
_config_template = """
- -- maxTTL=86400, minTTL=0, temporaryFailureTTL=60, staleTTL=60, dontAge=true
- pc = newPacketCache(100, 86400, 0, 60, 60, true)
+ pc = newPacketCache(100, {maxTTL=86400, minTTL=0, temporaryFailureTTL=60, staleTTL=60, dontAge=true})
getPool(""):setCache(pc)
newServer{address="127.0.0.1:%d"}
"""
_consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
_config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort']
_config_template = """
- -- maxTTL=86400, minTTL=1
- pc = newPacketCache(100, 86400, 1)
+ pc = newPacketCache(100, {maxTTL=86400, minTTL=1})
getPool(""):setCache(pc)
setKey("%s")
controlSocket("127.0.0.1:%d")
response.answer.append(rrset)
# first query to fill the cache
- (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
- self.assertTrue(receivedQuery)
- self.assertTrue(receivedResponse)
- receivedQuery.id = query.id
- self.assertEquals(query, receivedQuery)
- self.assertEquals(receivedResponse, response)
- (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
- self.assertTrue(receivedQuery)
- self.assertTrue(receivedResponse)
- receivedQuery.id = query.id
- self.assertEquals(query, receivedQuery)
- self.assertEquals(receivedResponse, response)
+ for method in ("sendUDPQuery", "sendTCPQuery"):
+ sender = getattr(self, method)
+ (receivedQuery, receivedResponse) = sender(query, response)
+ self.assertTrue(receivedQuery)
+ self.assertTrue(receivedResponse)
+ receivedQuery.id = query.id
+ self.assertEquals(query, receivedQuery)
+ self.assertEquals(receivedResponse, response)
# next queries should hit the cache
- (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
- self.assertEquals(receivedResponse, response)
-
- # over TCP too
- (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
- self.assertEquals(receivedResponse, response)
+ for method in ("sendUDPQuery", "sendTCPQuery"):
+ sender = getattr(self, method)
+ (_, receivedResponse) = sender(query, response=None, useQueue=False)
+ self.assertEquals(receivedResponse, response)
# we mark the backend as down
self.sendConsoleCommand("getServer(0):setDown()")
# we should NOT get a cached entry since it has ECS and we haven't asked the pool
# to add ECS when no backend is up
- (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
- self.assertEquals(receivedResponse, None)
-
- # same over TCP
- (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
- self.assertEquals(receivedResponse, None)
+ for method in ("sendUDPQuery", "sendTCPQuery"):
+ sender = getattr(self, method)
+ (_, receivedResponse) = sender(query, response=None, useQueue=False)
+ self.assertEquals(receivedResponse, None)
class TestCachingECSWithPoolECS(DNSDistTest):
_consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
_config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort']
_config_template = """
- -- maxTTL=86400, minTTL=1
- pc = newPacketCache(100, 86400, 1)
+ pc = newPacketCache(100, {maxTTL=86400, minTTL=1})
getPool(""):setCache(pc)
getPool(""):setECS(true)
setKey("%s")
response.answer.append(rrset)
# first query to fill the cache
- (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
- self.assertTrue(receivedQuery)
- self.assertTrue(receivedResponse)
- receivedQuery.id = query.id
- self.assertEquals(query, receivedQuery)
- self.assertEquals(receivedResponse, response)
- (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
- self.assertTrue(receivedQuery)
- self.assertTrue(receivedResponse)
- receivedQuery.id = query.id
- self.assertEquals(query, receivedQuery)
- self.assertEquals(receivedResponse, response)
+ for method in ("sendUDPQuery", "sendTCPQuery"):
+ sender = getattr(self, method)
+ (receivedQuery, receivedResponse) = sender(query, response)
+ self.assertTrue(receivedQuery)
+ self.assertTrue(receivedResponse)
+ receivedQuery.id = query.id
+ self.assertEquals(query, receivedQuery)
+ self.assertEquals(receivedResponse, response)
# next queries should hit the cache
- (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
- self.assertEquals(receivedResponse, response)
-
- # over TCP too
- (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
- self.assertEquals(receivedResponse, response)
+ for method in ("sendUDPQuery", "sendTCPQuery"):
+ sender = getattr(self, method)
+ (_, receivedResponse) = sender(query, response=None, useQueue=False)
+ self.assertEquals(receivedResponse, response)
# we mark the backend as down
self.sendConsoleCommand("getServer(0):setDown()")
# we should STILL get a cached entry since it has ECS and we have asked the pool
# to add ECS when no backend is up
- (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
- self.assertEquals(receivedResponse, response)
-
- # same over TCP
- (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
- self.assertEquals(receivedResponse, response)
+ for method in ("sendUDPQuery", "sendTCPQuery"):
+ sender = getattr(self, method)
+ (_, receivedResponse) = sender(query, response=None, useQueue=False)
+ self.assertEquals(receivedResponse, response)
class TestCachingCollisionNoECSParsing(DNSDistTest):
_config_template = """
- -- maxTTL=86400, minTTL=1
- pc = newPacketCache(100, 86400, 1)
+ pc = newPacketCache(100, {maxTTL=86400, minTTL=1})
getPool(""):setCache(pc)
newServer{address="127.0.0.1:%d"}
"""
class TestCachingCollisionWithECSParsing(DNSDistTest):
_config_template = """
- -- maxTTL=86400, minTTL=1, temporaryFailureTTL=60, staleTTL=60, dontAge=false, numberOfShards=1, deferrableInsertLock=true, maxNegativeTTL=3600, parseECS=true
- pc = newPacketCache(100, 86400, 1, 60, 60, false, 1, true, 3600, true)
+ pc = newPacketCache(100, {maxTTL=86400, minTTL=1, temporaryFailureTTL=60, staleTTL=60, dontAge=false, numberOfShards=1, deferrableInsertLock=true, maxNegativeTTL=3600, parseECS=true})
getPool(""):setCache(pc)
newServer{address="127.0.0.1:%d"}
"""
_config_template = """
-- Be careful to enable ECS parsing in the packet cache, otherwise scope zero is disabled
- pc = newPacketCache(100, 86400, 1, 60, 60, false, 1, true, 3600, true)
+ pc = newPacketCache(100, {maxTTL=86400, minTTL=1, temporaryFailureTTL=60, staleTTL=60, dontAge=false, numberOfShards=1, deferrableInsertLock=true, maxNegativeTTL=3600, parseECS=true})
getPool(""):setCache(pc)
newServer{address="127.0.0.1:%d", useClientSubnet=true}
-- to simulate a second client coming from a different IP address,
_config_template = """
-- We disable ECS parsing in the packet cache, meaning scope zero is disabled
- pc = newPacketCache(100, 86400, 1, 60, 60, false, 1, true, 3600, false)
+ pc = newPacketCache(100, {maxTTL=86400, minTTL=1, temporaryFailureTTL=60, staleTTL=60, dontAge=false, numberOfShards=1, deferrableInsertLock=true, maxNegativeTTL=3600, parseECS=false})
getPool(""):setCache(pc)
newServer{address="127.0.0.1:%d", useClientSubnet=true}
-- to simulate a second client coming from a different IP address,