From a3824e4306892da907960052665644c6f1442465 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 8 Feb 2017 17:19:18 +0100 Subject: [PATCH] dnsdist: Don't cache answers without any TTL `RFC2308` states that "negative responses without SOA records SHOULD NOT be cached as there is no way to prevent the negative responses looping forever between a pair of servers even with a short TTL". --- pdns/dnsdist-cache.cc | 9 +++++- regression-tests.dnsdist/test_Caching.py | 35 ++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/pdns/dnsdist-cache.cc b/pdns/dnsdist-cache.cc index 24bd53fe39..ec3358795f 100644 --- a/pdns/dnsdist-cache.cc +++ b/pdns/dnsdist-cache.cc @@ -56,8 +56,15 @@ void DNSDistPacketCache::insert(uint32_t key, const DNSName& qname, uint16_t qty } else { minTTL = getMinTTL(response, responseLen); - if (minTTL > d_maxTTL) + + /* no TTL found, we don't want to cache this */ + if (minTTL == std::numeric_limits::max()) { + return; + } + + if (minTTL > d_maxTTL) { minTTL = d_maxTTL; + } if (minTTL < d_minTTL) { d_ttlTooShorts++; diff --git a/regression-tests.dnsdist/test_Caching.py b/regression-tests.dnsdist/test_Caching.py index 46d3329ae8..832ca80af2 100644 --- a/regression-tests.dnsdist/test_Caching.py +++ b/regression-tests.dnsdist/test_Caching.py @@ -874,6 +874,41 @@ class TestCachingTTL(DNSDistTest): self.assertEquals(total, misses) + def testCacheNXWithNoRR(self): + """ + Cache: NX with no RR + + """ + misses = 0 + name = 'nxwithnorr.cache.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN') + response = dns.message.make_response(query) + response.set_rcode(dns.rcode.NXDOMAIN) + + # Miss + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + self.assertTrue(receivedQuery) + self.assertTrue(receivedResponse) + receivedQuery.id = query.id + self.assertEquals(query, receivedQuery) + self.assertEquals(response, receivedResponse) + misses += 1 + + # We should not have been cached + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + self.assertTrue(receivedQuery) + self.assertTrue(receivedResponse) + receivedQuery.id = query.id + self.assertEquals(query, receivedQuery) + self.assertEquals(response, receivedResponse) + misses += 1 + + total = 0 + for key in self._responsesCounter: + total += self._responsesCounter[key] + + self.assertEquals(total, misses) + class TestCachingLongTTL(DNSDistTest): _maxCacheTTL = 2 -- 2.47.2