]> granicus.if.org Git - pdns/commitdiff
fixes PowerDNS/pdns#692
authorMark Zealey <mark@markandruth.co.uk>
Mon, 2 Dec 2013 09:19:24 +0000 (11:19 +0200)
committerMark Zealey <mark@markandruth.co.uk>
Mon, 2 Dec 2013 09:19:24 +0000 (11:19 +0200)
For the second time when writing a backend I forgot that an ANY query needs to return any SOA data as well. This is because we store our SOA's separately from our other DNS data in order to optimize zone lookups. According to Habbie MyDNS backend has the same bug. The attached patch basically forces an SOA to be included which is actually much more optimal than anything I can do in my backends as I don't have easy access to the knowledge of:

* sd data structure;
* is this query also an SOA

meaning that if I answer it in the backend I have to do a number of additional lookups for information that is already available in the PacketHandler. Additionally, I notice that you are basically doing all the SOA setup anyway if there is anything looking like an SOA entry. So, all this patch does is strip out any SOA entries and then insert one if there should be. This seems to me to both potentially simplify backend code and fix up any user errors more accurately than the current code does.

pdns/packethandler.cc

index 3437f4081654ca0bb2d8a125d39dcd07b92cb295..0d2daa66efe93533aaef8c8d88c1fdfbddfc4e26 100644 (file)
@@ -1310,17 +1310,25 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse)
 
       if(rr.qtype.getCode() == QType::CNAME && p->qtype.getCode() != QType::CNAME) 
         weRedirected=1;
-        
-      if(rr.qtype.getCode() == QType::SOA && pdns_iequals(rr.qname, sd.qname)) { // fix up possible SOA adjustments for this zone
-        rr.content=serializeSOAData(sd);
-        rr.ttl=sd.ttl;
-        rr.domain_id=sd.domain_id;
-        rr.auth = true;
-      }
-      
+
+      // Filter out all SOA's and add them in later
+      if(rr.qtype.getCode() == QType::SOA)
+        continue;
+
       rrset.push_back(rr);
     }
 
+    /* Add in SOA if required */
+    if( pdns_iequals( target, sd.qname ) ) {
+        rr.qtype = QType::SOA;
+        rr.content = serializeSOAData(sd);
+        rr.qname = sd.qname;
+        rr.ttl = sd.ttl;
+        rr.domain_id = sd.domain_id;
+        rr.auth = true;
+        rrset.push_back(rr);
+    }
+
     DLOG(L<<"After first ANY query for '"<<target<<"', id="<<sd.domain_id<<": weDone="<<weDone<<", weHaveUnauth="<<weHaveUnauth<<", weRedirected="<<weRedirected<<endl);
     if(p->qtype.getCode() == QType::DS && weHaveUnauth &&  !weDone && !weRedirected && d_dk.isSecuredZone(sd.qname)) {
       DLOG(L<<"Q for DS of a name for which we do have NS, but for which we don't have on a zone with DNSSEC need to provide an AUTH answer that proves we don't"<<endl);