]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Implement AXFR priority level queue code
authorRobin Geuze <robing@transip.nl>
Fri, 19 Mar 2021 12:08:18 +0000 (13:08 +0100)
committerRobin Geuze <robing@transip.nl>
Wed, 24 Mar 2021 10:10:36 +0000 (11:10 +0100)
pdns/communicator.cc
pdns/communicator.hh
pdns/slavecommunicator.cc

index 19135f8c869b0f412d12e01c68d183f857403d3b..a8fcdacf46de243de5069915815e679d02872f20 100644 (file)
@@ -50,9 +50,15 @@ void CommunicatorClass::retrievalLoopThread()
       std::lock_guard<std::mutex> l(d_lock);
       if(d_suckdomains.empty()) 
         continue;
+
+      domains_by_queuepos_t& queueindex = boost::multi_index::get<QueueTag>(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);
   }
index 78d2f7de415e9e2f2f4269e00df3475d0d357c5e..5ab76fc29292ba8185eb0ca4d6bea2f15b0a246b 100644 (file)
@@ -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<tag<QueueTag>, identity<SuckRequest>, suckQueueCmp>,
     ordered_unique<tag<IDTag>, identity<SuckRequest> >
   >
 > UniQueue;
 typedef UniQueue::index<IDTag>::type domains_by_name_t;
+typedef UniQueue::index<QueueTag>::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<DNSName> d_inprogress;
   
index 924113672f84a1e2546430b332e4a052336c2cb9..54e7511172d1d9697cd95daa4abf5ff5aa171114 100644 (file)
 
 #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<std::mutex> l(d_lock);
   SuckRequest sr;
   sr.domain = domain;
   sr.master = master;
   sr.force = force;
+  sr.priority = priority;
+  sr.sortHelper = d_sorthelper++;
   pair<UniQueue::iterator, bool>  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<IDTag>(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