]> granicus.if.org Git - pdns/commitdiff
Fix sortlist in the presence of CNAME
authorbert hubert <bert.hubert@netherlabs.nl>
Mon, 14 Aug 2017 20:19:02 +0000 (22:19 +0200)
committerbert hubert <bert.hubert@netherlabs.nl>
Mon, 14 Aug 2017 20:19:02 +0000 (22:19 +0200)
In #5357 @killerwhile discovered we were missorting CNAME records when using sortlist.
With this commit, we should get it right by moving to stable_sort and being more careful about type equivalence.

pdns/pdns_recursor.cc
pdns/sortlist.cc

index afad36ca6d3631f816644cf2e7844ea6551a2541..8e84f339d07d59455a0faf54ad98e2452cc68594 100644 (file)
@@ -1089,7 +1089,7 @@ static void startDoResolve(void *p)
       if(ret.size()) {
         orderAndShuffle(ret);
        if(auto sl = luaconfsLocal->sortlist.getOrderCmp(dc->d_remote)) {
-         sort(ret.begin(), ret.end(), *sl);
+         stable_sort(ret.begin(), ret.end(), *sl);
          variableAnswer=true;
        }
       }
index f840844f0cfdb6f256e85995f7ca3cf7f63e8d56..49a51bfb129f9e95b8568bee9ef66618b44afd21 100644 (file)
@@ -52,15 +52,21 @@ bool SortListOrderCmp::operator()(const ComboAddress& a, const ComboAddress& b)
   return aOrder < bOrder;
 }
 
+// call this with **stable_sort**
 bool SortListOrderCmp::operator()(const DNSRecord& ar, const DNSRecord& br) const
 {
-  if(ar.d_type < br.d_type)
-    return true;
-  if(ar.d_type > br.d_type)
-    return false;
+  bool aAddr = (ar.d_type == QType::A || ar.d_type == QType::AAAA);
+  bool bAddr = (br.d_type == QType::A || br.d_type == QType::AAAA);
 
-  if(ar.d_type != QType::A && ar.d_type != QType::AAAA) 
-    return false;  // all other types are equal among themselves
+  // anything address related is always 'larger', rest is equal
+  
+  if(aAddr && !bAddr)
+    return false;
+  else if(!aAddr && bAddr)
+    return true;
+  else if(!aAddr && !bAddr)
+    return true;
+  
 
   int aOrder=std::numeric_limits<int>::max();
   int bOrder=aOrder;