BIND 10 trac1063, updated. c5cf3cc081042fec0e2baea7cdf7f22a8a84664a [1063] Implement the delegations

BIND 10 source code commits bind10-changes at lists.isc.org
Fri Aug 12 11:46:23 UTC 2011


The branch, trac1063 has been updated
       via  c5cf3cc081042fec0e2baea7cdf7f22a8a84664a (commit)
      from  adcbbb141bdb09a6fd999f3369e15c2881f843ba (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit c5cf3cc081042fec0e2baea7cdf7f22a8a84664a
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Fri Aug 12 13:44:46 2011 +0200

    [1063] Implement the delegations

-----------------------------------------------------------------------

Summary of changes:
 src/lib/datasrc/database.cc                |   79 ++++++++++++++++++++++++----
 src/lib/datasrc/database.h                 |    7 ++-
 src/lib/datasrc/tests/database_unittest.cc |   17 ++++---
 3 files changed, 84 insertions(+), 19 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/datasrc/database.cc b/src/lib/datasrc/database.cc
index a4a2d92..f581d27 100644
--- a/src/lib/datasrc/database.cc
+++ b/src/lib/datasrc/database.cc
@@ -164,7 +164,9 @@ private:
 
 std::pair<bool, isc::dns::RRsetPtr>
 DatabaseClient::Finder::getRRset(const isc::dns::Name& name,
-                                 const isc::dns::RRType& type)
+                                 const isc::dns::RRType* type,
+                                 bool want_cname, bool want_dname,
+                                 bool want_ns)
 {
     RRsigStore sig_store;
     database_->searchForRecords(zone_id_, name.toText());
@@ -194,16 +196,21 @@ DatabaseClient::Finder::getRRset(const isc::dns::Name& name,
             // of the 'type covered' field in the RRSIG Rdata).
             //cur_sigtype(columns[SIGTYPE_COLUMN]);
 
-            if (cur_type == type) {
+            if (type != NULL && cur_type == *type) {
                 if (result_rrset &&
                     result_rrset->getType() == isc::dns::RRType::CNAME()) {
                     isc_throw(DataSourceError, "CNAME found but it is not "
                               "the only record for " + name.toText());
+                } else if (result_rrset && want_ns &&
+                           result_rrset->getType() == isc::dns::RRType::NS()) {
+                    // In case there's a NS, we should find the delegation, not
+                    // the data
+                    continue;
                 }
                 addOrCreate(result_rrset, name, getClass(), cur_type, cur_ttl,
                             columns[DatabaseAccessor::RDATA_COLUMN],
                             *database_);
-            } else if (cur_type == isc::dns::RRType::CNAME()) {
+            } else if (want_cname && cur_type == isc::dns::RRType::CNAME()) {
                 // There should be no other data, so result_rrset should
                 // be empty.
                 if (result_rrset) {
@@ -213,6 +220,26 @@ DatabaseClient::Finder::getRRset(const isc::dns::Name& name,
                 addOrCreate(result_rrset, name, getClass(), cur_type, cur_ttl,
                             columns[DatabaseAccessor::RDATA_COLUMN],
                             *database_);
+            } else if (want_ns && cur_type == isc::dns::RRType::NS()) {
+                if (result_rrset &&
+                    // In case we already found some data here, we should
+                    // replace it with the NS, we should delegate
+                    result_rrset->getType() != isc::dns::RRType::NS()) {
+                    result_rrset = isc::dns::RRsetPtr();
+                }
+                addOrCreate(result_rrset, name, getClass(), cur_type, cur_ttl,
+                            columns[DatabaseAccessor::RDATA_COLUMN],
+                            *database_);
+            } else if (want_dname && cur_type == isc::dns::RRType::DNAME()) {
+                // There should be max one RR of DNAME present
+                if (result_rrset &&
+                    result_rrset->getType() == isc::dns::RRType::DNAME()) {
+                    isc_throw(DataSourceError, "DNAME with multiple RRs in " +
+                              name.toText());
+                }
+                addOrCreate(result_rrset, name, getClass(), cur_type, cur_ttl,
+                            columns[DatabaseAccessor::RDATA_COLUMN],
+                            *database_);
             } else if (cur_type == isc::dns::RRType::RRSIG()) {
                 // If we get signatures before we get the actual data, we
                 // can't know which ones to keep and which to drop...
@@ -256,19 +283,51 @@ DatabaseClient::Finder::find(const isc::dns::Name& name,
     bool records_found = false;
     isc::dns::RRsetPtr result_rrset;
     ZoneFinder::Result result_status = SUCCESS;
+    std::pair<bool, isc::dns::RRsetPtr> found;
     logger.debug(DBG_TRACE_DETAILED, DATASRC_DATABASE_FIND_RECORDS)
         .arg(database_->getDBName()).arg(name).arg(type);
 
     try {
         // First, do we have any kind of delegation (NS/DNAME) here?
+        Name origin(getOrigin());
+        size_t originLabelCount(origin.getLabelCount());
+        size_t currentLabelCount(name.getLabelCount());
+        // This is how many labels we remove to get origin
+        size_t removeLabels(currentLabelCount - originLabelCount);
+        // Now go trough all superdomains from origin down
+        for (int i(removeLabels); i > 0; -- i) {
+            Name superdomain(name.split(i));
+            // Look if there's NS or DNAME (but ignore the NS in origin)
+            found = getRRset(superdomain, NULL, false, true,
+                             i != removeLabels);
+            if (found.second) {
+                // We found something redirecting somewhere else
+                // (it can be only NS or DNAME here)
+                result_rrset = found.second;
+                if (result_rrset->getType() == isc::dns::RRType::NS()) {
+                    result_status = DELEGATION;
+                } else {
+                    result_status = DNAME;
+                }
+                // Don't search more
+                break;
+            }
+        }
 
-        // Try getting the final result and extract it
-        std::pair<bool, isc::dns::RRsetPtr> found(getRRset(name, type));
-        records_found = found.first;
-        result_rrset = found.second;
-        if (result_rrset && type != isc::dns::RRType::CNAME() &&
-            result_rrset->getType() == isc::dns::RRType::CNAME()) {
-            result_status = CNAME;
+        if (!result_rrset) { // Only if we didn't find a redirect already
+            // Try getting the final result and extract it
+            // It is special if there's a CNAME or NS, DNAME is ignored here
+            // And we don't consider the NS in origin
+            found = getRRset(name, &type, true, false, name != origin);
+            records_found = found.first;
+            result_rrset = found.second;
+            if (result_rrset && type != isc::dns::RRType::NS() &&
+                result_rrset->getType() == isc::dns::RRType::NS()) {
+                result_status = DELEGATION;
+            } else if (result_rrset && type != isc::dns::RRType::CNAME() &&
+                       result_rrset->getType() == isc::dns::RRType::CNAME()) {
+                result_status = CNAME;
+            }
         }
     } catch (const DataSourceError& dse) {
         logger.error(DATASRC_DATABASE_FIND_ERROR)
diff --git a/src/lib/datasrc/database.h b/src/lib/datasrc/database.h
index 9339284..9e41f91 100644
--- a/src/lib/datasrc/database.h
+++ b/src/lib/datasrc/database.h
@@ -293,8 +293,11 @@ public:
         /// \brief Searches database for an RRset
         std::pair<bool, isc::dns::RRsetPtr> getRRset(const isc::dns::Name&
                                                      name,
-                                                     const isc::dns::RRType&
-                                                     type);
+                                                     const isc::dns::RRType*
+                                                     type,
+                                                     bool want_cname,
+                                                     bool want_dname,
+                                                     bool want_ns);
     };
     /**
      * \brief Find a zone in the database
diff --git a/src/lib/datasrc/tests/database_unittest.cc b/src/lib/datasrc/tests/database_unittest.cc
index 6c1bbe1..32ce8d9 100644
--- a/src/lib/datasrc/tests/database_unittest.cc
+++ b/src/lib/datasrc/tests/database_unittest.cc
@@ -370,14 +370,17 @@ doFindTest(shared_ptr<DatabaseClient::Finder> finder,
            const isc::dns::RRTTL expected_ttl,
            ZoneFinder::Result expected_result,
            const std::vector<std::string>& expected_rdatas,
-           const std::vector<std::string>& expected_sig_rdatas)
+           const std::vector<std::string>& expected_sig_rdatas,
+           const isc::dns::Name& expected_name = isc::dns::Name::ROOT_NAME())
 {
+    SCOPED_TRACE("doFindTest " + name.toText() + " " + type.toText());
     ZoneFinder::FindResult result =
         finder->find(name, type, NULL, ZoneFinder::FIND_DEFAULT);
     ASSERT_EQ(expected_result, result.code) << name << " " << type;
     if (expected_rdatas.size() > 0) {
-        checkRRset(result.rrset, name, finder->getClass(),
-                   expected_type, expected_ttl, expected_rdatas);
+        checkRRset(result.rrset, expected_name != Name(".") ? expected_name :
+                   name, finder->getClass(), expected_type, expected_ttl,
+                   expected_rdatas);
 
         if (expected_sig_rdatas.size() > 0) {
             checkRRset(result.rrset->getRRsig(), name,
@@ -709,12 +712,12 @@ TEST_F(DatabaseClientTest, find) {
     doFindTest(finder, isc::dns::Name("ns.delegation.example.org."),
                isc::dns::RRType::A(), isc::dns::RRType::NS(),
                isc::dns::RRTTL(3600), ZoneFinder::DELEGATION, expected_rdatas,
-               expected_sig_rdatas);
+               expected_sig_rdatas, isc::dns::Name("delegation.example.org."));
     EXPECT_FALSE(current_database_->searchRunning());
     doFindTest(finder, isc::dns::Name("ns.delegation.example.org."),
                isc::dns::RRType::AAAA(), isc::dns::RRType::NS(),
                isc::dns::RRTTL(3600), ZoneFinder::DELEGATION, expected_rdatas,
-               expected_sig_rdatas);
+               expected_sig_rdatas, isc::dns::Name("delegation.example.org."));
     EXPECT_FALSE(current_database_->searchRunning());
 
     // Even when we check directly at the delegation point, we should get
@@ -738,12 +741,12 @@ TEST_F(DatabaseClientTest, find) {
     doFindTest(finder, isc::dns::Name("below.dname.example.org."),
                isc::dns::RRType::A(), isc::dns::RRType::DNAME(),
                isc::dns::RRTTL(3600), ZoneFinder::DNAME, expected_rdatas,
-               expected_sig_rdatas);
+               expected_sig_rdatas, isc::dns::Name("dname.example.org."));
     EXPECT_FALSE(current_database_->searchRunning());
     doFindTest(finder, isc::dns::Name("below.dname.example.org."),
                isc::dns::RRType::AAAA(), isc::dns::RRType::DNAME(),
                isc::dns::RRTTL(3600), ZoneFinder::DNAME, expected_rdatas,
-               expected_sig_rdatas);
+               expected_sig_rdatas, isc::dns::Name("dname.example.org."));
     EXPECT_FALSE(current_database_->searchRunning());
 
     // But we don't delegate at DNAME point




More information about the bind10-changes mailing list