From 619732813a1344ff53131dbd07ab711f29b054f9 Mon Sep 17 00:00:00 2001 From: Bert Hubert Date: Fri, 19 May 2006 13:29:36 +0000 Subject: [PATCH] fix 'perpetually self-reviving NS records', as noted by Darren Gamble, see http://mailman.powerdns.com/pipermail/pdns-users/2006-May/003413.html git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@837 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- pdns/pdns_recursor.cc | 6 +++--- pdns/recursor_cache.cc | 5 ++++- pdns/recursor_cache.hh | 2 +- pdns/syncres.cc | 10 +++++----- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 62a14eb6a..dd9c4717f 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -415,7 +415,7 @@ void primeHints(void) arr.content=ips[c-'a']; set aset; aset.insert(arr); - RC.replace(string(templ), QType(QType::A), aset, true); // auth, nuke it all + RC.replace(time(0), string(templ), QType(QType::A), aset, true); // auth, nuke it all nsset.insert(nsrr); } @@ -430,7 +430,7 @@ void primeHints(void) if(rr.qtype.getCode()==QType::A) { set aset; aset.insert(rr); - RC.replace(rr.qname, QType(QType::A), aset, true); // auth, etc see above + RC.replace(time(0), rr.qname, QType(QType::A), aset, true); // auth, etc see above } if(rr.qtype.getCode()==QType::NS) { rr.content=toLower(rr.content); @@ -438,7 +438,7 @@ void primeHints(void) } } } - RC.replace(".", QType(QType::NS), nsset, true); // and stuff in the cache (auth) + RC.replace(time(0),".", QType(QType::NS), nsset, true); // and stuff in the cache (auth) } map g_tcpClientCounts; diff --git a/pdns/recursor_cache.cc b/pdns/recursor_cache.cc index 7f7dfeb70..af1b0ec4f 100644 --- a/pdns/recursor_cache.cc +++ b/pdns/recursor_cache.cc @@ -198,7 +198,7 @@ int MemRecursorCache::get(time_t now, const string &qname, const QType& qt, set< /* the code below is rather tricky - it basically replaces the stuff cached for qname by content, but it is special cased for when inserting identical records with only differing ttls, in which case the entry is not touched, but only given a new ttd */ -void MemRecursorCache::replace(const string &qname, const QType& qt, const set& content, bool auth) +void MemRecursorCache::replace(time_t now, const string &qname, const QType& qt, const set& content, bool auth) { d_cachecachevalid=false; tuple key=make_tuple(qname, qt.getCode()); @@ -232,6 +232,9 @@ void MemRecursorCache::replace(const string &qname, const QType& qt, const set< if(range.first != range.second) { for(vector::iterator j=range.first ; j!=range.second; ++j) { + /* see http://mailman.powerdns.com/pipermail/pdns-users/2006-May/003413.html */ + if(j->d_ttd > now && i->ttl > j->d_ttd && qt.getCode()==QType::NS && auth) // don't allow auth servers to *raise* TTL of an NS record + continue; if(i->ttl > j->d_ttd || auth) // authoritative packets can override the TTL to be lower j->d_ttd=i->ttl; } diff --git a/pdns/recursor_cache.hh b/pdns/recursor_cache.hh index 97aaf2ade..e6132fc6b 100644 --- a/pdns/recursor_cache.hh +++ b/pdns/recursor_cache.hh @@ -32,7 +32,7 @@ public: unsigned int size(); unsigned int bytes(); int get(time_t, const string &qname, const QType& qt, set* res); - void replace(const string &qname, const QType& qt, const set& content, bool auth); + void replace(time_t, const string &qname, const QType& qt, const set& content, bool auth); void doPrune(void); void doSlash(int perc); void doDumpAndClose(int fd); diff --git a/pdns/syncres.cc b/pdns/syncres.cc index a63a8da19..7ca6a3bf4 100644 --- a/pdns/syncres.cc +++ b/pdns/syncres.cc @@ -288,7 +288,7 @@ void SyncRes::getBestNSFromCache(const string &qname, set&bes LOG<<", in cache, ttl="<<(unsigned int)(((time_t)aset.begin()->ttl- d_now.tv_sec ))< nameservers, string auth, DNSResourceRecord rr=*i; rr.d_place=DNSResourceRecord::ANSWER; - // if(rr.ttl < 5) - // rr.ttl=60; + rr.ttl=min(86400*14U, rr.ttl); // limit TTL to two weeks rr.ttl += d_now.tv_sec; + if(rr.qtype.getCode() == QType::NS) // people fiddle with the case - rr.content=toLower(rr.content); // this must stay! + rr.content=toLower(rr.content); // this must stay! (the cache can't be case-insensitive on the RHS of records) tcache[make_pair(i->qname,i->qtype)].insert(rr); } } @@ -725,7 +725,7 @@ int SyncRes::doResolveAt(set nameservers, string auth, ((tcache_t::value_type::second_type::value_type*)&(*j))->ttl=lowestTTL; } - RC.replace(i->first.first, i->first.second, i->second, d_lwr.d_aabit); + RC.replace(d_now.tv_sec, i->first.first, i->first.second, i->second, d_lwr.d_aabit); } set nsset; LOG<