]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Avoid self-assignment of DNSName, some version of boost::container::string
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 8 Apr 2020 13:26:08 +0000 (15:26 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 22 Apr 2020 07:44:48 +0000 (09:44 +0200)
do not like that and throw an assertion.

12 files changed:
modules/remotebackend/Makefile.am
pdns/Makefile.am
pdns/calidns.cc
pdns/dnsbulktest.cc
pdns/dnsname.hh
pdns/dynhandler.cc
pdns/shuffle.cc
pdns/shuffle.hh
pdns/signingpipe.cc
pdns/slavecommunicator.cc
pdns/syncres.cc
pdns/ws-auth.cc

index e106047624b284c494cf94acea7b3ae4ccfb7bad..762df16080975046c22715ecd35c7a9057b86b21 100644 (file)
@@ -125,6 +125,7 @@ libtestremotebackend_la_SOURCES = \
        ../../pdns/unix_utility.cc \
        ../../pdns/gss_context.cc ../../pdns/gss_context.hh \
        ../../pdns/json.hh ../../pdns/json.cc \
+       ../../pdns/shuffle.hh ../../pdns/shuffle.cc \
        httpconnector.cc \
        pipeconnector.cc \
        unixconnector.cc \
index 3aa748fd6f36344e6667891ecb918eeb50b7bf58..2436ee05504f317ac23f795314c2524f11a04ce0 100644 (file)
@@ -920,7 +920,9 @@ dnsbulktest_SOURCES = \
        rcpgenerator.cc \
        sillyrecords.cc \
        statbag.cc \
-       unix_utility.cc
+       unix_utility.cc \
+       arguments.cc arguments.hh \
+       dns_random.cc dns_random.hh
 
 dnsbulktest_LDFLAGS = \
        $(AM_LDFLAGS) \
@@ -1083,6 +1085,7 @@ pdns_notify_LDADD = \
 
 if LIBSODIUM
 pdns_notify_LDADD += $(LIBSODIUM_LIBS)
+dnsbulktest_LDADD += $(LIBSODIUM_LIBS)
 endif
 
 dnsscope_SOURCES = \
index 39796e5f715ba3a63f8f00290b1bb2d4add0cd7a..d07ac19f4ad440a2b5b942c2f500000d2debd967 100644 (file)
@@ -408,7 +408,8 @@ try
     }
     unknown.emplace_back(std::make_shared<vector<uint8_t>>(packet));
   }
-  random_shuffle(unknown.begin(), unknown.end());
+
+  shuffle(unknown.begin(), unknown.end(), pdns::dns_random_engine());
   if (!g_quiet) {
     cout<<"Generated "<<unknown.size()<<" ready to use queries"<<endl;
   }
@@ -473,7 +474,8 @@ try
     for(;n < total; ++n) {
       toSend.push_back(known[dns_random(known.size())].get());
     }
-    random_shuffle(toSend.begin(), toSend.end());
+
+    shuffle(toSend.begin(), toSend.end(), pdns::dns_random_engine());
     g_recvcounter.store(0);
     g_recvbytes=0;
     DTime dt;
index 18bfeee6cf07776ae98909a899b570cc57cadd6b..a93866e99dbc436d0829b826afa2bcde809fd807 100644 (file)
@@ -34,6 +34,8 @@
 #include "misc.hh"
 #include "dnswriter.hh"
 #include "dnsrecords.hh"
+#include "dns_random.hh"
+#include "arguments.hh"
 
 using namespace boost::accumulators;
 namespace po = boost::program_options;
@@ -42,6 +44,12 @@ po::variables_map g_vm;
 
 StatBag S;
 
+ArgvMap &arg()
+{
+  static ArgvMap theArg;
+  return theArg;
+}
+
 bool g_quiet=false;
 bool g_envoutput=false;
 
@@ -307,7 +315,7 @@ try
       domains.push_back(TypedQuery("www."+split.second, qtype));
   }
   cerr<<"Read "<<domains.size()<<" domains!"<<endl;
