]> granicus.if.org Git - pdns/commitdiff
implement ixfr-falls-back-to-axfr support
authorbert hubert <bert.hubert@netherlabs.nl>
Mon, 11 Jan 2016 12:59:35 +0000 (13:59 +0100)
committerbert hubert <bert.hubert@netherlabs.nl>
Mon, 11 Jan 2016 13:00:08 +0000 (14:00 +0100)
pdns/filterpo.cc
pdns/ixfr.cc
pdns/ixplore.cc
pdns/reczones.cc

index c50f7e55cd94191fe98d5b125f07035ad8b573d2..19b0210b77fbefd3f6a03533db76cfd21af65f29 100644 (file)
@@ -101,6 +101,16 @@ void DNSFilterEngine::assureZones(int zone)
     d_zones.resize(zone+1);
 }
 
+void DNSFilterEngine::clear(int zone)
+{
+  assureZones(zone);
+  auto& z = d_zones[zone];
+  z.qpolAddr.clear();
+  z.postpolAddr.clear();
+  z.propolName.clear();
+  z.qpolName.clear();
+}
+
 void DNSFilterEngine::addClientTrigger(const Netmask& nm, Policy pol, int zone)
 {
   assureZones(zone);
index c9bb5e48fe14f3b6f1187ca2677f454bdf58f44f..ad4ef2d6d991d1d66dba7128bb8e37905aa0fa0e 100644 (file)
@@ -4,7 +4,9 @@
 #include "dnsrecords.hh"
 #include "dnssecinfra.hh"
 
-vector<pair<vector<DNSRecord>, vector<DNSRecord> > >   getIXFRDeltas(const ComboAddress& master, const DNSName& zone, const DNSRecord& oursr, const TSIGTriplet& tt)
+
+// if you the remove,add pairs always remove a SOA and add a new one. If you get an empty remove, it means you got an AXFR!
+vector<pair<vector<DNSRecord>, vector<DNSRecord> > > getIXFRDeltas(const ComboAddress& master, const DNSName& zone, const DNSRecord& oursr, const TSIGTriplet& tt)
 {
   vector<pair<vector<DNSRecord>, vector<DNSRecord> > >  ret;
   vector<uint8_t> packet;
@@ -82,10 +84,14 @@ vector<pair<vector<DNSRecord>, vector<DNSRecord> > >   getIXFRDeltas(const Combo
  done:;
   for(unsigned int pos = 1;pos < records.size();) {
     auto sr = std::dynamic_pointer_cast<SOARecordContent>(records[pos].d_content);
+    vector<DNSRecord> remove, add;
+    if(!sr) { // this is an actual AXFR!
+      return {{remove, records}};
+    }
     if(sr->d_st.serial == masterSOA->d_st.serial)
       break;
     
-    vector<DNSRecord> remove, add;
+
     remove.push_back(records[pos]); // this adds the SOA
     for(pos++; pos < records.size() && records[pos].d_type != QType::SOA; ++pos) {
       remove.push_back(records[pos]);
index ca663495ea5c6c4f8d944656c8afa8d48f20bea3..be45c1694fe3d387cf09fc9105ded4fefa7d6ebb 100644 (file)
@@ -300,6 +300,7 @@ try
     cout<<"Got "<<deltas.size()<<" deltas, applying.."<<endl;
 
     for(const auto& delta : deltas) {
+    
       const auto& remove = delta.first;
       const auto& add = delta.second;
 
@@ -310,9 +311,17 @@ try
          newserial=std::dynamic_pointer_cast<SOARecordContent>(rr.d_content)->d_st.serial;
        }
       }
+
       cout<<"This delta ("<<ourSerial<<" - "<<newserial<<") has "<<remove.size()<<" removals, "<<add.size()<<" additions"<<endl;
+      ofstream report(directory +"/delta."+std::to_string(ourSerial)+"-"+std::to_string(newserial));      
+      if(remove.empty()) {
+        cout<<"This delta is a whole new zone"<<endl;
+        report<<"- everything, whole new zone update follow"<<endl;
+        records.clear();
+      }
+
       bool stop=false;
-      ofstream report(directory +"/delta."+std::to_string(ourSerial)+"-"+std::to_string(newserial));
+
       for(const auto& rr : remove) {
        report<<'-'<< (rr.d_name+zone) <<" IN "<<DNSRecordContent::NumberToType(rr.d_type)<<" "<<rr.d_content->getZoneRepresentation()<<endl;
        auto range = records.equal_range(tie(rr.d_name, rr.d_type, rr.d_class, rr.d_content));
@@ -322,7 +331,6 @@ try
          report.flush();
        }
        records.erase(range.first, range.second);
-
       }
 
       for(const auto& rr : add) {
index 9861a718336a241adac1ceed53df5f021bcc0e7e..698aecf5c664d491252378713baee5a2e2626492 100644 (file)
@@ -338,7 +338,10 @@ void RPZIXFRTracker(const ComboAddress& master, const DNSName& zone, const TSIGT
     for(const auto& delta : deltas) {
       const auto& remove = delta.first;
       const auto& add = delta.second;
-      
+      if(remove.empty()) {
+        L<<Logger::Warning<<"IXFR update is a whole new zone"<<endl;
+        luaconfsCopy.dfe.clear(0);
+      }
       for(const auto& rr : remove) { // should always contain the SOA
        totremove++;
        if(rr.d_type == QType::SOA) {