From: Robin Geuze Date: Fri, 19 Mar 2021 12:08:18 +0000 (+0100) Subject: Implement AXFR priority level queue code X-Git-Tag: dnsdist-1.6.0-rc1~28^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6a401e760d26e0d33a19c8925ab6cfd1e79bab82;p=thirdparty%2Fpdns.git Implement AXFR priority level queue code --- diff --git a/pdns/communicator.cc b/pdns/communicator.cc index 19135f8c86..a8fcdacf46 100644 --- a/pdns/communicator.cc +++ b/pdns/communicator.cc @@ -50,9 +50,15 @@ void CommunicatorClass::retrievalLoopThread() std::lock_guard l(d_lock); if(d_suckdomains.empty()) continue; + + domains_by_queuepos_t& queueindex = boost::multi_index::get(d_suckdomains); + auto firstItem = queueindex.begin(); - sr=d_suckdomains.front(); - d_suckdomains.pop_front(); + sr=*firstItem; + queueindex.erase(firstItem); + if (d_suckdomains.empty()) { + d_sorthelper = 0; + } } suck(sr.domain, sr.master, sr.force); } diff --git a/pdns/communicator.hh b/pdns/communicator.hh index 78d2f7de41..5ab76fc292 100644 --- a/pdns/communicator.hh +++ b/pdns/communicator.hh @@ -46,22 +46,36 @@ struct SuckRequest DNSName domain; ComboAddress master; bool force; + uint8_t priority; + uint64_t sortHelper; bool operator<(const SuckRequest& b) const { return tie(domain, master) < tie(b.domain, b.master); } }; +struct suckQueueCmp +{ + bool operator()(const SuckRequest& a, const SuckRequest& b) const { + if (a.priority == b.priority) { + return a.sortHelper < b.sortHelper; + } + return a.priority < b.priority; + }; +}; + struct IDTag{}; +struct QueueTag{}; typedef multi_index_container< SuckRequest, indexed_by< - sequenced<>, + ordered_non_unique, identity, suckQueueCmp>, ordered_unique, identity > > > UniQueue; typedef UniQueue::index::type domains_by_name_t; +typedef UniQueue::index::type domains_by_queuepos_t; class NotificationQueue { @@ -155,6 +169,7 @@ public: d_nsock4 = -1; d_nsock6 = -1; d_preventSelfNotification = false; + d_sorthelper = 0; } time_t doNotifications(PacketHandler *P); void go(); @@ -162,7 +177,7 @@ public: void drillHole(const DNSName &domain, const string &ip); bool justNotified(const DNSName &domain, const string &ip); - void addSuckRequest(const DNSName &domain, const ComboAddress& master, bool force=false); + void addSuckRequest(const DNSName &domain, const ComboAddress& master, bool force=false, uint8_t priority = 0); void addSlaveCheckRequest(const DomainInfo& di, const ComboAddress& remote); void addTrySuperMasterRequest(const DNSPacket& p); void notify(const DNSName &domain, const string &ip); @@ -187,6 +202,7 @@ private: void masterUpdateCheck(PacketHandler *P); std::mutex d_lock; + uint64_t d_sorthelper; UniQueue d_suckdomains; set d_inprogress; diff --git a/pdns/slavecommunicator.cc b/pdns/slavecommunicator.cc index 924113672f..54e7511172 100644 --- a/pdns/slavecommunicator.cc +++ b/pdns/slavecommunicator.cc @@ -48,20 +48,35 @@ #include "ixfr.hh" -void CommunicatorClass::addSuckRequest(const DNSName &domain, const ComboAddress& master, bool force) +void CommunicatorClass::addSuckRequest(const DNSName &domain, const ComboAddress& master, bool force, uint8_t priority) { std::lock_guard l(d_lock); SuckRequest sr; sr.domain = domain; sr.master = master; sr.force = force; + sr.priority = priority; + sr.sortHelper = d_sorthelper++; pair res; - res=d_suckdomains.push_back(sr); + res=d_suckdomains.insert(sr); if(res.second) { d_suck_sem.post(); + } else { + // Domain is already in there, we should check the priority and whether its forced + domains_by_name_t& nameindex=boost::multi_index::get(d_suckdomains); + auto iter = nameindex.find(sr); + if (iter == nameindex.end()) { + // bit weird, but ok + return; + } + nameindex.modify(iter, [priority = priority, sorthelper = sr.sortHelper] (SuckRequest& so) { + if (priority < so.priority) { + so.priority = priority; + so.sortHelper = sorthelper; + } + }); } - } struct ZoneStatus