-  random_shuffle(domains.begin(), domains.end());
+  shuffle(domains.begin(), domains.end(), pdns::dns_random_engine());
 
   boost::format datafmt("%s %|20t|%+15s  %|40t|%s %|60t|%+15s\n");
 
index f933a62252c1c44281498414c187534248ee982c..d23be23d908946cba41bbed2027713c4c478622c 100644 (file)
@@ -63,6 +63,23 @@ class DNSName
 {
 public:
   DNSName()  {}          //!< Constructs an *empty* DNSName, NOT the root!
+  // Work around assertion in some boost versions that do not like self-assignment of boost::container::string
+  DNSName& operator=(const DNSName& rhs)
+  {
+    if (this != &rhs) {
+      d_storage = rhs.d_storage;
+    }
+    return *this;
+  }
+  DNSName& operator=(const DNSName&& rhs)
+  {
+    if (this != &rhs) {
+      d_storage = std::move(rhs.d_storage);
+    }
+    return *this;
+  }
+  DNSName(const DNSName& a) = default;
+  DNSName(DNSName&& a) = default;
   explicit DNSName(const char* p): DNSName(p, std::strlen(p)) {} //!< Constructs from a human formatted, escaped presentation
   explicit DNSName(const char* p, size_t len);      //!< Constructs from a human formatted, escaped presentation
   explicit DNSName(const std::string& str) : DNSName(str.c_str(), str.length()) {}; //!< Constructs from a human formatted, escaped presentation
index db1615909d6df4a2a784905090acefbfdbaf9b56..4aef4a2f32fae33575989240a62b494720fa5abc 100644 (file)
@@ -254,7 +254,7 @@ string DLNotifyRetrieveHandler(const vector<string>&parts, Utility::pid_t ppid)
   if(di.kind != DomainInfo::Slave || di.masters.empty())
     return "Domain '"+domain.toString()+"' is not a slave domain (or has no master defined)";
 
-  random_shuffle(di.masters.begin(), di.masters.end());
+  shuffle(di.masters.begin(), di.masters.end(), pdns::dns_random_engine());
   Communicator.addSuckRequest(domain, di.masters.front()); 
   return "Added retrieval request for '"+domain.toString()+"' from master "+di.masters.front().toLogString();
 }
index 6440d77c661ef6eadb1fb0b1abf710e5ee263a6d..64c4bba7dda401d4dfc4fc0725094c922382f4d4 100644 (file)
 void pdns::shuffle(std::vector<DNSZoneRecord>& rrs)
 {
   std::vector<DNSZoneRecord>::iterator first, second;
-  for(first=rrs.begin();first!=rrs.end();++first)
-    if(first->dr.d_place==DNSResourceRecord::ANSWER && first->dr.d_type != QType::CNAME) // CNAME must come first
+
+  // We assume the CNAMES are listed firts in the ANSWWER section and the the other records
+  // and we want to shuffle the other records only
+
+  // First we scan for the first non-CNAME ANSWER record
+  for (first = rrs.begin(); first != rrs.end(); ++first) {
+    if (first->dr.d_place == DNSResourceRecord::ANSWER && first->dr.d_type != QType::CNAME) {
       break;
-  for(second=first;second!=rrs.end();++second)
-    if(second->dr.d_place!=DNSResourceRecord::ANSWER)
+    }
+  }
+  // And then for one past the last ANSWER recordd
+  for (second = first; second != rrs.end(); ++second)
+    if (second->dr.d_place != DNSResourceRecord::ANSWER)
       break;
 
+  // Now shuffle the non-CNAME ANSWER records
   dns_random_engine r;
-  if(second-first > 1)
+  if (second - first > 1) {
     shuffle(first, second, r);
+  }
 
-  // now shuffle the additional records
-  for(first=second;first!=rrs.end();++first)
-    if(first->dr.d_place==DNSResourceRecord::ADDITIONAL && first->dr.d_type != QType::CNAME) // CNAME must come first
+  // now shuffle the ADDITIONAL records in the same manner as the ANSWER records
+  for (first = second; first != rrs.end(); ++first) {
+    if (first->dr.d_place == DNSResourceRecord::ADDITIONAL && first->dr.d_type != QType::CNAME) {
       break;
-  for(second=first;second!=rrs.end();++second)
-    if(second->dr.d_place!=DNSResourceRecord::ADDITIONAL)
+    }
+  }
+  for (second = first; second != rrs.end(); ++second) {
+    if (second->dr.d_place != DNSResourceRecord::ADDITIONAL) {
       break;
+    }
+  }
 
-  if(second-first>1)
+  if (second - first > 1) {
     shuffle(first, second, r);
-
+  }
   // we don't shuffle the rest
 }
 
