From: bert hubert Date: Tue, 31 May 2016 15:02:13 +0000 (+0200) Subject: yolocommit, but it does track a zone. Once. X-Git-Tag: rec-4.0.0-rc1~4^2~7 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cd189f245337b180d90b6a66307f51e2d762f1fe;p=pdns yolocommit, but it does track a zone. Once. --- diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 4434692c6..ff5dd7c80 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -165,6 +165,7 @@ pdns_server_SOURCES = \ ednssubnet.cc ednssubnet.hh \ gss_context.cc gss_context.hh \ iputils.cc iputils.hh \ + ixfr.cc ixfr.hh \ json.cc json.hh \ lock.hh \ logger.cc logger.hh \ diff --git a/pdns/communicator.cc b/pdns/communicator.cc index 28543082c..cba4180e2 100644 --- a/pdns/communicator.cc +++ b/pdns/communicator.cc @@ -52,7 +52,7 @@ void CommunicatorClass::retrievalLoopThread(void) sr=d_suckdomains.front(); d_suckdomains.pop_front(); } - suck(sr.domain,sr.master); + suck(sr.domain, sr.master, sr.currentSerial ? &sr.currentSerial : 0); } } diff --git a/pdns/communicator.hh b/pdns/communicator.hh index b4356d9ad..a1e84319f 100644 --- a/pdns/communicator.hh +++ b/pdns/communicator.hh @@ -46,6 +46,7 @@ struct SuckRequest { DNSName domain; string master; + uint32_t currentSerial; bool operator<(const SuckRequest& b) const { return tie(domain, master) < tie(b.domain, b.master); @@ -164,7 +165,7 @@ public: void drillHole(const DNSName &domain, const string &ip); bool justNotified(const DNSName &domain, const string &ip); - void addSuckRequest(const DNSName &domain, const string &master); + void addSuckRequest(const DNSName &domain, const string &master, uint32_t curser); void addSlaveCheckRequest(const DomainInfo& di, const ComboAddress& remote); void addTrySuperMasterRequest(DNSPacket *p); void notify(const DNSName &domain, const string &ip); @@ -190,7 +191,9 @@ private: map,time_t>d_holes; pthread_mutex_t d_holelock; void launchRetrievalThreads(); - void suck(const DNSName &domain, const string &remote); + void suck(const DNSName &domain, const string &remote, uint32_t* curser); + void ixfrSuck(const DNSName &domain, const string &remote, uint32_t curser); + void slaveRefresh(PacketHandler *P); void masterUpdateCheck(PacketHandler *P); pthread_mutex_t d_lock; diff --git a/pdns/dynhandler.cc b/pdns/dynhandler.cc index 3e2d5fbd4..f1e6833ee 100644 --- a/pdns/dynhandler.cc +++ b/pdns/dynhandler.cc @@ -251,7 +251,7 @@ string DLNotifyRetrieveHandler(const vector&parts, Utility::pid_t ppid) return "Domain '"+domain.toString()+"' is not a slave domain (or has no master defined)"; random_shuffle(di.masters.begin(), di.masters.end()); - Communicator.addSuckRequest(domain, di.masters.front()); + Communicator.addSuckRequest(domain, di.masters.front(), 0); // we don't know serial return "Added retrieval request for '"+domain.toString()+"' from master "+di.masters.front(); } diff --git a/pdns/ixfr.cc b/pdns/ixfr.cc index 7e53f938b..b30b84f06 100644 --- a/pdns/ixfr.cc +++ b/pdns/ixfr.cc @@ -39,6 +39,8 @@ vector, vector > > getIXFRDeltas(const ComboAd Socket s(master.sin4.sin_family, SOCK_STREAM); // cout<<"going to connect"< +#include "ixfr.hh" using boost::scoped_ptr; -void CommunicatorClass::addSuckRequest(const DNSName &domain, const string &master) +void CommunicatorClass::addSuckRequest(const DNSName &domain, const string &master, uint32_t curser) { Lock l(&d_lock); SuckRequest sr; sr.domain = domain; sr.master = master; + sr.currentSerial = curser; pair res; res=d_suckdomains.push_back(sr); @@ -64,8 +66,106 @@ void CommunicatorClass::addSuckRequest(const DNSName &domain, const string &mast } } -void CommunicatorClass::suck(const DNSName &domain,const string &remote) +void CommunicatorClass::ixfrSuck(const DNSName &domain, const string &remote, uint32_t curser) { + UeberBackend B; // fresh UeberBackend + + DomainInfo di; + di.backend=0; + // bool transaction=false; + try { + DNSSECKeeper dk (&B); // reuse our UeberBackend copy for DNSSECKeeper + + if(!B.getDomainInfo(domain, di) || !di.backend) { // di.backend and B are mostly identical + L<(DNSName("."), DNSName("."), st); + auto deltas = getIXFRDeltas(ComboAddress(remote, 53), domain, dr, tt); + cout<<"Got "<& rrset) + // first thing we need to do is delete every {qname/qt} present in before and not in after + + typedef set> present_t; + present_t pbefore, pafter; + for(const auto& b: before) + pbefore.insert({b.d_name, b.d_type}); + for(const auto& a: after) + pafter.insert({a.d_name, a.d_type}); + + vector> diff; + + set_difference(pbefore.cbegin(), pbefore.cend(), pafter.cbegin(), pafter.cend(), back_inserter(diff)); + + di.backend->startTransaction(domain, -1); + for(const auto& gone : diff) { + cerr<<"Removing "<replaceRRSet(di.id, gone.first+domain, QType(gone.second), vector()); + } + + map, vector> replacement; + + for(const auto& add : after) { + DNSResourceRecord dr(add); + dr.qname += domain; + dr.domain_id=di.id; + replacement[{add.d_name, add.d_type}].push_back(dr); + } + for(const auto& rep : replacement) { + cerr<<"Adding back in "<content<replaceRRSet(di.id, rep.first.first+domain, QType(rep.first.second), rep.second); + } + cerr<<"And commit!"<commitTransaction(); + } + + exit(1); + + } + catch(std::exception& p) { + cerr<<"Got exception: "< localaddr; SuckRequest sr; sr.domain=di.zone; + sr.currentSerial = di.serial; if(di.masters.empty()) // slave domains w/o masters are ignored continue; // remove unfresh domains already queued for AXFR, no sense polling them again @@ -684,13 +785,13 @@ void CommunicatorClass::slaveRefresh(PacketHandler *P) } else { L<setSuccessResult("Added retrieval request for '"+zonename.toString()+"' from master "+di.masters.front()); }