[svn] commit: r885 - in /branches/each-ds/src/lib: auth/cpp/data_source.cc auth/cpp/data_source_sqlite3.cc dns/cpp/rdata/generic/nsec_47.cc dns/cpp/rrset.h

BIND 10 source code commits bind10-changes at lists.isc.org
Fri Feb 19 23:13:56 UTC 2010


Author: each
Date: Fri Feb 19 23:13:56 2010
New Revision: 885

Log:
checkpoint:
- fixed a bug when querying for an NSEC at a node with a CNAME
- add NSEC to negative answers

Modified:
    branches/each-ds/src/lib/auth/cpp/data_source.cc
    branches/each-ds/src/lib/auth/cpp/data_source_sqlite3.cc
    branches/each-ds/src/lib/dns/cpp/rdata/generic/nsec_47.cc
    branches/each-ds/src/lib/dns/cpp/rrset.h

Modified: branches/each-ds/src/lib/auth/cpp/data_source.cc
==============================================================================
--- branches/each-ds/src/lib/auth/cpp/data_source.cc (original)
+++ branches/each-ds/src/lib/auth/cpp/data_source.cc Fri Feb 19 23:13:56 2010
@@ -226,6 +226,11 @@
                  task.qtype == RRType::DS() || task.qtype == RRType::DNAME())) {
                 task.flags &= ~REFERRAL;
             }
+
+            // XXX: Don't follow CNAMEs when looking for an NSEC
+            if (task.flags & CNAME_FOUND && task.qtype == RRType::NSEC()) {
+                task.flags &= ~CNAME_FOUND;
+            }
         }
 
         if (result == SUCCESS && task.flags == 0) {
@@ -335,11 +340,13 @@
             }
             continue;
         } else if (task.flags & (NAME_NOT_FOUND|TYPE_NOT_FOUND)) {
-            // No data found at this qname.  If we were looking for answer
-            // data, we need to check to see if there are any relevant
-            // wildcards.
-            if (task.state == QueryTask::GETANSWER ||
-                task.state == QueryTask::FOLLOWCNAME) {
+            // No data found at this qname/qtype.
+            // If we were looking for answer data, not additional,
+            // and the name was not found, we need to find out whether
+            // there are any relevant wildcards.
+            if (task.flags & NAME_NOT_FOUND && 
+                (task.state == QueryTask::GETANSWER ||
+                 task.state == QueryTask::FOLLOWCNAME)) {
                 Result r;
                 int nlen = task.qname.getLabelCount();
                 int diff = nlen - zone->getLabelCount();
@@ -407,18 +414,41 @@
                             }
                         }
                         continue;
-                    }
-                }
-            }
-
-            // If we've reached this point, there really is no answer.
+                    } else if (q.wantDnssec()) {
+                        // No wildcard found; add an NSEC to prove it
+                        RRsetList nsec;
+                        QueryTask t = QueryTask(*task.zone, task.qclass,
+                                                RRType::NSEC(),
+                                                QueryTask::SIMPLE_QUERY); 
+                        result = doQueryTask(ds, q, t, nsec);
+                        if (result != SUCCESS) {
+                            m.setRcode(Rcode::SERVFAIL());
+                            q.setStatus(Query::FAILURE);
+                            return;
+                        }
+
+                        if (t.flags == 0) {
+                            m.addRRset(Section::AUTHORITY(), nsec[0], true);
+                        }
+
+                    }
+                }
+            }
+
+            // If we've reached this point, there is definitely no answer.
             // If we were chasing cnames or adding additional data, that's
