]>
git.ipfire.org Git - thirdparty/pdns.git/blob - regression-tests.dnsdist/test_Caching.py
5 import clientsubnetoption
6 from dnsdisttests
import DNSDistTest
8 class TestCaching(DNSDistTest
):
10 _config_template
= """
11 pc = newPacketCache(100, 86400, 1)
12 getPool(""):setCache(pc)
13 addAction(makeRule("nocache.cache.tests.powerdns.com."), SkipCacheAction())
14 function skipViaLua(dq)
16 return DNSAction.None, ""
18 addAction("nocachevialua.cache.tests.powerdns.com.", LuaAction(skipViaLua))
19 newServer{address="127.0.0.1:%s"}
24 Cache: Served from cache
26 dnsdist is configured to cache entries, we are sending several
27 identical requests and checking that the backend only receive
31 name
= 'cached.cache.tests.powerdns.com.'
32 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
33 response
= dns
.message
.make_response(query
)
34 rrset
= dns
.rrset
.from_text(name
,
39 response
.answer
.append(rrset
)
41 # first query to fill the cache
42 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
43 self
.assertTrue(receivedQuery
)
44 self
.assertTrue(receivedResponse
)
45 receivedQuery
.id = query
.id
46 self
.assertEquals(query
, receivedQuery
)
47 self
.assertEquals(receivedResponse
, response
)
49 for _
in range(numberOfQueries
):
50 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
51 self
.assertEquals(receivedResponse
, response
)
54 for key
in self
._responsesCounter
:
55 total
+= self
._responsesCounter
[key
]
56 TestCaching
._responsesCounter
[key
] = 0
58 self
.assertEquals(total
, 1)
60 # TCP should not be cached
61 # first query to fill the cache
62 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
63 self
.assertTrue(receivedQuery
)
64 self
.assertTrue(receivedResponse
)
65 receivedQuery
.id = query
.id
66 self
.assertEquals(query
, receivedQuery
)
67 self
.assertEquals(receivedResponse
, response
)
69 for _
in range(numberOfQueries
):
70 (_
, receivedResponse
) = self
.sendTCPQuery(query
, response
=None, useQueue
=False)
71 self
.assertEquals(receivedResponse
, response
)
74 for key
in self
._responsesCounter
:
75 total
+= self
._responsesCounter
[key
]
76 TestCaching
._responsesCounter
[key
] = 0
78 self
.assertEquals(total
, 1)
80 def testDOCached(self
):
82 Cache: Served from cache, query has DO bit set
84 dnsdist is configured to cache entries, we are sending several
85 identical requests and checking that the backend only receive
89 name
= 'cached-do.cache.tests.powerdns.com.'
90 query
= dns
.message
.make_query(name
, 'AAAA', 'IN', use_edns
=True, payload
=4096, want_dnssec
=True)
91 response
= dns
.message
.make_response(query
)
92 rrset
= dns
.rrset
.from_text(name
,
97 response
.answer
.append(rrset
)
99 # first query to fill the cache
100 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
101 self
.assertTrue(receivedQuery
)
102 self
.assertTrue(receivedResponse
)
103 receivedQuery
.id = query
.id
104 self
.assertEquals(query
, receivedQuery
)
105 self
.assertEquals(receivedResponse
, response
)
107 for _
in range(numberOfQueries
):
108 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
109 self
.assertEquals(receivedResponse
, response
)
112 for key
in self
._responsesCounter
:
113 total
+= self
._responsesCounter
[key
]
114 TestCaching
._responsesCounter
[key
] = 0
116 self
.assertEquals(total
, 1)
118 # TCP should not be cached
119 # first query to fill the cache
120 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
121 self
.assertTrue(receivedQuery
)
122 self
.assertTrue(receivedResponse
)
123 receivedQuery
.id = query
.id
124 self
.assertEquals(query
, receivedQuery
)
125 self
.assertEquals(receivedResponse
, response
)
127 for _
in range(numberOfQueries
):
128 (_
, receivedResponse
) = self
.sendTCPQuery(query
, response
=None, useQueue
=False)
129 self
.assertEquals(receivedResponse
, response
)
132 for key
in self
._responsesCounter
:
133 total
+= self
._responsesCounter
[key
]
134 TestCaching
._responsesCounter
[key
] = 0
136 self
.assertEquals(total
, 1)
138 def testSkipCache(self
):
140 Cache: SkipCacheAction
142 dnsdist is configured to not cache entries for nocache.cache.tests.powerdns.com.
143 we are sending several requests and checking that the backend get them all.
145 name
= 'nocache.cache.tests.powerdns.com.'
147 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
148 response
= dns
.message
.make_response(query
)
149 rrset
= dns
.rrset
.from_text(name
,
154 response
.answer
.append(rrset
)
156 for _
in range(numberOfQueries
):
157 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
158 self
.assertTrue(receivedQuery
)
159 self
.assertTrue(receivedResponse
)
160 receivedQuery
.id = query
.id
161 self
.assertEquals(query
, receivedQuery
)
162 self
.assertEquals(receivedResponse
, response
)
164 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
165 self
.assertTrue(receivedQuery
)
166 self
.assertTrue(receivedResponse
)
167 receivedQuery
.id = query
.id
168 self
.assertEquals(query
, receivedQuery
)
169 self
.assertEquals(receivedResponse
, response
)
171 for key
in self
._responsesCounter
:
172 value
= self
._responsesCounter
[key
]
173 self
.assertEquals(value
, numberOfQueries
)
175 def testSkipCacheViaLua(self
):
177 Cache: SkipCache via Lua
179 dnsdist is configured to not cache entries for nocachevialua.cache.tests.powerdns.com.
180 we are sending several requests and checking that the backend get them all.
182 name
= 'nocachevialua.cache.tests.powerdns.com.'
184 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
185 response
= dns
.message
.make_response(query
)
186 rrset
= dns
.rrset
.from_text(name
,
191 response
.answer
.append(rrset
)
193 for _
in range(numberOfQueries
):
194 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
195 self
.assertTrue(receivedQuery
)
196 self
.assertTrue(receivedResponse
)
197 receivedQuery
.id = query
.id
198 self
.assertEquals(query
, receivedQuery
)
199 self
.assertEquals(receivedResponse
, response
)
201 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
202 self
.assertTrue(receivedQuery
)
203 self
.assertTrue(receivedResponse
)
204 receivedQuery
.id = query
.id
205 self
.assertEquals(query
, receivedQuery
)
206 self
.assertEquals(receivedResponse
, response
)
208 for key
in self
._responsesCounter
:
209 value
= self
._responsesCounter
[key
]
210 self
.assertEquals(value
, numberOfQueries
)
212 def testCacheExpiration(self
):
214 Cache: Cache expiration
216 dnsdist is configured to cache entries, we are sending one request
217 (cache miss) with a very short TTL, checking that the next requests
218 are cached. Then we wait for the TTL to expire, check that the
219 next request is a miss but the following one a hit.
223 name
= 'cacheexpiration.cache.tests.powerdns.com.'
224 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
225 response
= dns
.message
.make_response(query
)
226 rrset
= dns
.rrset
.from_text(name
,
231 response
.answer
.append(rrset
)
233 # first query to fill the cache
234 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
235 self
.assertTrue(receivedQuery
)
236 self
.assertTrue(receivedResponse
)
237 receivedQuery
.id = query
.id
238 self
.assertEquals(query
, receivedQuery
)
239 self
.assertEquals(receivedResponse
, response
)
242 # next queries should hit the cache
243 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
244 self
.assertEquals(receivedResponse
, response
)
246 # now we wait a bit for the cache entry to expire
249 # next query should be a miss, fill the cache again
250 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
251 self
.assertTrue(receivedQuery
)
252 self
.assertTrue(receivedResponse
)
253 receivedQuery
.id = query
.id
254 self
.assertEquals(query
, receivedQuery
)
255 self
.assertEquals(receivedResponse
, response
)
258 # following queries should hit the cache again
259 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
260 self
.assertEquals(receivedResponse
, response
)
263 for key
in self
._responsesCounter
:
264 total
+= self
._responsesCounter
[key
]
266 self
.assertEquals(total
, misses
)
268 def testCacheExpirationDifferentSets(self
):
270 Cache: Cache expiration with different sets
272 dnsdist is configured to cache entries, we are sending one request
273 (cache miss) whose response has a long and a very short TTL,
274 checking that the next requests are cached. Then we wait for the
275 short TTL to expire, check that the
276 next request is a miss but the following one a hit.
280 name
= 'cacheexpirationdifferentsets.cache.tests.powerdns.com.'
281 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
282 response
= dns
.message
.make_response(query
)
283 rrset
= dns
.rrset
.from_text(name
,
287 'cname.cacheexpirationdifferentsets.cache.tests.powerdns.com.')
288 response
.answer
.append(rrset
)
289 rrset
= dns
.rrset
.from_text('cname.cacheexpirationdifferentsets.cache.tests.powerdns.com.',
294 response
.additional
.append(rrset
)
296 # first query to fill the cache
297 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
298 self
.assertTrue(receivedQuery
)
299 self
.assertTrue(receivedResponse
)
300 receivedQuery
.id = query
.id
301 self
.assertEquals(query
, receivedQuery
)
302 self
.assertEquals(receivedResponse
, response
)
305 # next queries should hit the cache
306 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
307 self
.assertEquals(receivedResponse
, response
)
309 # now we wait a bit for the cache entry to expire
312 # next query should be a miss, fill the cache again
313 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
314 self
.assertTrue(receivedQuery
)
315 self
.assertTrue(receivedResponse
)
316 receivedQuery
.id = query
.id
317 self
.assertEquals(query
, receivedQuery
)
318 self
.assertEquals(receivedResponse
, response
)
321 # following queries should hit the cache again
322 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
323 self
.assertEquals(receivedResponse
, response
)
326 for key
in self
._responsesCounter
:
327 total
+= self
._responsesCounter
[key
]
329 self
.assertEquals(total
, misses
)
331 def testCacheDecreaseTTL(self
):
333 Cache: Cache decreases TTL
335 dnsdist is configured to cache entries, we are sending one request
336 (cache miss) and verify that the cache hits have a decreasing TTL.
340 name
= 'cachedecreasettl.cache.tests.powerdns.com.'
341 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
342 response
= dns
.message
.make_response(query
)
343 rrset
= dns
.rrset
.from_text(name
,
348 response
.answer
.append(rrset
)
350 # first query to fill the cache
351 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
352 self
.assertTrue(receivedQuery
)
353 self
.assertTrue(receivedResponse
)
354 receivedQuery
.id = query
.id
355 self
.assertEquals(query
, receivedQuery
)
356 self
.assertEquals(receivedResponse
, response
)
359 # next queries should hit the cache
360 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
361 self
.assertEquals(receivedResponse
, response
)
362 for an
in receivedResponse
.answer
:
363 self
.assertTrue(an
.ttl
<= ttl
)
365 # now we wait a bit for the TTL to decrease
368 # next queries should hit the cache
369 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
370 self
.assertEquals(receivedResponse
, response
)
371 for an
in receivedResponse
.answer
:
372 self
.assertTrue(an
.ttl
< ttl
)
375 for key
in self
._responsesCounter
:
376 total
+= self
._responsesCounter
[key
]
378 self
.assertEquals(total
, misses
)
380 def testCacheDifferentCase(self
):
382 Cache: Cache matches different case
384 dnsdist is configured to cache entries, we are sending one request
385 (cache miss) and verify that the same one with a different case
389 name
= 'cachedifferentcase.cache.tests.powerdns.com.'
390 differentCaseName
= 'CacheDifferentCASE.cache.tests.powerdns.com.'
391 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
392 differentCaseQuery
= dns
.message
.make_query(differentCaseName
, 'AAAA', 'IN')
393 response
= dns
.message
.make_response(query
)
394 differentCaseResponse
= dns
.message
.make_response(differentCaseQuery
)
395 rrset
= dns
.rrset
.from_text(name
,
400 response
.answer
.append(rrset
)
401 differentCaseResponse
.answer
.append(rrset
)
403 # first query to fill the cache
404 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
405 self
.assertTrue(receivedQuery
)
406 self
.assertTrue(receivedResponse
)
407 receivedQuery
.id = query
.id
408 self
.assertEquals(query
, receivedQuery
)
409 self
.assertEquals(receivedResponse
, response
)
411 # different case query should still hit the cache
412 (_
, receivedResponse
) = self
.sendUDPQuery(differentCaseQuery
, response
=None, useQueue
=False)
413 self
.assertEquals(receivedResponse
, differentCaseResponse
)
416 class TestTempFailureCacheTTLAction(DNSDistTest
):
418 _config_template
= """
419 pc = newPacketCache(100, 86400, 1)
420 getPool(""):setCache(pc)
421 addAction("servfail.cache.tests.powerdns.com.", TempFailureCacheTTLAction(1))
422 newServer{address="127.0.0.1:%s"}
425 def testTempFailureCacheTTLAction(self
):
427 Cache: When a TempFailure TTL is set, it should be honored
429 dnsdist is configured to cache packets, plus a specific qname is
430 set up with a lower TempFailure Cache TTL. we are sending one request
431 (cache miss) and verify that the cache is hit for the following query,
432 but the TTL then expires before the larger "good" packetcache TTL.
434 name
= 'servfail.cache.tests.powerdns.com.'
435 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
436 response
= dns
.message
.make_response(query
)
437 response
.set_rcode(dns
.rcode
.SERVFAIL
)
439 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
440 self
.assertTrue(receivedQuery
)
441 self
.assertTrue(receivedResponse
)
442 receivedQuery
.id = query
.id
443 self
.assertEquals(query
, receivedQuery
)
444 self
.assertEquals(receivedResponse
, response
)
446 # next query should hit the cache
447 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
448 self
.assertFalse(receivedQuery
)
449 self
.assertTrue(receivedResponse
)
450 self
.assertEquals(receivedResponse
, response
)
452 # now we wait a bit for the Failure-Cache TTL to expire
455 # next query should NOT hit the cache
456 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
457 self
.assertTrue(receivedQuery
)
458 self
.assertTrue(receivedResponse
)
459 self
.assertEquals(receivedResponse
, response
)
462 class TestCachingWithExistingEDNS(DNSDistTest
):
464 _config_template
= """
465 pc = newPacketCache(5, 86400, 1)
466 getPool(""):setCache(pc)
467 newServer{address="127.0.0.1:%s"}
469 def testCacheWithEDNS(self
):
471 Cache: Cache should not match different EDNS value
473 dnsdist is configured to cache entries, we are sending one request
474 (cache miss) and verify that the same one with a different EDNS UDP
475 Payload size is not served from the cache.
478 name
= 'cachedifferentedns.cache.tests.powerdns.com.'
479 query
= dns
.message
.make_query(name
, 'A', 'IN', use_edns
=True, payload
=512)
480 response
= dns
.message
.make_response(query
)
481 rrset
= dns
.rrset
.from_text(name
,
486 response
.answer
.append(rrset
)
488 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
489 self
.assertTrue(receivedQuery
)
490 self
.assertTrue(receivedResponse
)
491 receivedQuery
.id = query
.id
492 self
.assertEquals(query
, receivedQuery
)
493 self
.assertEquals(response
, receivedResponse
)
496 query
= dns
.message
.make_query(name
, 'A', 'IN', use_edns
=True, payload
=4096)
497 response
= dns
.message
.make_response(query
)
498 rrset
= dns
.rrset
.from_text(name
,
503 response
.answer
.append(rrset
)
505 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
506 self
.assertTrue(receivedQuery
)
507 self
.assertTrue(receivedResponse
)
508 receivedQuery
.id = query
.id
509 self
.assertEquals(query
, receivedQuery
)
510 self
.assertEquals(response
, receivedResponse
)
514 for key
in self
._responsesCounter
:
515 total
+= self
._responsesCounter
[key
]
517 self
.assertEquals(total
, misses
)
519 class TestCachingCacheFull(DNSDistTest
):
521 _config_template
= """
522 pc = newPacketCache(1, 86400, 1)
523 getPool(""):setCache(pc)
524 newServer{address="127.0.0.1:%s"}
526 def testCacheFull(self
):
528 Cache: No new entries are cached when the cache is full
532 name
= 'cachenotfullyet.cache.tests.powerdns.com.'
533 query
= dns
.message
.make_query(name
, 'A', 'IN')
534 response
= dns
.message
.make_response(query
)
535 rrset
= dns
.rrset
.from_text(name
,
540 response
.answer
.append(rrset
)
543 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
544 self
.assertTrue(receivedQuery
)
545 self
.assertTrue(receivedResponse
)
546 receivedQuery
.id = query
.id
547 self
.assertEquals(query
, receivedQuery
)
548 self
.assertEquals(response
, receivedResponse
)
551 # next queries should hit the cache
552 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
553 self
.assertEquals(receivedResponse
, response
)
555 # ok, now the cache is full, send another query
556 name
= 'cachefull.cache.tests.powerdns.com.'
557 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
558 response
= dns
.message
.make_response(query
)
559 rrset
= dns
.rrset
.from_text(name
,
564 response
.answer
.append(rrset
)
567 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
568 self
.assertTrue(receivedQuery
)
569 self
.assertTrue(receivedResponse
)
570 receivedQuery
.id = query
.id
571 self
.assertEquals(query
, receivedQuery
)
572 self
.assertEquals(response
, receivedResponse
)
575 # next queries should NOT hit the cache
576 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
577 self
.assertTrue(receivedQuery
)
578 self
.assertTrue(receivedResponse
)
579 receivedQuery
.id = query
.id
580 self
.assertEquals(query
, receivedQuery
)
581 self
.assertEquals(response
, receivedResponse
)
585 for key
in self
._responsesCounter
:
586 total
+= self
._responsesCounter
[key
]
588 self
.assertEquals(total
, misses
)
590 class TestCachingNoStale(DNSDistTest
):
592 _consoleKey
= DNSDistTest
.generateConsoleKey()
593 _consoleKeyB64
= base64
.b64encode(_consoleKey
).decode('ascii')
594 _config_params
= ['_consoleKeyB64', '_consolePort', '_testServerPort']
595 _config_template
= """
596 pc = newPacketCache(100, 86400, 1)
597 getPool(""):setCache(pc)
599 controlSocket("127.0.0.1:%s")
600 newServer{address="127.0.0.1:%s"}
602 def testCacheNoStale(self
):
604 Cache: Cache entry, set backend down, we should not get a stale entry
608 name
= 'nostale.cache.tests.powerdns.com.'
609 query
= dns
.message
.make_query(name
, 'A', 'IN')
610 response
= dns
.message
.make_response(query
)
611 rrset
= dns
.rrset
.from_text(name
,
616 response
.answer
.append(rrset
)
619 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
620 self
.assertTrue(receivedQuery
)
621 self
.assertTrue(receivedResponse
)
622 receivedQuery
.id = query
.id
623 self
.assertEquals(query
, receivedQuery
)
624 self
.assertEquals(response
, receivedResponse
)
626 # next queries should hit the cache
627 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
628 self
.assertEquals(receivedResponse
, response
)
630 # ok, we mark the backend as down
631 self
.sendConsoleCommand("getServer(0):setDown()")
632 # and we wait for the entry to expire
635 # we should NOT get a cached, stale, entry
636 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
637 self
.assertEquals(receivedResponse
, None)
640 class TestCachingStale(DNSDistTest
):
642 _consoleKey
= DNSDistTest
.generateConsoleKey()
643 _consoleKeyB64
= base64
.b64encode(_consoleKey
).decode('ascii')
645 _config_params
= ['_staleCacheTTL', '_consoleKeyB64', '_consolePort', '_testServerPort']
646 _config_template
= """
647 pc = newPacketCache(100, 86400, 1, %s)
648 getPool(""):setCache(pc)
649 setStaleCacheEntriesTTL(600)
651 controlSocket("127.0.0.1:%s")
652 newServer{address="127.0.0.1:%s"}
654 def testCacheStale(self
):
656 Cache: Cache entry, set backend down, get stale entry
661 name
= 'stale.cache.tests.powerdns.com.'
662 query
= dns
.message
.make_query(name
, 'A', 'IN')
663 response
= dns
.message
.make_response(query
)
664 rrset
= dns
.rrset
.from_text(name
,
669 response
.answer
.append(rrset
)
672 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
673 self
.assertTrue(receivedQuery
)
674 self
.assertTrue(receivedResponse
)
675 receivedQuery
.id = query
.id
676 self
.assertEquals(query
, receivedQuery
)
677 self
.assertEquals(response
, receivedResponse
)
680 # next queries should hit the cache
681 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
682 self
.assertEquals(receivedResponse
, response
)
684 # ok, we mark the backend as down
685 self
.sendConsoleCommand("getServer(0):setDown()")
686 # and we wait for the entry to expire
689 # we should get a cached, stale, entry
690 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
691 self
.assertEquals(receivedResponse
, response
)
692 for an
in receivedResponse
.answer
:
693 self
.assertEquals(an
.ttl
, self
._staleCacheTTL
)
696 for key
in self
._responsesCounter
:
697 total
+= self
._responsesCounter
[key
]
699 self
.assertEquals(total
, misses
)
701 class TestCacheManagement(DNSDistTest
):
703 _consoleKey
= DNSDistTest
.generateConsoleKey()
704 _consoleKeyB64
= base64
.b64encode(_consoleKey
).decode('ascii')
705 _config_params
= ['_consoleKeyB64', '_consolePort', '_testServerPort']
706 _config_template
= """
707 pc = newPacketCache(100, 86400, 1)
708 getPool(""):setCache(pc)
710 controlSocket("127.0.0.1:%s")
711 newServer{address="127.0.0.1:%s"}
713 def testCacheExpunge(self
):
720 name
= 'expunge.cache.tests.powerdns.com.'
721 query
= dns
.message
.make_query(name
, 'A', 'IN')
722 response
= dns
.message
.make_response(query
)
723 rrset
= dns
.rrset
.from_text(name
,
728 response
.answer
.append(rrset
)
731 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
732 self
.assertTrue(receivedQuery
)
733 self
.assertTrue(receivedResponse
)
734 receivedQuery
.id = query
.id
735 self
.assertEquals(query
, receivedQuery
)
736 self
.assertEquals(response
, receivedResponse
)
739 # next queries should hit the cache
740 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
741 self
.assertEquals(receivedResponse
, response
)
743 # remove cached entries
744 self
.sendConsoleCommand("getPool(\"\"):getCache():expunge(0)")
747 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
748 self
.assertTrue(receivedQuery
)
749 self
.assertTrue(receivedResponse
)
750 receivedQuery
.id = query
.id
751 self
.assertEquals(query
, receivedQuery
)
752 self
.assertEquals(response
, receivedResponse
)
755 # next queries should hit the cache again
756 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
757 self
.assertEquals(receivedResponse
, response
)
760 for key
in self
._responsesCounter
:
761 total
+= self
._responsesCounter
[key
]
763 self
.assertEquals(total
, misses
)
765 def testCacheExpungeByName(self
):
767 Cache: Expunge by name
772 name
= 'expungebyname.cache.tests.powerdns.com.'
773 query
= dns
.message
.make_query(name
, 'A', 'IN')
774 response
= dns
.message
.make_response(query
)
775 rrset
= dns
.rrset
.from_text(name
,
780 response
.answer
.append(rrset
)
782 name2
= 'expungebynameother.cache.tests.powerdns.com.'
783 query2
= dns
.message
.make_query(name2
, 'A', 'IN')
784 response2
= dns
.message
.make_response(query2
)
785 rrset2
= dns
.rrset
.from_text(name2
,
790 response2
.answer
.append(rrset2
)
793 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
794 self
.assertTrue(receivedQuery
)
795 self
.assertTrue(receivedResponse
)
796 receivedQuery
.id = query
.id
797 self
.assertEquals(query
, receivedQuery
)
798 self
.assertEquals(response
, receivedResponse
)
801 # next queries should hit the cache
802 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
803 self
.assertEquals(receivedResponse
, response
)
805 # cache another entry
806 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query2
, response2
)
807 self
.assertTrue(receivedQuery
)
808 self
.assertTrue(receivedResponse
)
809 receivedQuery
.id = query2
.id
810 self
.assertEquals(query2
, receivedQuery
)
811 self
.assertEquals(response2
, receivedResponse
)
814 # queries for name and name 2 should hit the cache
815 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
816 self
.assertEquals(receivedResponse
, response
)
818 (_
, receivedResponse
) = self
.sendUDPQuery(query2
, response
=None, useQueue
=False)
819 self
.assertEquals(receivedResponse
, response2
)
821 # remove cached entries from name
822 self
.sendConsoleCommand("getPool(\"\"):getCache():expungeByName(newDNSName(\"" + name
+ "\"))")
825 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
826 self
.assertTrue(receivedQuery
)
827 self
.assertTrue(receivedResponse
)
828 receivedQuery
.id = query
.id
829 self
.assertEquals(query
, receivedQuery
)
830 self
.assertEquals(response
, receivedResponse
)
833 # next queries for name should hit the cache again
834 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
835 self
.assertEquals(receivedResponse
, response
)
837 # queries for name2 should still hit the cache
838 (_
, receivedResponse
) = self
.sendUDPQuery(query2
, response
=None, useQueue
=False)
839 self
.assertEquals(receivedResponse
, response2
)
842 for key
in self
._responsesCounter
:
843 total
+= self
._responsesCounter
[key
]
845 self
.assertEquals(total
, misses
)
847 def testCacheExpungeByNameAndType(self
):
849 Cache: Expunge by name and type
854 name
= 'expungebynameandtype.cache.tests.powerdns.com.'
855 query
= dns
.message
.make_query(name
, 'A', 'IN')
856 response
= dns
.message
.make_response(query
)
857 rrset
= dns
.rrset
.from_text(name
,
862 response
.answer
.append(rrset
)
864 query2
= dns
.message
.make_query(name
, 'AAAA', 'IN')
865 response2
= dns
.message
.make_response(query2
)
866 rrset2
= dns
.rrset
.from_text(name
,
871 response2
.answer
.append(rrset2
)
874 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
875 self
.assertTrue(receivedQuery
)
876 self
.assertTrue(receivedResponse
)
877 receivedQuery
.id = query
.id
878 self
.assertEquals(query
, receivedQuery
)
879 self
.assertEquals(response
, receivedResponse
)
882 # next queries should hit the cache
883 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
884 self
.assertEquals(receivedResponse
, response
)
886 # cache another entry
887 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query2
, response2
)
888 self
.assertTrue(receivedQuery
)
889 self
.assertTrue(receivedResponse
)
890 receivedQuery
.id = query2
.id
891 self
.assertEquals(query2
, receivedQuery
)
892 self
.assertEquals(response2
, receivedResponse
)
895 # queries for name A and AAAA should hit the cache
896 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
897 self
.assertEquals(receivedResponse
, response
)
899 (_
, receivedResponse
) = self
.sendUDPQuery(query2
, response
=None, useQueue
=False)
900 self
.assertEquals(receivedResponse
, response2
)
902 # remove cached entries from name A
903 self
.sendConsoleCommand("getPool(\"\"):getCache():expungeByName(newDNSName(\"" + name
+ "\"), dnsdist.A)")
906 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
907 self
.assertTrue(receivedQuery
)
908 self
.assertTrue(receivedResponse
)
909 receivedQuery
.id = query
.id
910 self
.assertEquals(query
, receivedQuery
)
911 self
.assertEquals(response
, receivedResponse
)
914 # next queries for name A should hit the cache again
915 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
916 self
.assertEquals(receivedResponse
, response
)
918 # queries for name AAAA should still hit the cache
919 (_
, receivedResponse
) = self
.sendUDPQuery(query2
, response
=None, useQueue
=False)
920 self
.assertEquals(receivedResponse
, response2
)
923 for key
in self
._responsesCounter
:
924 total
+= self
._responsesCounter
[key
]
925 self
.assertEquals(total
, misses
)
927 def testCacheExpungeByNameAndSuffix(self
):
929 Cache: Expunge by name
934 name
= 'expungebyname.suffix.cache.tests.powerdns.com.'
935 query
= dns
.message
.make_query(name
, 'A', 'IN')
936 response
= dns
.message
.make_response(query
)
937 rrset
= dns
.rrset
.from_text(name
,
942 response
.answer
.append(rrset
)
944 name2
= 'expungebyname.suffixother.cache.tests.powerdns.com.'
945 query2
= dns
.message
.make_query(name2
, 'A', 'IN')
946 response2
= dns
.message
.make_response(query2
)
947 rrset2
= dns
.rrset
.from_text(name2
,
952 response2
.answer
.append(rrset2
)
955 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
956 self
.assertTrue(receivedQuery
)
957 self
.assertTrue(receivedResponse
)
958 receivedQuery
.id = query
.id
959 self
.assertEquals(query
, receivedQuery
)
960 self
.assertEquals(response
, receivedResponse
)
963 # next queries should hit the cache
964 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
965 self
.assertEquals(receivedResponse
, response
)
967 # cache another entry
968 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query2
, response2
)
969 self
.assertTrue(receivedQuery
)
970 self
.assertTrue(receivedResponse
)
971 receivedQuery
.id = query2
.id
972 self
.assertEquals(query2
, receivedQuery
)
973 self
.assertEquals(response2
, receivedResponse
)
976 # queries for name and name 2 should hit the cache
977 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
978 self
.assertEquals(receivedResponse
, response
)
980 (_
, receivedResponse
) = self
.sendUDPQuery(query2
, response
=None, useQueue
=False)
981 self
.assertEquals(receivedResponse
, response2
)
983 # remove cached entries from name
984 self
.sendConsoleCommand("getPool(\"\"):getCache():expungeByName(newDNSName(\"suffix.cache.tests.powerdns.com.\"), dnsdist.ANY, true)")
987 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
988 self
.assertTrue(receivedQuery
)
989 self
.assertTrue(receivedResponse
)
990 receivedQuery
.id = query
.id
991 self
.assertEquals(query
, receivedQuery
)
992 self
.assertEquals(response
, receivedResponse
)
995 # next queries for name should hit the cache again
996 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
997 self
.assertEquals(receivedResponse
, response
)
999 # queries for name2 should still hit the cache
1000 (_
, receivedResponse
) = self
.sendUDPQuery(query2
, response
=None, useQueue
=False)
1001 self
.assertEquals(receivedResponse
, response2
)
1004 for key
in self
._responsesCounter
:
1005 total
+= self
._responsesCounter
[key
]
1007 self
.assertEquals(total
, misses
)
1009 def testCacheExpungeByNameAndTypeAndSuffix(self
):
1011 Cache: Expunge by name and type
1016 name
= 'expungebynameandtype.suffixtype.cache.tests.powerdns.com.'
1017 query
= dns
.message
.make_query(name
, 'A', 'IN')
1018 response
= dns
.message
.make_response(query
)
1019 rrset
= dns
.rrset
.from_text(name
,
1024 response
.answer
.append(rrset
)
1026 query2
= dns
.message
.make_query(name
, 'AAAA', 'IN')
1027 response2
= dns
.message
.make_response(query2
)
1028 rrset2
= dns
.rrset
.from_text(name
,
1033 response2
.answer
.append(rrset2
)
1036 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1037 self
.assertTrue(receivedQuery
)
1038 self
.assertTrue(receivedResponse
)
1039 receivedQuery
.id = query
.id
1040 self
.assertEquals(query
, receivedQuery
)
1041 self
.assertEquals(response
, receivedResponse
)
1044 # next queries should hit the cache
1045 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
1046 self
.assertEquals(receivedResponse
, response
)
1048 # cache another entry
1049 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query2
, response2
)
1050 self
.assertTrue(receivedQuery
)
1051 self
.assertTrue(receivedResponse
)
1052 receivedQuery
.id = query2
.id
1053 self
.assertEquals(query2
, receivedQuery
)
1054 self
.assertEquals(response2
, receivedResponse
)
1057 # queries for name A and AAAA should hit the cache
1058 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
1059 self
.assertEquals(receivedResponse
, response
)
1061 (_
, receivedResponse
) = self
.sendUDPQuery(query2
, response
=None, useQueue
=False)
1062 self
.assertEquals(receivedResponse
, response2
)
1064 # remove cached entries from name A
1065 self
.sendConsoleCommand("getPool(\"\"):getCache():expungeByName(newDNSName(\"suffixtype.cache.tests.powerdns.com.\"), dnsdist.A, true)")
1068 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1069 self
.assertTrue(receivedQuery
)
1070 self
.assertTrue(receivedResponse
)
1071 receivedQuery
.id = query
.id
1072 self
.assertEquals(query
, receivedQuery
)
1073 self
.assertEquals(response
, receivedResponse
)
1076 # next queries for name A should hit the cache again
1077 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
1078 self
.assertEquals(receivedResponse
, response
)
1080 # queries for name AAAA should still hit the cache
1081 (_
, receivedResponse
) = self
.sendUDPQuery(query2
, response
=None, useQueue
=False)
1082 self
.assertEquals(receivedResponse
, response2
)
1085 for key
in self
._responsesCounter
:
1086 total
+= self
._responsesCounter
[key
]
1087 self
.assertEquals(total
, misses
)
1089 class TestCachingTTL(DNSDistTest
):
1091 _maxCacheTTL
= 86400
1093 _config_params
= ['_maxCacheTTL', '_minCacheTTL', '_testServerPort']
1094 _config_template
= """
1095 pc = newPacketCache(1000, %s, %s)
1096 getPool(""):setCache(pc)
1097 newServer{address="127.0.0.1:%s"}
1099 def testCacheShortTTL(self
):
1101 Cache: Entries with a TTL shorter than minTTL
1106 name
= 'ttltooshort.cache.tests.powerdns.com.'
1107 query
= dns
.message
.make_query(name
, 'A', 'IN')
1108 response
= dns
.message
.make_response(query
)
1109 rrset
= dns
.rrset
.from_text(name
,
1114 response
.answer
.append(rrset
)
1117 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1118 self
.assertTrue(receivedQuery
)
1119 self
.assertTrue(receivedResponse
)
1120 receivedQuery
.id = query
.id
1121 self
.assertEquals(query
, receivedQuery
)
1122 self
.assertEquals(response
, receivedResponse
)
1123 for an
in receivedResponse
.answer
:
1124 self
.assertEquals(an
.ttl
, ttl
)
1127 # We should not have been cached
1128 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1129 self
.assertTrue(receivedQuery
)
1130 self
.assertTrue(receivedResponse
)
1131 receivedQuery
.id = query
.id
1132 self
.assertEquals(query
, receivedQuery
)
1133 self
.assertEquals(response
, receivedResponse
)
1134 for an
in receivedResponse
.answer
:
1135 self
.assertEquals(an
.ttl
, ttl
)
1139 for key
in self
._responsesCounter
:
1140 total
+= self
._responsesCounter
[key
]
1142 self
.assertEquals(total
, misses
)
1144 def testCacheNXWithNoRR(self
):
1146 Cache: NX with no RR
1150 name
= 'nxwithnorr.cache.tests.powerdns.com.'
1151 query
= dns
.message
.make_query(name
, 'A', 'IN')
1152 response
= dns
.message
.make_response(query
)
1153 response
.set_rcode(dns
.rcode
.NXDOMAIN
)
1156 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1157 self
.assertTrue(receivedQuery
)
1158 self
.assertTrue(receivedResponse
)
1159 receivedQuery
.id = query
.id
1160 self
.assertEquals(query
, receivedQuery
)
1161 self
.assertEquals(response
, receivedResponse
)
1164 # We should not have been cached
1165 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1166 self
.assertTrue(receivedQuery
)
1167 self
.assertTrue(receivedResponse
)
1168 receivedQuery
.id = query
.id
1169 self
.assertEquals(query
, receivedQuery
)
1170 self
.assertEquals(response
, receivedResponse
)
1174 for key
in self
._responsesCounter
:
1175 total
+= self
._responsesCounter
[key
]
1177 self
.assertEquals(total
, misses
)
1179 class TestCachingLongTTL(DNSDistTest
):
1182 _config_params
= ['_maxCacheTTL', '_testServerPort']
1183 _config_template
= """
1184 pc = newPacketCache(1000, %s)
1185 getPool(""):setCache(pc)
1186 newServer{address="127.0.0.1:%s"}
1188 def testCacheLongTTL(self
):
1190 Cache: Entries with a longer TTL than the maximum
1195 name
= 'longttl.cache.tests.powerdns.com.'
1196 query
= dns
.message
.make_query(name
, 'A', 'IN')
1197 response
= dns
.message
.make_response(query
)
1198 rrset
= dns
.rrset
.from_text(name
,
1203 response
.answer
.append(rrset
)
1206 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1207 self
.assertTrue(receivedQuery
)
1208 self
.assertTrue(receivedResponse
)
1209 receivedQuery
.id = query
.id
1210 self
.assertEquals(query
, receivedQuery
)
1211 self
.assertEquals(response
, receivedResponse
)
1212 for an
in receivedResponse
.answer
:
1213 self
.assertEquals(an
.ttl
, ttl
)
1216 # next queries should hit the cache
1217 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
1218 self
.assertEquals(receivedResponse
, response
)
1219 for an
in receivedResponse
.answer
:
1220 self
.assertTrue(an
.ttl
<= ttl
)
1222 time
.sleep(self
._maxCacheTTL
+ 1)
1224 # we should not have cached for longer than max cache
1225 # so it should be a miss
1226 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1227 self
.assertTrue(receivedQuery
)
1228 self
.assertTrue(receivedResponse
)
1229 receivedQuery
.id = query
.id
1230 self
.assertEquals(query
, receivedQuery
)
1231 self
.assertEquals(response
, receivedResponse
)
1232 for an
in receivedResponse
.answer
:
1233 self
.assertEquals(an
.ttl
, ttl
)
1237 for key
in self
._responsesCounter
:
1238 total
+= self
._responsesCounter
[key
]
1240 self
.assertEquals(total
, misses
)
1242 class TestCachingFailureTTL(DNSDistTest
):
1244 _failureCacheTTL
= 2
1245 _config_params
= ['_failureCacheTTL', '_testServerPort']
1246 _config_template
= """
1247 pc = newPacketCache(1000, 86400, 0, %d, 60)
1248 getPool(""):setCache(pc)
1249 newServer{address="127.0.0.1:%s"}
1251 def testCacheServFailTTL(self
):
1257 name
= 'servfail.failure.cache.tests.powerdns.com.'
1258 query
= dns
.message
.make_query(name
, 'A', 'IN')
1259 response
= dns
.message
.make_response(query
)
1260 response
.set_rcode(dns
.rcode
.SERVFAIL
)
1263 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1264 self
.assertTrue(receivedQuery
)
1265 self
.assertTrue(receivedResponse
)
1266 receivedQuery
.id = query
.id
1267 self
.assertEquals(query
, receivedQuery
)
1268 self
.assertEquals(response
, receivedResponse
)
1271 # next queries should hit the cache
1272 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
1273 self
.assertEquals(receivedResponse
, response
)
1275 time
.sleep(self
._failureCacheTTL
+ 1)
1277 # we should not have cached for longer than failure cache
1278 # so it should be a miss
1279 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1280 self
.assertTrue(receivedQuery
)
1281 self
.assertTrue(receivedResponse
)
1282 receivedQuery
.id = query
.id
1283 self
.assertEquals(query
, receivedQuery
)
1284 self
.assertEquals(response
, receivedResponse
)
1288 for key
in self
._responsesCounter
:
1289 total
+= self
._responsesCounter
[key
]
1291 self
.assertEquals(total
, misses
)
1293 def testCacheRefusedTTL(self
):
1299 name
= 'refused.failure.cache.tests.powerdns.com.'
1300 query
= dns
.message
.make_query(name
, 'A', 'IN')
1301 response
= dns
.message
.make_response(query
)
1302 response
.set_rcode(dns
.rcode
.REFUSED
)
1305 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1306 self
.assertTrue(receivedQuery
)
1307 self
.assertTrue(receivedResponse
)
1308 receivedQuery
.id = query
.id
1309 self
.assertEquals(query
, receivedQuery
)
1310 self
.assertEquals(response
, receivedResponse
)
1313 # next queries should hit the cache
1314 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
1315 self
.assertEquals(receivedResponse
, response
)
1317 time
.sleep(self
._failureCacheTTL
+ 1)
1319 # we should not have cached for longer than failure cache
1320 # so it should be a miss
1321 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1322 self
.assertTrue(receivedQuery
)
1323 self
.assertTrue(receivedResponse
)
1324 receivedQuery
.id = query
.id
1325 self
.assertEquals(query
, receivedQuery
)
1326 self
.assertEquals(response
, receivedResponse
)
1330 for key
in self
._responsesCounter
:
1331 total
+= self
._responsesCounter
[key
]
1333 self
.assertEquals(total
, misses
)
1335 def testCacheHeaderOnlyRefusedTTL(self
):
1337 Cache: Header-Only Refused TTL
1341 name
= 'header-only-refused.failure.cache.tests.powerdns.com.'
1342 query
= dns
.message
.make_query(name
, 'A', 'IN')
1343 response
= dns
.message
.make_response(query
)
1344 response
.set_rcode(dns
.rcode
.REFUSED
)
1345 response
.question
= []
1348 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1349 self
.assertTrue(receivedQuery
)
1350 self
.assertTrue(receivedResponse
)
1351 receivedQuery
.id = query
.id
1352 self
.assertEquals(query
, receivedQuery
)
1353 self
.assertEquals(response
, receivedResponse
)
1356 # next queries should hit the cache
1357 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
1358 self
.assertEquals(receivedResponse
, response
)
1360 time
.sleep(self
._failureCacheTTL
+ 1)
1362 # we should not have cached for longer than failure cache
1363 # so it should be a miss
1364 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1365 self
.assertTrue(receivedQuery
)
1366 self
.assertTrue(receivedResponse
)
1367 receivedQuery
.id = query
.id
1368 self
.assertEquals(query
, receivedQuery
)
1369 self
.assertEquals(response
, receivedResponse
)
1373 for key
in self
._responsesCounter
:
1374 total
+= self
._responsesCounter
[key
]
1376 self
.assertEquals(total
, misses
)
1378 class TestCachingNegativeTTL(DNSDistTest
):
1381 _config_params
= ['_negCacheTTL', '_testServerPort']
1382 _config_template
= """
1383 pc = newPacketCache(1000, 86400, 0, 60, 60, false, 1, true, %d)
1384 getPool(""):setCache(pc)
1385 newServer{address="127.0.0.1:%s"}
1388 def testCacheNegativeTTLNXDomain(self
):
1390 Cache: Negative TTL on NXDOMAIN
1394 name
= 'nxdomain.negativettl.cache.tests.powerdns.com.'
1395 query
= dns
.message
.make_query(name
, 'A', 'IN')
1396 response
= dns
.message
.make_response(query
)
1397 response
.set_rcode(dns
.rcode
.NXDOMAIN
)
1398 soa
= dns
.rrset
.from_text(name
,
1402 'ns.' + name
+ ' hostmaster.' + name
+ ' 1 3600 3600 3600 60')
1403 response
.authority
.append(soa
)
1406 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1407 self
.assertTrue(receivedQuery
)
1408 self
.assertTrue(receivedResponse
)
1409 receivedQuery
.id = query
.id
1410 self
.assertEquals(query
, receivedQuery
)
1411 self
.assertEquals(response
, receivedResponse
)
1414 # next queries should hit the cache
1415 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
1416 self
.assertEquals(receivedResponse
, response
)
1418 time
.sleep(self
._negCacheTTL
+ 1)
1420 # we should not have cached for longer than the negativel TTL
1421 # so it should be a miss
1422 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1423 self
.assertTrue(receivedQuery
)
1424 self
.assertTrue(receivedResponse
)
1425 receivedQuery
.id = query
.id
1426 self
.assertEquals(query
, receivedQuery
)
1427 self
.assertEquals(response
, receivedResponse
)
1431 for key
in self
._responsesCounter
:
1432 total
+= self
._responsesCounter
[key
]
1434 self
.assertEquals(total
, misses
)
1436 def testCacheNegativeTTLNoData(self
):
1438 Cache: Negative TTL on NoData
1442 name
= 'nodata.negativettl.cache.tests.powerdns.com.'
1443 query
= dns
.message
.make_query(name
, 'A', 'IN')
1444 response
= dns
.message
.make_response(query
)
1445 response
.set_rcode(dns
.rcode
.NOERROR
)
1446 soa
= dns
.rrset
.from_text(name
,
1450 'ns.' + name
+ ' hostmaster.' + name
+ ' 1 3600 3600 3600 60')
1451 response
.authority
.append(soa
)
1454 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1455 self
.assertTrue(receivedQuery
)
1456 self
.assertTrue(receivedResponse
)
1457 receivedQuery
.id = query
.id
1458 self
.assertEquals(query
, receivedQuery
)
1459 self
.assertEquals(response
, receivedResponse
)
1462 # next queries should hit the cache
1463 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
1464 self
.assertEquals(receivedResponse
, response
)
1466 time
.sleep(self
._negCacheTTL
+ 1)
1468 # we should not have cached for longer than the negativel TTL
1469 # so it should be a miss
1470 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1471 self
.assertTrue(receivedQuery
)
1472 self
.assertTrue(receivedResponse
)
1473 receivedQuery
.id = query
.id
1474 self
.assertEquals(query
, receivedQuery
)
1475 self
.assertEquals(response
, receivedResponse
)
1479 for key
in self
._responsesCounter
:
1480 total
+= self
._responsesCounter
[key
]
1482 self
.assertEquals(total
, misses
)
1484 class TestCachingDontAge(DNSDistTest
):
1486 _config_template
= """
1487 pc = newPacketCache(100, 86400, 0, 60, 60, true)
1488 getPool(""):setCache(pc)
1489 newServer{address="127.0.0.1:%s"}
1491 def testCacheDoesntDecreaseTTL(self
):
1493 Cache: Cache doesn't decrease TTL with 'don't age' set
1495 dnsdist is configured to cache entries but without aging the TTL,
1496 we are sending one request (cache miss) and verify that the cache
1497 hits don't have a decreasing TTL.
1501 name
= 'cachedoesntdecreasettl.cache-dont-age.tests.powerdns.com.'
1502 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
1503 response
= dns
.message
.make_response(query
)
1504 rrset
= dns
.rrset
.from_text(name
,
1509 response
.answer
.append(rrset
)
1511 # first query to fill the cache
1512 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1513 self
.assertTrue(receivedQuery
)
1514 self
.assertTrue(receivedResponse
)
1515 receivedQuery
.id = query
.id
1516 self
.assertEquals(query
, receivedQuery
)
1517 self
.assertEquals(receivedResponse
, response
)
1520 # next queries should hit the cache
1521 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
1522 self
.assertEquals(receivedResponse
, response
)
1523 for an
in receivedResponse
.answer
:
1524 self
.assertTrue(an
.ttl
== ttl
)
1526 # now we wait a bit for the TTL to decrease
1529 # next queries should hit the cache
1530 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
1531 self
.assertEquals(receivedResponse
, response
)
1532 for an
in receivedResponse
.answer
:
1533 self
.assertTrue(an
.ttl
== ttl
)
1536 for key
in self
._responsesCounter
:
1537 total
+= self
._responsesCounter
[key
]
1539 self
.assertEquals(total
, misses
)
1541 class TestCachingECSWithoutPoolECS(DNSDistTest
):
1543 _consoleKey
= DNSDistTest
.generateConsoleKey()
1544 _consoleKeyB64
= base64
.b64encode(_consoleKey
).decode('ascii')
1545 _config_params
= ['_consoleKeyB64', '_consolePort', '_testServerPort']
1546 _config_template
= """
1547 pc = newPacketCache(100, 86400, 1)
1548 getPool(""):setCache(pc)
1550 controlSocket("127.0.0.1:%d")
1551 newServer{address="127.0.0.1:%d", useClientSubnet=true}
1554 def testCached(self
):
1556 Cache: Cached entry with ECS is a miss when no backend are available
1559 name
= 'cached.cache-ecs-without-pool-ecs.tests.powerdns.com.'
1560 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
1561 response
= dns
.message
.make_response(query
)
1562 rrset
= dns
.rrset
.from_text(name
,
1567 response
.answer
.append(rrset
)
1569 # first query to fill the cache
1570 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1571 self
.assertTrue(receivedQuery
)
1572 self
.assertTrue(receivedResponse
)
1573 receivedQuery
.id = query
.id
1574 self
.assertEquals(query
, receivedQuery
)
1575 self
.assertEquals(receivedResponse
, response
)
1576 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
1577 self
.assertTrue(receivedQuery
)
1578 self
.assertTrue(receivedResponse
)
1579 receivedQuery
.id = query
.id
1580 self
.assertEquals(query
, receivedQuery
)
1581 self
.assertEquals(receivedResponse
, response
)
1583 # next queries should hit the cache
1584 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
1585 self
.assertEquals(receivedResponse
, response
)
1588 (_
, receivedResponse
) = self
.sendTCPQuery(query
, response
=None, useQueue
=False)
1589 self
.assertEquals(receivedResponse
, response
)
1591 # we mark the backend as down
1592 self
.sendConsoleCommand("getServer(0):setDown()")
1594 # we should NOT get a cached entry since it has ECS and we haven't asked the pool
1595 # to add ECS when no backend is up
1596 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
1597 self
.assertEquals(receivedResponse
, None)
1600 (_
, receivedResponse
) = self
.sendTCPQuery(query
, response
=None, useQueue
=False)
1601 self
.assertEquals(receivedResponse
, None)
1603 class TestCachingECSWithPoolECS(DNSDistTest
):
1605 _consoleKey
= DNSDistTest
.generateConsoleKey()
1606 _consoleKeyB64
= base64
.b64encode(_consoleKey
).decode('ascii')
1607 _config_params
= ['_consoleKeyB64', '_consolePort', '_testServerPort']
1608 _config_template
= """
1609 pc = newPacketCache(100, 86400, 1)
1610 getPool(""):setCache(pc)
1611 getPool(""):setECS(true)
1613 controlSocket("127.0.0.1:%d")
1614 newServer{address="127.0.0.1:%d", useClientSubnet=true}
1617 def testCached(self
):
1619 Cache: Cached entry with ECS is a hit when no backend are available
1622 name
= 'cached.cache-ecs-with-pool-ecs.tests.powerdns.com.'
1623 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
1624 response
= dns
.message
.make_response(query
)
1625 rrset
= dns
.rrset
.from_text(name
,
1630 response
.answer
.append(rrset
)
1632 # first query to fill the cache
1633 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1634 self
.assertTrue(receivedQuery
)
1635 self
.assertTrue(receivedResponse
)
1636 receivedQuery
.id = query
.id
1637 self
.assertEquals(query
, receivedQuery
)
1638 self
.assertEquals(receivedResponse
, response
)
1639 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
1640 self
.assertTrue(receivedQuery
)
1641 self
.assertTrue(receivedResponse
)
1642 receivedQuery
.id = query
.id
1643 self
.assertEquals(query
, receivedQuery
)
1644 self
.assertEquals(receivedResponse
, response
)
1646 # next queries should hit the cache
1647 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
1648 self
.assertEquals(receivedResponse
, response
)
1651 (_
, receivedResponse
) = self
.sendTCPQuery(query
, response
=None, useQueue
=False)
1652 self
.assertEquals(receivedResponse
, response
)
1654 # we mark the backend as down
1655 self
.sendConsoleCommand("getServer(0):setDown()")
1657 # we should STILL get a cached entry since it has ECS and we have asked the pool
1658 # to add ECS when no backend is up
1659 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
1660 self
.assertEquals(receivedResponse
, response
)
1663 (_
, receivedResponse
) = self
.sendTCPQuery(query
, response
=None, useQueue
=False)
1664 self
.assertEquals(receivedResponse
, response
)
1666 class TestCachingCollisionNoECSParsing(DNSDistTest
):
1668 _config_template
= """
1669 pc = newPacketCache(100, 86400, 1)
1670 getPool(""):setCache(pc)
1671 newServer{address="127.0.0.1:%s"}
1674 def testCacheCollisionNoECSParsing(self
):
1676 Cache: Collision with no ECS parsing
1678 name
= 'collision-no-ecs-parsing.cache.tests.powerdns.com.'
1679 ecso
= clientsubnetoption
.ClientSubnetOption('10.0.188.3', 32)
1680 query
= dns
.message
.make_query(name
, 'AAAA', 'IN', use_edns
=True, options
=[ecso
], payload
=512)
1681 query
.flags
= dns
.flags
.RD
1682 response
= dns
.message
.make_response(query
)
1683 rrset
= dns
.rrset
.from_text(name
,
1688 response
.answer
.append(rrset
)
1690 # first query should to fill the cache
1691 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1692 self
.assertTrue(receivedQuery
)
1693 self
.assertTrue(receivedResponse
)
1694 receivedQuery
.id = query
.id
1695 self
.assertEquals(query
, receivedQuery
)
1696 self
.assertEquals(receivedResponse
, response
)
1698 # second query will hash to the same key, triggering a collision which
1699 # will not be detected because the qname, qtype, qclass and flags will
1700 # match and EDNS Client Subnet parsing has not been enabled
1701 ecso2
= clientsubnetoption
.ClientSubnetOption('10.0.192.138', 32)
1702 query2
= dns
.message
.make_query(name
, 'AAAA', 'IN', use_edns
=True, options
=[ecso2
], payload
=512)
1703 query2
.flags
= dns
.flags
.RD
1704 (_
, receivedResponse
) = self
.sendUDPQuery(query2
, response
=None, useQueue
=False)
1705 receivedResponse
.id = response
.id
1706 self
.assertEquals(receivedResponse
, response
)
1708 class TestCachingCollisionWithECSParsing(DNSDistTest
):
1710 _config_template
= """
1711 pc = newPacketCache(100, 86400, 1, 60, 60, false, 1, true, 3600, true)
1712 getPool(""):setCache(pc)
1713 newServer{address="127.0.0.1:%s"}
1716 def testCacheCollisionWithECSParsing(self
):
1718 Cache: Collision with ECS parsing
1720 name
= 'collision-with-ecs-parsing.cache.tests.powerdns.com.'
1721 ecso
= clientsubnetoption
.ClientSubnetOption('10.0.115.61', 32)
1722 query
= dns
.message
.make_query(name
, 'AAAA', 'IN', use_edns
=True, options
=[ecso
], payload
=512)
1723 query
.flags
= dns
.flags
.RD
1724 response
= dns
.message
.make_response(query
)
1725 rrset
= dns
.rrset
.from_text(name
,
1730 response
.answer
.append(rrset
)
1732 # first query should to fill the cache
1733 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1734 self
.assertTrue(receivedQuery
)
1735 self
.assertTrue(receivedResponse
)
1736 receivedQuery
.id = query
.id
1737 self
.assertEquals(query
, receivedQuery
)
1738 self
.assertEquals(receivedResponse
, response
)
1740 # second query will hash to the same key, triggering a collision which
1741 # _will_ be detected this time because the qname, qtype, qclass and flags will
1742 # match but EDNS Client Subnet parsing is now enabled and will detect the issue
1743 ecso2
= clientsubnetoption
.ClientSubnetOption('10.0.143.21', 32)
1744 query2
= dns
.message
.make_query(name
, 'AAAA', 'IN', use_edns
=True, options
=[ecso2
], payload
=512)
1745 query2
.flags
= dns
.flags
.RD
1746 response2
= dns
.message
.make_response(query2
)
1747 rrset
= dns
.rrset
.from_text(name
,
1752 response2
.answer
.append(rrset
)
1753 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query2
, response2
)
1754 self
.assertEquals(receivedResponse
, response2
)
1756 class TestCachingScopeZero(DNSDistTest
):
1758 _config_template
= """
1759 -- Be careful to enable ECS parsing in the packet cache, otherwise scope zero is disabled
1760 pc = newPacketCache(100, 86400, 1, 60, 60, false, 1, true, 3600, true)
1761 getPool(""):setCache(pc)
1762 newServer{address="127.0.0.1:%d", useClientSubnet=true}
1763 -- to simulate a second client coming from a different IP address,
1764 -- we will force the ECS value added to the query if RD is set (note that we need
1765 -- to unset it using rules before the first cache lookup)
1766 addAction(RDRule(), SetECSAction("192.0.2.1/32"))
1767 addAction(RDRule(), NoRecurseAction())
1770 def testScopeZero(self
):
1772 Cache: Test the scope-zero feature, backend returns a scope of zero
1775 name
= 'scope-zero.cache.tests.powerdns.com.'
1776 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
1777 query
.flags
&= ~dns
.flags
.RD
1778 ecso
= clientsubnetoption
.ClientSubnetOption('127.0.0.0', 24)
1779 expectedQuery
= dns
.message
.make_query(name
, 'AAAA', 'IN', use_edns
=True, options
=[ecso
], payload
=512)
1780 expectedQuery
.flags
&= ~dns
.flags
.RD
1781 ecsoResponse
= clientsubnetoption
.ClientSubnetOption('127.0.0.1', 24, 0)
1782 expectedResponse
= dns
.message
.make_response(query
)
1783 scopedResponse
= dns
.message
.make_response(query
)
1784 scopedResponse
.use_edns(edns
=True, payload
=4096, options
=[ecsoResponse
])
1785 rrset
= dns
.rrset
.from_text(name
,
1790 scopedResponse
.answer
.append(rrset
)
1791 expectedResponse
.answer
.append(rrset
)
1793 for method
in ("sendUDPQuery", "sendTCPQuery"):
1794 sender
= getattr(self
, method
)
1795 (receivedQuery
, receivedResponse
) = sender(query
, scopedResponse
)
1796 receivedQuery
.id = expectedQuery
.id
1797 self
.checkMessageEDNSWithECS(expectedQuery
, receivedQuery
)
1798 self
.checkMessageNoEDNS(receivedResponse
, expectedResponse
)
1800 # next query should hit the cache, nothing special about that
1801 for method
in ("sendUDPQuery", "sendTCPQuery"):
1802 sender
= getattr(self
, method
)
1803 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1804 self
.checkMessageNoEDNS(receivedResponse
, expectedResponse
)
1806 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
1807 query
.flags
&= dns
.flags
.RD
1808 # next query FROM A DIFFERENT CLIENT since RD is now set should STILL hit the cache
1809 for method
in ("sendUDPQuery", "sendTCPQuery"):
1810 sender
= getattr(self
, method
)
1811 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1812 receivedResponse
.id = expectedResponse
.id
1813 self
.checkMessageNoEDNS(receivedResponse
, expectedResponse
)
1815 name
= 'scope-zero-with-ecs.cache.tests.powerdns.com.'
1816 ecso
= clientsubnetoption
.ClientSubnetOption('127.0.0.1', 24)
1817 query
= dns
.message
.make_query(name
, 'AAAA', 'IN', use_edns
=True, options
=[ecso
], payload
=512)
1818 query
.flags
&= ~dns
.flags
.RD
1819 expectedQuery
= dns
.message
.make_query(name
, 'AAAA', 'IN', use_edns
=True, options
=[ecso
], payload
=512)
1820 expectedQuery
.flags
&= ~dns
.flags
.RD
1821 expectedResponse
= dns
.message
.make_response(query
)
1822 expectedResponse
.use_edns(edns
=True, payload
=4096, options
=[ecsoResponse
])
1823 expectedResponse
.answer
.append(rrset
)
1824 scopedResponse
= dns
.message
.make_response(query
)
1825 scopedResponse
.use_edns(edns
=True, payload
=4096, options
=[ecsoResponse
])
1826 scopedResponse
.answer
.append(rrset
)
1827 # this query has ECS, it should NOT be able to use the scope-zero cached entry since the hash will be
1829 for method
in ("sendUDPQuery", "sendTCPQuery"):
1830 sender
= getattr(self
, method
)
1831 (receivedQuery
, receivedResponse
) = sender(query
, scopedResponse
)
1832 receivedQuery
.id = expectedQuery
.id
1833 self
.checkMessageEDNSWithECS(expectedQuery
, receivedQuery
)
1834 self
.checkMessageEDNSWithECS(receivedResponse
, expectedResponse
)
1836 # it should still have been cached, though, so the next query should be a hit
1837 for method
in ("sendUDPQuery", "sendTCPQuery"):
1838 sender
= getattr(self
, method
)
1839 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1840 self
.checkMessageEDNSWithECS(receivedResponse
, expectedResponse
)
1842 def testScopeNotZero(self
):
1844 Cache: Test the scope-zero feature, backend returns a scope of non-zero
1847 name
= 'scope-not-zero.cache.tests.powerdns.com.'
1848 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
1849 query
.flags
&= ~dns
.flags
.RD
1850 ecso
= clientsubnetoption
.ClientSubnetOption('127.0.0.0', 24)
1851 expectedQuery
= dns
.message
.make_query(name
, 'AAAA', 'IN', use_edns
=True, options
=[ecso
], payload
=512)
1852 expectedQuery
.flags
&= ~dns
.flags
.RD
1853 ecso2
= clientsubnetoption
.ClientSubnetOption('192.0.2.1', 32)
1854 expectedQuery2
= dns
.message
.make_query(name
, 'AAAA', 'IN', use_edns
=True, options
=[ecso2
], payload
=512)
1855 expectedQuery2
.flags
&= ~dns
.flags
.RD
1856 ecsoResponse
= clientsubnetoption
.ClientSubnetOption('127.0.0.1', 24, 24)
1857 ecsoResponse2
= clientsubnetoption
.ClientSubnetOption('192.0.2.1', 32, 24)
1858 rrset
= dns
.rrset
.from_text(name
,
1863 expectedResponse
= dns
.message
.make_response(query
)
1864 expectedResponse
.answer
.append(rrset
)
1865 scopedResponse
= dns
.message
.make_response(query
)
1866 scopedResponse
.use_edns(edns
=True, payload
=4096, options
=[ecsoResponse
])
1867 scopedResponse
.answer
.append(rrset
)
1868 scopedResponse2
= dns
.message
.make_response(query
)
1869 scopedResponse2
.use_edns(edns
=True, payload
=4096, options
=[ecsoResponse2
])
1870 scopedResponse2
.answer
.append(rrset
)
1872 for method
in ("sendUDPQuery", "sendTCPQuery"):
1873 sender
= getattr(self
, method
)
1874 (receivedQuery
, receivedResponse
) = sender(query
, scopedResponse
)
1875 receivedQuery
.id = expectedQuery
.id
1876 self
.checkMessageEDNSWithECS(expectedQuery
, receivedQuery
)
1877 self
.checkMessageNoEDNS(receivedResponse
, expectedResponse
)
1879 # next query should hit the cache, nothing special about that
1880 for method
in ("sendUDPQuery", "sendTCPQuery"):
1881 sender
= getattr(self
, method
)
1882 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1883 self
.checkMessageNoEDNS(receivedResponse
, expectedResponse
)
1885 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
1886 query
.flags
&= dns
.flags
.RD
1887 expectedResponse
= dns
.message
.make_response(query
)
1888 expectedResponse
.answer
.append(rrset
)
1889 # next query FROM A DIFFERENT CLIENT since RD is now set should NOT hit the cache
1890 for method
in ("sendUDPQuery", "sendTCPQuery"):
1891 sender
= getattr(self
, method
)
1892 (receivedQuery
, receivedResponse
) = sender(query
, scopedResponse2
)
1893 receivedQuery
.id = expectedQuery2
.id
1894 self
.checkMessageEDNSWithECS(expectedQuery2
, receivedQuery
)
1895 self
.checkMessageNoEDNS(receivedResponse
, expectedResponse
)
1897 def testNoECS(self
):
1899 Cache: Test the scope-zero feature, backend returns no ECS at all
1902 name
= 'scope-zero-no-ecs.cache.tests.powerdns.com.'
1903 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
1904 query
.flags
&= ~dns
.flags
.RD
1905 ecso
= clientsubnetoption
.ClientSubnetOption('127.0.0.0', 24)
1906 expectedQuery
= dns
.message
.make_query(name
, 'AAAA', 'IN', use_edns
=True, options
=[ecso
], payload
=512)
1907 expectedQuery
.flags
&= ~dns
.flags
.RD
1908 ecso2
= clientsubnetoption
.ClientSubnetOption('192.0.2.1', 32)
1909 expectedQuery2
= dns
.message
.make_query(name
, 'AAAA', 'IN', use_edns
=True, options
=[ecso2
], payload
=512)
1910 expectedQuery2
.flags
&= ~dns
.flags
.RD
1911 rrset
= dns
.rrset
.from_text(name
,
1916 response
= dns
.message
.make_response(query
)
1917 response
.answer
.append(rrset
)
1919 for method
in ("sendUDPQuery", "sendTCPQuery"):
1920 sender
= getattr(self
, method
)
1921 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1922 receivedQuery
.id = expectedQuery
.id
1923 self
.checkMessageEDNSWithECS(expectedQuery
, receivedQuery
)
1924 self
.checkMessageNoEDNS(receivedResponse
, response
)
1926 # next query should hit the cache, nothing special about that
1927 for method
in ("sendUDPQuery", "sendTCPQuery"):
1928 sender
= getattr(self
, method
)
1929 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1930 self
.checkMessageNoEDNS(receivedResponse
, response
)
1932 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
1933 query
.flags
&= dns
.flags
.RD
1934 response
= dns
.message
.make_response(query
)
1935 response
.answer
.append(rrset
)
1936 # next query FROM A DIFFERENT CLIENT since RD is now set should NOT hit the cache
1937 for method
in ("sendUDPQuery", "sendTCPQuery"):
1938 sender
= getattr(self
, method
)
1939 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1940 receivedQuery
.id = expectedQuery2
.id
1941 self
.checkMessageEDNSWithECS(expectedQuery2
, receivedQuery
)
1942 self
.checkMessageNoEDNS(receivedResponse
, response
)
1944 class TestCachingScopeZeroButNoSubnetcheck(DNSDistTest
):
1946 _config_template
= """
1947 -- We disable ECS parsing in the packet cache, meaning scope zero is disabled
1948 pc = newPacketCache(100, 86400, 1, 60, 60, false, 1, true, 3600, false)
1949 getPool(""):setCache(pc)
1950 newServer{address="127.0.0.1:%d", useClientSubnet=true}
1951 -- to simulate a second client coming from a different IP address,
1952 -- we will force the ECS value added to the query if RD is set (note that we need
1953 -- to unset it using rules before the first cache lookup)
1954 addAction(RDRule(), SetECSAction("192.0.2.1/32"))
1955 addAction(RDRule(), NoRecurseAction())
1958 def testScopeZero(self
):
1960 Cache: Test that the scope-zero feature is disabled when ECS parsing is not enabled in the cache
1963 name
= 'scope-zero-no-subnet.cache.tests.powerdns.com.'
1964 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
1965 query
.flags
&= ~dns
.flags
.RD
1966 ecso
= clientsubnetoption
.ClientSubnetOption('127.0.0.0', 24)
1967 expectedQuery
= dns
.message
.make_query(name
, 'AAAA', 'IN', use_edns
=True, options
=[ecso
], payload
=512)
1968 expectedQuery
.flags
&= ~dns
.flags
.RD
1969 ecso2
= clientsubnetoption
.ClientSubnetOption('192.0.2.1', 32)
1970 expectedQuery2
= dns
.message
.make_query(name
, 'AAAA', 'IN', use_edns
=True, options
=[ecso2
], payload
=512)
1971 expectedQuery2
.flags
&= ~dns
.flags
.RD
1972 ecsoResponse
= clientsubnetoption
.ClientSubnetOption('127.0.0.1', 24, 0)
1973 expectedResponse
= dns
.message
.make_response(query
)
1974 scopedResponse
= dns
.message
.make_response(query
)
1975 scopedResponse
.use_edns(edns
=True, payload
=4096, options
=[ecsoResponse
])
1976 rrset
= dns
.rrset
.from_text(name
,
1981 scopedResponse
.answer
.append(rrset
)
1982 expectedResponse
.answer
.append(rrset
)
1984 for method
in ("sendUDPQuery", "sendTCPQuery"):
1985 sender
= getattr(self
, method
)
1986 (receivedQuery
, receivedResponse
) = sender(query
, scopedResponse
)
1987 receivedQuery
.id = expectedQuery
.id
1988 self
.checkMessageEDNSWithECS(expectedQuery
, receivedQuery
)
1989 self
.checkMessageNoEDNS(receivedResponse
, expectedResponse
)
1991 # next query should hit the cache, nothing special about that
1992 for method
in ("sendUDPQuery", "sendTCPQuery"):
1993 sender
= getattr(self
, method
)
1994 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1995 self
.checkMessageNoEDNS(receivedResponse
, expectedResponse
)
1997 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
1998 query
.flags
&= dns
.flags
.RD
1999 response
= dns
.message
.make_response(query
)
2000 response
.answer
.append(rrset
)
2001 # next query FROM A DIFFERENT CLIENT since RD is now set should NOT hit the cache
2002 for method
in ("sendUDPQuery", "sendTCPQuery"):
2003 sender
= getattr(self
, method
)
2004 (receivedQuery
, receivedResponse
) = sender(query
, response
)
2005 receivedQuery
.id = expectedQuery2
.id
2006 self
.checkMessageEDNSWithECS(expectedQuery2
, receivedQuery
)
2007 self
.checkMessageNoEDNS(receivedResponse
, response
)