]> granicus.if.org Git - pdns/commitdiff
The PowerDNS Recursor shuffles answers randomly, so no single A record gets overloade...
authorbert hubert <bert.hubert@netherlabs.nl>
Sun, 21 Aug 2016 12:21:28 +0000 (14:21 +0200)
committerbert hubert <bert.hubert@netherlabs.nl>
Sun, 21 Aug 2016 12:21:28 +0000 (14:21 +0200)
Our logic however assumed all the CNAMEs would initially be at the front of the packet. We'd start our shuffling after skipping all the CNAMEs up front. It now turns out that sometimes we end up with a 'CNAME A CNAME A' packet to shuffle.
This would happily shuffle the last three records. With this PR, we put the CNAMEs up front explicitly before commencing the shuffle. Closes #4339.

Still to be investigated: why didn't this bite us before?

pdns/misc.cc

index bca2bbd80eec94e9c26fcfb28cfea0df64f64a4f..4c20b2cbd66b95acce719a0c050899ebdf0140a0 100644 (file)
@@ -581,12 +581,20 @@ void shuffle(vector<DNSRecord>& rrs)
   // we don't shuffle the rest
 }
 
+static uint16_t mapCnameToFirst(uint16_t type)
+{
+  if(type == QType::CNAME)
+    return 0;
+  else
+    return 1;
+}
+
 // make sure rrs is sorted in d_place order to avoid surprises later
 // then shuffle the parts that desire shuffling
 void orderAndShuffle(vector<DNSRecord>& rrs)
 {
   std::stable_sort(rrs.begin(), rrs.end(), [](const DNSRecord&a, const DNSRecord& b) { 
-      return a.d_place < b.d_place;
+      return std::make_tuple(a.d_place, mapCnameToFirst(a.d_type)) < std::make_tuple(b.d_place, mapCnameToFirst(b.d_type));
     });
   shuffle(rrs);
 }