-            // okay, but if we were doing an original query, return NXDOMAIN
-            // and the SOA.
+            // okay, but if we were doing an original query, reply with the
+            // SOA in the authority section.  For NAME_NOT_FOUND, set
+            // NXDOMAIN, and also add the previous NSEC to the authority
+            // section.  For TYPE_NOT_FOUND, do not set an error rcode,
+            // and send the current NSEC in the authority section.
+            Name nsecname(task.qname);
+            if (task.flags & NAME_NOT_FOUND) {
+                ds->findPreviousName(q, task.qname, nsecname, task.zone);
+            }
+
             if (task.state == QueryTask::GETANSWER) {
-                if (task.flags & NAME_NOT_FOUND) {
-                    m.setRcode(Rcode::NXDOMAIN());
-                }
+                m.setRcode(Rcode::NXDOMAIN());
 
                 RRsetList soa;
                 QueryTask t(Name(*zone), task.qclass, RRType::SOA(), 
@@ -431,10 +461,27 @@
                 }
 
                 m.addRRset(Section::AUTHORITY(), soa[0], q.wantDnssec());
-                q.setStatus(Query::FAILURE);
-                return;
-            }
-            continue;
+            }
+
+            if (q.wantDnssec()) {
+                RRsetList nsec;
+                QueryTask t = QueryTask(nsecname, task.qclass, RRType::NSEC(), 
+                                        QueryTask::SIMPLE_QUERY); 
+                t.zone = task.zone;
+                result = doQueryTask(ds, q, t, nsec);
+                if (result != SUCCESS) {
+                    m.setRcode(Rcode::SERVFAIL());
+                    q.setStatus(Query::FAILURE);
+                    return;
+                }
+
+                if (t.flags == 0) {
+                    m.addRRset(Section::AUTHORITY(), nsec[0], true);
+                }
+            }
+
+            q.setStatus(Query::FAILURE);
+            return;
         } else {
             // Should never be reached!
             m.setRcode(Rcode::SERVFAIL());

Modified: branches/each-ds/src/lib/auth/cpp/data_source_sqlite3.cc
==============================================================================
--- branches/each-ds/src/lib/auth/cpp/data_source_sqlite3.cc (original)
+++ branches/each-ds/src/lib/auth/cpp/data_source_sqlite3.cc Fri Feb 19 23:13:56 2010
@@ -135,8 +135,9 @@
 
         rows++;
 
-        // looking for something else but found a CNAME
-        if (strcmp(type, "CNAME") == 0 && strcmp(c_rdtype, "CNAME") != 0) {
+        // found a CNAME when looking for something else (other than NSEC)
+        if (strcmp(type, "CNAME") == 0 && strcmp(c_rdtype, "CNAME") != 0 &&
+            strcmp(c_rdtype, "NSEC") != 0) {
             flags |= CNAME_FOUND;
         }
 
@@ -151,14 +152,14 @@
             }
         }
 
-        if (sigtype == NULL) {
+        if (sigtype == NULL && RRType(type) == rrset->getType()) {
             RdataPtr item = createRdata(RRType(type), RRClass("IN"), rdata);
             rrset->addRdata(item);
 
             if (target_ttl == -1 || target_ttl > ttl) {
                 target_ttl = ttl;
             }
-        } else {
+        } else if (sigtype != NULL && RRType(sigtype) == rrset->getType()) {
             RdataPtr rrsig = createRdata(RRType::RRSIG(), RRClass::IN(), rdata);
             if (rrset->getRRsig()) {
                 rrset->getRRsig()->addRdata(rrsig);
@@ -292,8 +293,8 @@
     }
 
     const char *q_previous_str = "SELECT name FROM records "
-                                 "WHERE zone_id=?1 AND rname < $2 "
-                                 "ORDER BY rname DESC LIMIT 1";
+                                 "WHERE zone_id=?1 AND rdtype = 'NSEC' AND "
+                                 "rname < $2 ORDER BY rname DESC LIMIT 1";
     try {
         q_previous = prepare(q_previous_str);
     } catch (const char *e) {
@@ -404,6 +405,7 @@
         const char *c_zone = zone->toText().c_str();
         zone_id = findClosest(c_zone, NULL);
     }
+std::cerr << "looking in zone_id " << zone_id << "\n";
 
     if (zone_id < 0) {
         return (ERROR);

Modified: branches/each-ds/src/lib/dns/cpp/rdata/generic/nsec_47.cc
==============================================================================
--- branches/each-ds/src/lib/dns/cpp/rdata/generic/nsec_47.cc (original)
+++ branches/each-ds/src/lib/dns/cpp/rdata/generic/nsec_47.cc Fri Feb 19 23:13:56 2010
@@ -27,7 +27,6 @@
 #include "rrttl.h"
 #include "rdata.h"
 #include "rdataclass.h"
-#include <boost/lexical_cast.hpp>
 
 #include <stdio.h>
 #include <time.h>

Modified: branches/each-ds/src/lib/dns/cpp/rrset.h
==============================================================================
--- branches/each-ds/src/lib/dns/cpp/rrset.h (original)
+++ branches/each-ds/src/lib/dns/cpp/rrset.h Fri Feb 19 23:13:56 2010
@@ -189,6 +189,13 @@
         }
     }
 
+    virtual void setTTL(const RRTTL& ttl) {
+        this->BasicRRset::setTTL(ttl);
+        if (rrsig_) {
+            rrsig_->BasicRRset::setTTL(ttl);
+        }
+    }
+
     virtual void addRRsig(const rdata::RdataPtr rdata) {
         if (!rrsig_) {
             rrsig_ = RRsetPtr(new RRset(this->getName(), this->getClass(),




More information about the bind10-changes mailing list