From: Peter van Dijk Date: Mon, 21 Jan 2013 13:07:31 +0000 (+0000) Subject: doAgeCache would sometimes get confused when we mixed expired and non-expired records... X-Git-Tag: rec-3.5-rc1~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e06f9f151170fb15fc4f2d9f97c0e65acc85a8c2;p=thirdparty%2Fpdns.git doAgeCache would sometimes get confused when we mixed expired and non-expired records. Report and patch by Winfried Angele. Closes #438 git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@3068 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- diff --git a/pdns/recursor_cache.cc b/pdns/recursor_cache.cc index 2efebf9ef3..c96fd2f4e8 100644 --- a/pdns/recursor_cache.cc +++ b/pdns/recursor_cache.cc @@ -299,22 +299,34 @@ int MemRecursorCache::doWipeCache(const string& name, uint16_t qtype) bool MemRecursorCache::doAgeCache(time_t now, const string& name, uint16_t qtype, int32_t newTTL) { cache_t::iterator iter = d_cache.find(tie(name, qtype)); - if(iter == d_cache.end()) + uint32_t maxTTD=std::numeric_limits::min(); + if(iter == d_cache.end()) { return false; + } + + CacheEntry ce = *iter; + + if(ce.d_records.size()==1) { + maxTTD=ce.d_records.begin()->d_ttd; + } + else { // find the LATEST ttd + for(vector::const_iterator i=ce.d_records.begin(); i != ce.d_records.end(); ++i) + maxTTD=max(maxTTD, i->d_ttd); + } + + int32_t maxTTL = maxTTD - now; - int32_t ttl = iter->getTTD() - now; - if(ttl < 0) + if(maxTTL < 0) return false; // would be dead anyhow - if(ttl > newTTL) { + if(maxTTL > newTTL) { d_cachecachevalid=false; - ttl = newTTL; - uint32_t newTTD = now + ttl; + uint32_t newTTD = now + newTTL; - CacheEntry ce = *iter; for(vector::iterator j = ce.d_records.begin() ; j != ce.d_records.end(); ++j) { - j->d_ttd = newTTD; + if(j->d_ttd>newTTD) // do never renew expired or older TTLs + j->d_ttd = newTTD; } d_cache.replace(iter, ce);