-
 // shuffle, maintaining some semblance of order
-void pdns::shuffle(std::vector<DNSRecord>& rrs)
+static void shuffle(std::vector<DNSRecord>& rrs)
 {
+  // This shuffles in the same style as the above method, keeping CNAME in the front and RRSIGs at the end
   std::vector<DNSRecord>::iterator first, second;
-  for(first=rrs.begin();first!=rrs.end();++first)
-    if(first->d_place==DNSResourceRecord::ANSWER && first->d_type != QType::CNAME) // CNAME must come first
+  for (first = rrs.begin(); first != rrs.end(); ++first) {
+    if (first->d_place == DNSResourceRecord::ANSWER && first->d_type != QType::CNAME) {
       break;
-  for(second=first;second!=rrs.end();++second)
-    if(second->d_place!=DNSResourceRecord::ANSWER || second->d_type == QType::RRSIG) // leave RRSIGs at the end
+    }
+  }
+  for (second = first; second != rrs.end(); ++second) {
+    if (second->d_place != DNSResourceRecord::ANSWER || second->d_type == QType::RRSIG) {
       break;
+    }
+  }
 
-  dns_random_engine r;
-  if(second-first>1)
+  pdns::dns_random_engine r;
+  if (second - first > 1) {
     shuffle(first, second, r);
+  }
 
   // now shuffle the additional records
-  for(first=second;first!=rrs.end();++first)
-    if(first->d_place==DNSResourceRecord::ADDITIONAL && first->d_type != QType::CNAME) // CNAME must come first
+  for (first = second; first != rrs.end(); ++first) {
+    if (first->d_place == DNSResourceRecord::ADDITIONAL && first->d_type != QType::CNAME) {
       break;
-  for(second=first; second!=rrs.end(); ++second)
-    if(second->d_place!=DNSResourceRecord::ADDITIONAL)
+    }
+  }
+  for (second = first; second != rrs.end(); ++second) {
+    if (second->d_place != DNSResourceRecord::ADDITIONAL) {
       break;
+    }
+  }
 
-  if(second-first>1)
+  if (second - first > 1) {
     shuffle(first, second, r);
-
+  }
   // we don't shuffle the rest
 }
 
@@ -102,8 +125,8 @@ static uint16_t mapTypesToOrder(uint16_t type)
 // then shuffle the parts that desire shuffling
 void pdns::orderAndShuffle(vector<DNSRecord>& rrs)
 {
-  std::stable_sort(rrs.begin(), rrs.end(), [](const DNSRecord&a, const DNSRecord& b) { 
-      return std::make_tuple(a.d_place, mapTypesToOrder(a.d_type)) < std::make_tuple(b.d_place, mapTypesToOrder(b.d_type));
-    });
+  std::stable_sort(rrs.begin(), rrs.end(), [](const DNSRecord& a, const DNSRecord& b) {
+    return std::make_tuple(a.d_place, mapTypesToOrder(a.d_type)) < std::make_tuple(b.d_place, mapTypesToOrder(b.d_type));
+  });
   shuffle(rrs);
 }
index c42e400720181f023ab479fc34d8d75e3bbef4dc..89172049044bcd471a7b089624e1494ea2b096b3 100644 (file)
@@ -25,9 +25,8 @@
 struct DNSRecord;
 struct DNSZoneRecord;
 
