BIND 10 trac1066, updated. 2384bcf387e93435658ec1ab92addbf28c9ab640 [1066] More wildcard cornercases

BIND 10 source code commits bind10-changes at lists.isc.org
Wed Aug 17 11:44:31 UTC 2011


The branch, trac1066 has been updated
       via  2384bcf387e93435658ec1ab92addbf28c9ab640 (commit)
      from  1d314b2544b8af8a936c90e00a0dbbb605410952 (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 2384bcf387e93435658ec1ab92addbf28c9ab640
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Wed Aug 17 13:43:01 2011 +0200

    [1066] More wildcard cornercases
    
    Wildcard match below NS with GLUE_OK mode
    Empty non-terminal asterisk

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

Summary of changes:
 src/lib/datasrc/database.cc                |   40 ++++++++++++++----
 src/lib/datasrc/tests/database_unittest.cc |   63 +++++++++++++++++++++++++++-
 2 files changed, 93 insertions(+), 10 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/datasrc/database.cc b/src/lib/datasrc/database.cc
index 36ce554..2444257 100644
--- a/src/lib/datasrc/database.cc
+++ b/src/lib/datasrc/database.cc
@@ -316,6 +316,9 @@ DatabaseClient::Finder::find(const isc::dns::Name& name,
     std::pair<bool, isc::dns::RRsetPtr> found;
     logger.debug(DBG_TRACE_DETAILED, DATASRC_DATABASE_FIND_RECORDS)
         .arg(database_->getDBName()).arg(name).arg(type);
+    // In case we are in GLUE_OK mode and start matching wildcards,
+    // we can't do it under NS, so we store it here to check
+    isc::dns::RRsetPtr first_ns;
 
     try {
         // First, do we have any kind of delegation (NS/DNAME) here?
@@ -336,6 +339,12 @@ DatabaseClient::Finder::find(const isc::dns::Name& name,
             if (found.first) {
                 // It contains some RRs, so it exists.
                 last_known = superdomain.getLabelCount();
+                // In case we are in GLUE_OK, we want to store the highest
+                // encounderet RRset.
+                if (glue_ok && !first_ns && i != remove_labels) {
+                    first_ns = getRRset(superdomain, NULL, false, false,
+                                        true).second;
+                }
             }
             if (found.second) {
                 // We found something redirecting somewhere else
@@ -376,27 +385,42 @@ DatabaseClient::Finder::find(const isc::dns::Name& name,
                 // It's not empty non-terminal. So check for wildcards.
                 // We remove labels one by one and look for the wildcard there.
                 // Go up to first non-empty domain.
+
                 remove_labels = current_label_count - last_known;
                 Name star("*");
-                for (size_t i(1); i < remove_labels; ++ i) {
+                for (size_t i(1); i <= remove_labels; ++ i) {
                     // Construct the name with *
-                    // TODO: Once the underlying DatabaseAccessor takes string,
-                    // do the concatenation on strings, not Names
+                    // TODO: Once the underlying DatabaseAccessor takes
+                    // string, do the concatenation on strings, not
+                    // Names
                     Name superdomain(name.split(i));
                     Name wildcard(star.concatenate(superdomain));
                     // TODO What do we do about DNAME here?
                     found = getRRset(wildcard, &type, true, false, true,
                                      &name);
                     if (found.first) {
-                        // Nothing we added as part of the * can exist directly,
-                        // as we go up only to first existing domain,
-                        // but it could be empty non-terminal. In that case, we
-                        // need to cancel the match.
-                        if (!hasSubdomains(name.split(i - 1).toText())) {
+                        if (first_ns) {
+                            // In case we are under NS, we don't
+                            // wildcard-match, but return delegation
+                            result_rrset = first_ns;
+                            result_status = DELEGATION;
+                            records_found = true;
+                            // We pretend to switch to non-glue_ok mode
+                            glue_ok = false;
+                        } else if (!hasSubdomains(name.split(i - 1).toText()))
+                        {
+                            // Nothing we added as part of the * can exist
+                            // directly, as we go up only to first existing
+                            // domain, but it could be empty non-terminal. In
+                            // that case, we need to cancel the match.
                             records_found = true;
                             result_rrset = found.second;
                         }
                         break;
+                    } else if (hasSubdomains(wildcard.toText())) {
+                        // Empty non-terminal asterisk
+                        records_found = true;
+                        break;
                     }
                 }
             }
diff --git a/src/lib/datasrc/tests/database_unittest.cc b/src/lib/datasrc/tests/database_unittest.cc
index 21511fd..a0efd50 100644
--- a/src/lib/datasrc/tests/database_unittest.cc
+++ b/src/lib/datasrc/tests/database_unittest.cc
@@ -332,6 +332,14 @@ private:
         addCurName("*.wild.example.org.");
         addRecord("AAAA", "3600", "", "2001:db8::5");
         addCurName("cancel.here.wild.example.org.");
+        addRecord("NS", "3600", "", "ns.example.com.");
+        addCurName("delegatedwild.example.org.");
+        addRecord("A", "3600", "", "192.0.2.5");
+        addCurName("*.delegatedwild.example.org.");
+        addRecord("A", "3600", "", "192.0.2.5");
+        addCurName("wild.*.foo.example.org.");
+        addRecord("A", "3600", "", "192.0.2.5");
+        addCurName("wild.*.foo.*.bar.example.org.");
     }
 };
 
@@ -1030,8 +1038,59 @@ TEST_F(DatabaseClientTest, wildcard) {
                isc::dns::RRTTL(3600), ZoneFinder::NXRRSET, expected_rdatas_,
                expected_sig_rdatas_);
 
-    // TODO Check delegation, multiple wildcards and wildcards somewhere
-    // in the middle.
+    // How wildcard go together with delegation
+    expected_rdatas_.push_back("ns.example.com.");
+    doFindTest(finder, isc::dns::Name("below.delegatedwild.example.org"),
+               isc::dns::RRType::A(), isc::dns::RRType::NS(),
+               isc::dns::RRTTL(3600), ZoneFinder::DELEGATION, expected_rdatas_,
+               expected_sig_rdatas_,
+               isc::dns::Name("delegatedwild.example.org"));
+    // FIXME: This doesn't look logically OK, GLUE_OK should make it transparent,
+    // so the match should either work or be canceled, but return NXDOMAIN
+    doFindTest(finder, isc::dns::Name("below.delegatedwild.example.org"),
+               isc::dns::RRType::A(), isc::dns::RRType::NS(),
+               isc::dns::RRTTL(3600), ZoneFinder::DELEGATION, expected_rdatas_,
+               expected_sig_rdatas_,
+               isc::dns::Name("delegatedwild.example.org"),
+               ZoneFinder::FIND_GLUE_OK);
+
+    expected_rdatas_.clear();
+    expected_rdatas_.push_back("192.0.2.5");
+    // These are direct matches
+    const char* positive_names[] = {
+        "wild.*.foo.example.org.",
+        "wild.*.foo.*.bar.example.org.",
+        NULL
+    };
+    for (const char** name(positive_names); *name != NULL; ++ name) {
+        doFindTest(finder, isc::dns::Name(*name), isc::dns::RRType::A(),
+                   isc::dns::RRType::A(), isc::dns::RRTTL(3600),
+                   ZoneFinder::SUCCESS, expected_rdatas_,
+                   expected_sig_rdatas_);
+    }
+
+    // These are wildcard matches against empty nonterminal asterisk
+    expected_rdatas_.clear();
+    const char* negative_names[] = {
+        "a.foo.example.org.",
+        "*.foo.example.org.",
+        "foo.example.org.",
+        "wild.bar.foo.example.org.",
+        "baz.foo.*.bar.example.org",
+        "baz.foo.baz.bar.example.org",
+        "*.foo.baz.bar.example.org",
+        "*.foo.*.bar.example.org",
+        "foo.*.bar.example.org",
+        "*.bar.example.org",
+        "bar.example.org",
+        NULL
+    };
+    for (const char** name(negative_names); *name != NULL; ++ name) {
+        doFindTest(finder, isc::dns::Name(*name), isc::dns::RRType::A(),
+                   isc::dns::RRType::A(), isc::dns::RRTTL(3600),
+                   ZoneFinder::NXRRSET, expected_rdatas_,
+                   expected_sig_rdatas_);
+    }
 }
 
 TEST_F(DatabaseClientTest, getOrigin) {




More information about the bind10-changes mailing list