Browse Source

initial work for delegation processing (waiting for Zone cut handling)

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac453@4071 e5f2f494-b856-4b98-b285-d166d9295462
Jerry 14 years ago
parent
commit
8c5d4f5541
3 changed files with 75 additions and 6 deletions
  1. 39 1
      src/bin/auth/query.cc
  2. 30 0
      src/bin/auth/query.h
  3. 6 5
      src/bin/auth/tests/query_unittest.cc

+ 39 - 1
src/bin/auth/query.cc

@@ -14,6 +14,7 @@
 
 #include <dns/message.h>
 #include <dns/rcode.h>
+#include <dns/rdataclass.h>
 
 #include <datasrc/memory_datasrc.h>
 
@@ -21,11 +22,45 @@
 
 using namespace isc::dns;
 using namespace isc::datasrc;
+using namespace isc::dns::rdata;
 
 namespace isc {
 namespace auth {
 
 void
+Query::getAdditional(const isc::datasrc::Zone& zone,
+                     const isc::dns::RRset& rrset) const
+{
+    if (rrset.getType() == RRType::NS()) {
+        // Need to perform the search in the "GLUE OK" mode.
+        RdataIteratorPtr rdata_iterator = rrset.getRdataIterator();
+        for (; !rdata_iterator->isLast(); rdata_iterator->next()) {
+             const Rdata& rdata(rdata_iterator->getCurrent());
+             const generic::NS& ns = dynamic_cast<const generic::NS&>(rdata);
+             findAddrs(zone, ns.getNSName());
+        }
+    }
+}
+
+void
+Query::findAddrs(const isc::datasrc::Zone& zone,
+                 const isc::dns::Name& qname) const
+{
+    // Find A rrset
+    Zone::FindResult a_result = zone.find(qname, RRType::A());
+    if (a_result.code == Zone::SUCCESS) {
+        response_.addRRset(Message::SECTION_ADDITIONAL,
+                     boost::const_pointer_cast<RRset>(a_result.rrset));
+    }
+    // Find AAAA rrset
+    Zone::FindResult aaaa_result = zone.find(qname, RRType::AAAA());
+    if (aaaa_result.code == Zone::SUCCESS) {
+        response_.addRRset(Message::SECTION_ADDITIONAL,
+                     boost::const_pointer_cast<RRset>(aaaa_result.rrset));
+    }
+}
+
+void
 Query::process() const {
     bool keep_doing = true;
     response_.setHeaderFlag(Message::HEADERFLAG_AA, false);
@@ -56,7 +91,10 @@ Query::process() const {
                 // TODO : fill in authority and addtional sections.
                 break;
             case Zone::DELEGATION:
-                // TODO : add NS to authority section, fill in additional section.
+                response_.setRcode(Rcode::NOERROR());
+                response_.addRRset(Message::SECTION_AUTHORITY,
+                            boost::const_pointer_cast<RRset>(db_result.rrset));
+                getAdditional(*result.zone, *db_result.rrset);
                 break;
             case Zone::NXDOMAIN:
                 response_.setRcode(Rcode::NXDOMAIN());

+ 30 - 0
src/bin/auth/query.h

@@ -19,10 +19,12 @@ namespace dns {
 class Message;
 class Name;
 class RRType;
+class RRset;
 }
 
 namespace datasrc {
 class MemoryDataSrc;
+class Zone;
 }
 
 namespace auth {
@@ -104,6 +106,34 @@ public:
     /// future version.
     void process() const;
 
+    /// Look up additional data (i.e., address records for the names included
+    /// in NS or MX records).
+    ///
+    /// Right now this method never throws an exception.
+    ///
+    /// \param zone The Zone wherein the additional data to the query is bo be
+    /// found.
+    /// \param rrset The RRset (i.e., NS or MX rrset) which require additional
+    /// processing.
+    void getAdditional(const isc::datasrc::Zone& zone,
+                       const isc::dns::RRset& rrset) const;
+
+    /// Find address records for a specified name.
+    ///
+    /// Search the specified zone for AAAA/A RRs of each of the NS/MX RDATA
+    /// (domain name), and insert the found ones into the additional section
+    /// if address records are available.
+    ///
+    /// Note: we need to perform the search in the "GLUE OK" mode for NS RDATA,
+    /// which means that we should include A/AAAA RRs under a zone cut.
+    /// The glue records must exactly match the name in the NS RDATA, without
+    /// CNAME or wildcard processing.
+    ///
+    /// \param zone The Zone wherein the address records is to be found.
+    /// \param qname The name in rrset RDATA.
+    void findAddrs(const isc::datasrc::Zone& zone,
+                   const isc::dns::Name& qname) const;
+
 private:
     const isc::datasrc::MemoryDataSrc& memory_datasrc_;
     const isc::dns::Name& qname_;

+ 6 - 5
src/bin/auth/tests/query_unittest.cc

@@ -17,6 +17,7 @@
 #include <dns/rcode.h>
 #include <dns/rrttl.h>
 #include <dns/rrtype.h>
+#include <dns/rdataclass.h>
 
 #include <datasrc/memory_datasrc.h>
 
@@ -33,10 +34,10 @@ RRsetPtr a_rrset = RRsetPtr(new RRset(Name("www.example.com"),
                                       RRTTL(3600)));
 RRsetPtr glue_a_rrset(RRsetPtr(new RRset(Name("glue.a.example.com"),
                                          RRClass::IN(), RRType::A(),
-                                         RRTTL(3600)))),
+                                         RRTTL(3600))));
 RRsetPtr glue_aaaa_rrset(RRsetPtr(new RRset(Name("glue.aaaa.example.com"),
                                             RRClass::IN(), RRType::AAAA(),
-                                            RRTTL(3600)))),
+                                            RRTTL(3600))));
 namespace {
 // This is a mock Zone class for testing.
 // It is a derived class of Zone, and simply hardcode the results of find()
@@ -44,7 +45,7 @@ namespace {
 // return NXDOMAIN for "nxdomain.example.com",
 // return NXRRSET for "nxrrset.example.com",
 // return CNAME for "cname.example.com",
-// else return DNAME
+// otherwise return DNAME
 class MockZone : public Zone {
 public:
     MockZone() : origin_(Name("example.com")),
@@ -52,9 +53,9 @@ public:
                                              RRClass::IN(), RRType::NS(),
                                              RRTTL(3600))))
     {
-        ns_rrset.addRdata(rdata::generic::NS(
+        ns_rrset->addRdata(rdata::generic::NS(
                           Name("glue.a.example.com")));
-        ns_rrset.addRdata(rdata::generic::NS(
+        ns_rrset->addRdata(rdata::generic::NS(
                           Name("glue.aaaa.example.com")));
     }
     virtual const isc::dns::Name& getOrigin() const;