-namespace pdns {
-  void shuffle(std::vector<DNSRecord>& rrs);
-  void shuffle(std::vector<DNSZoneRecord>& rrs);
-  void orderAndShuffle(std::vector<DNSRecord>& rrs);
+namespace pdns
+{
+void shuffle(std::vector<DNSZoneRecord>& rrs);
+void orderAndShuffle(std::vector<DNSRecord>& rrs);
 }
-
index 83beaa8fd69b206f6678853af309e9b2b7fc6fc8..c129a4193a58313b957d12d52d250837631b81b5 100644 (file)
@@ -3,6 +3,7 @@
 #endif
 #include "signingpipe.hh"
 #include "misc.hh"
+#include "dns_random.hh"
 #include <poll.h>
 
 #include <sys/socket.h>
@@ -196,7 +197,7 @@ void ChunkedSigningPipe::sendRRSetToWorker() // it sounds so socialist!
   rwVect = waitForRW(wantRead, wantWrite, -1); // wait for something to happen
   
   if(wantWrite && !rwVect.second.empty()) {
-    random_shuffle(rwVect.second.begin(), rwVect.second.end()); // pick random available worker
+    shuffle(rwVect.second.begin(), rwVect.second.end(), pdns::dns_random_engine()); // pick random available worker
     auto ptr = d_rrsetToSign.release();
     writen2(*rwVect.second.begin(), &ptr, sizeof(ptr));
     d_rrsetToSign = make_unique<rrset_t>();
@@ -245,7 +246,7 @@ void ChunkedSigningPipe::sendRRSetToWorker() // it sounds so socialist!
   
   if(wantWrite) {  // our optimization above failed, we now wait synchronously
     rwVect = waitForRW(false, wantWrite, -1); // wait for something to happen
-    random_shuffle(rwVect.second.begin(), rwVect.second.end()); // pick random available worker
+    shuffle(rwVect.second.begin(), rwVect.second.end(), pdns::dns_random_engine()); // pick random available worker
     auto ptr = d_rrsetToSign.release();
     writen2(*rwVect.second.begin(), &ptr, sizeof(ptr));
     d_rrsetToSign = make_unique<rrset_t>();
index e88fc24791d5847be3e2a7287535d63e6c8acaf4..f6775de310e285a86a43401f918375cc830a35ab 100644 (file)
@@ -694,7 +694,7 @@ struct SlaveSenderReceiver
 
   Identifier send(DomainNotificationInfo& dni)
   {
-    random_shuffle(dni.di.masters.begin(), dni.di.masters.end());
+    shuffle(dni.di.masters.begin(), dni.di.masters.end(), pdns::dns_random_engine());
     try {
       return std::make_tuple(dni.di.zone,
                              *dni.di.masters.begin(),
index 50ac112d10cac45e81365cb023085bcab56b6887..d63952b282c1e746439d139bbfed8254853a8ebe 100644 (file)
@@ -1657,9 +1657,7 @@ inline std::vector<std::pair<DNSName, float>> SyncRes::shuffleInSpeedOrder(NsSet
       return rnameservers;
   }
 
-  // Using  shuffle(rnameservers.begin(), rnameservers.end(), pdsn:dns_ramndom_engine()) causes a boost assert,
-  // to be investigated
-  random_shuffle(rnameservers.begin(),rnameservers.end());
+  shuffle(rnameservers.begin(),rnameservers.end(), pdns::dns_random_engine());
   speedOrder so;
   stable_sort(rnameservers.begin(),rnameservers.end(), so);
 
index 8a8c4336e9a325744d287f63c649e58558814b9a..7b9143f59a0fb46fb2611c7e1805be201111fd47 100644 (file)
@@ -1836,7 +1836,7 @@ static void apiServerZoneAxfrRetrieve(HttpRequest* req, HttpResponse* resp) {
   if(di.masters.empty())
     throw ApiException("Domain '"+zonename.toString()+"' is not a slave domain (or has no master defined)");
 
-  random_shuffle(di.masters.begin(), di.masters.end());
+  shuffle(di.masters.begin(), di.masters.end(), pdns::dns_random_engine());
   Communicator.addSuckRequest(zonename, di.masters.front());
   resp->setSuccessResult("Added retrieval request for '"+zonename.toString()+"' from master "+di.masters.front().toLogString());
 }