BIND 10 master, updated. 72c4f5046949567927410bdb2ccb7ecb663d16dd Merge branch 'work/wildcard/main'
BIND 10 source code commits
bind10-changes at lists.isc.org
Thu Feb 17 15:48:39 UTC 2011
The branch, master has been updated
via 72c4f5046949567927410bdb2ccb7ecb663d16dd (commit)
via 8f777e093c960f76ff489f12684005eb48580323 (commit)
via 9b9f126d3e4adc4ef7e6b61945245499745996df (commit)
via 967fe3d95663240940e2c5e653fc3ecac7739037 (commit)
via 310d15bf23ac533d70a20c0a881fc285cb7af3f7 (commit)
via 1888b383084177cbfab6c408e15565a3bec17ee9 (commit)
via 73837f513323e69175abfcfd04ca2f7b1fe22a4c (commit)
via deedd6f7ff3339f822f9ed8de77a5a7164bda9a1 (commit)
via de81dbd26e42616b7c56718ffe1ffc7c6861b9e9 (commit)
via 406ff425ec228f5b99a61576d8a576fbc76b3122 (commit)
via 2db67df75178a2bc407417540dde75e895eb619b (commit)
via 0da13ea71e97d62ee8cffeac9613a59f6dd07335 (commit)
via c95b25359f139a816f114378872bc08ab7e6aef2 (commit)
via 91a8eaa5b51c15b6d8f6cad3d75597678eeb03f1 (commit)
via 7f5705228eb95dba445d0d1d8297c6de0306360b (commit)
via a463f3d1b7b87d98f8c84d9d93a9fbd0285c53b9 (commit)
via 5607fdf2add21db2a5e080fdc6b146dea58e15cc (commit)
via f3d4565f0bf0839c6b5d3cfd8ae8ee48dbc20732 (commit)
via 5cd467d3209b8665c21fad038e79c5063ca95798 (commit)
from 689503220317cf2e86dae704a8e660ed646af67b (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 72c4f5046949567927410bdb2ccb7ecb663d16dd
Merge: 689503220317cf2e86dae704a8e660ed646af67b 8f777e093c960f76ff489f12684005eb48580323
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Thu Feb 17 16:43:13 2011 +0100
Merge branch 'work/wildcard/main'
commit 8f777e093c960f76ff489f12684005eb48580323
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Thu Feb 17 16:40:45 2011 +0100
[trac551] Enable GLUE_OK in the wildcard test
commit 9b9f126d3e4adc4ef7e6b61945245499745996df
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Thu Feb 17 12:02:23 2011 +0100
[trac551] Comment
commit 967fe3d95663240940e2c5e653fc3ecac7739037
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Thu Feb 17 11:45:35 2011 +0100
[trac551] Small fix of tests
commit 310d15bf23ac533d70a20c0a881fc285cb7af3f7
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Wed Feb 16 14:17:21 2011 +0100
[trac551] Some more tests from review
commit 1888b383084177cbfab6c408e15565a3bec17ee9
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Tue Feb 15 10:16:44 2011 -0800
[trac551] minor editorial fixes: position of '*', avoid implicit conversion to bool
commit 73837f513323e69175abfcfd04ca2f7b1fe22a4c
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Tue Feb 15 09:36:39 2011 -0800
[trac551] editorial fix: made sure comments and code matched.
-----------------------------------------------------------------------
Summary of changes:
src/lib/datasrc/memory_datasrc.cc | 83 +++++++--
src/lib/datasrc/tests/memory_datasrc_unittest.cc | 235 ++++++++++++++++++++--
2 files changed, 283 insertions(+), 35 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/lib/datasrc/memory_datasrc.cc b/src/lib/datasrc/memory_datasrc.cc
index fdef888..f28df0d 100644
--- a/src/lib/datasrc/memory_datasrc.cc
+++ b/src/lib/datasrc/memory_datasrc.cc
@@ -94,22 +94,22 @@ struct MemoryZone::MemoryZoneImpl {
l > origin_labels;
--l, wname = wname.split(1)) {
if (wname.isWildcard()) {
- // Ensure a separate level exists for the wildcard name.
- // Note: for 'name' itself we do this later anyway, but the
- // overhead should be marginal because wildcard names should
- // be rare.
+ // Ensure a separate level exists for the "wildcarding" name,
+ // and mark the node as "wild".
DomainNode* node;
DomainTree::Result result(domains.insert(wname.split(1),
&node));
assert(result == DomainTree::SUCCESS ||
result == DomainTree::ALREADYEXISTS);
+ node->setFlag(DOMAINFLAG_WILD);
- // Ensure a separate level exists for the "wildcarding" name,
- // and mark the node as "wild".
+ // Ensure a separate level exists for the wildcard name.
+ // Note: for 'name' itself we do this later anyway, but the
+ // overhead should be marginal because wildcard names should
+ // be rare.
result = domains.insert(wname, &node);
assert(result == DomainTree::SUCCESS ||
result == DomainTree::ALREADYEXISTS);
- node->setFlag(DOMAINFLAG_WILD);
}
}
}
@@ -351,6 +351,35 @@ struct MemoryZone::MemoryZoneImpl {
return (false);
}
+ /*
+ * Prepares a rrset to be return as a result.
+ *
+ * If rename is false, it returns the one provided. If it is true, it
+ * creates a new rrset with the same data but with provided name.
+ * It is designed for wildcard case, where we create the rrsets
+ * dynamically.
+ */
+ static ConstRRsetPtr prepareRRset(const Name& name, const ConstRRsetPtr&
+ rrset, bool rename)
+ {
+ if (rename) {
+ /*
+ * We lose a signature here. But it would be wrong anyway, because
+ * the name changed. This might turn out to be unimportant in
+ * future, because wildcards will probably be handled somehow
+ * by DNSSEC.
+ */
+ RRsetPtr result(new RRset(name, rrset->getClass(),
+ rrset->getType(), rrset->getTTL()));
+ for (RdataIteratorPtr i(rrset->getRdataIterator()); !i->isLast();
+ i->next()) {
+ result->addRdata(i->getCurrent());
+ }
+ return (result);
+ } else {
+ return (rrset);
+ }
+ }
// Implementation of MemoryZone::find
FindResult find(const Name& name, RRType type,
@@ -360,6 +389,7 @@ struct MemoryZone::MemoryZoneImpl {
DomainNode* node(NULL);
FindState state(options);
RBTreeNodeChain<Domain> node_path;
+ bool rename(false);
switch (domains_.find(name, &node, node_path, cutCallback, &state)) {
case DomainTree::PARTIALMATCH:
/*
@@ -383,10 +413,33 @@ struct MemoryZone::MemoryZoneImpl {
if (state.dname_node_ != NULL) {
// We were traversing a DNAME node (and wanted to go
// lower below it), so return the DNAME
- return (FindResult(DNAME, state.rrset_));
+ return (FindResult(DNAME, prepareRRset(name, state.rrset_,
+ rename)));
}
if (state.zonecut_node_ != NULL) {
- return (FindResult(DELEGATION, state.rrset_));
+ return (FindResult(DELEGATION, prepareRRset(name,
+ state.rrset_, rename)));
+ }
+ /*
+ * No redirection anywhere. Let's try if it is a wildcard.
+ */
+ if (node->getFlag(DOMAINFLAG_WILD)) {
+ Name wildcard(Name("*").concatenate(
+ node_path.getAbsoluteName()));
+ DomainTree::Result result(domains_.find(wildcard, &node));
+ /*
+ * Otherwise, why would the DOMAINFLAG_WILD be there if
+ * there was no wildcard under it?
+ */
+ assert(result = DomainTree::EXACTMATCH);
+ /*
+ * We have the wildcard node now. Jump below the switch,
+ * where handling of the common (exact-match) case is.
+ *
+ * However, rename it to the searched name.
+ */
+ rename = true;
+ break;
}
// If the RBTree search stopped at a node for a super domain
@@ -420,7 +473,8 @@ struct MemoryZone::MemoryZoneImpl {
if (node->getFlag(DomainNode::FLAG_CALLBACK) && node != origin_data_) {
found = node->getData()->find(RRType::NS());
if (found != node->getData()->end()) {
- return (FindResult(DELEGATION, found->second));
+ return (FindResult(DELEGATION, prepareRRset(name,
+ found->second, rename)));
}
}
@@ -431,7 +485,8 @@ struct MemoryZone::MemoryZoneImpl {
found != node->getData()->end(); found++)
{
target->addRRset(
- boost::const_pointer_cast<RRset>(found->second));
+ boost::const_pointer_cast<RRset>(prepareRRset(name,
+ found->second, rename)));
}
return (FindResult(SUCCESS, ConstRRsetPtr()));
}
@@ -439,12 +494,14 @@ struct MemoryZone::MemoryZoneImpl {
found = node->getData()->find(type);
if (found != node->getData()->end()) {
// Good, it is here
- return (FindResult(SUCCESS, found->second));
+ return (FindResult(SUCCESS, prepareRRset(name, found->second,
+ rename)));
} else {
// Next, try CNAME.
found = node->getData()->find(RRType::CNAME());
if (found != node->getData()->end()) {
- return (FindResult(CNAME, found->second));
+ return (FindResult(CNAME, prepareRRset(name, found->second,
+ rename)));
}
}
// No exact match or CNAME. Return NXRRSET.
diff --git a/src/lib/datasrc/tests/memory_datasrc_unittest.cc b/src/lib/datasrc/tests/memory_datasrc_unittest.cc
index 15b06b4..a5bfc6f 100644
--- a/src/lib/datasrc/tests/memory_datasrc_unittest.cc
+++ b/src/lib/datasrc/tests/memory_datasrc_unittest.cc
@@ -197,12 +197,14 @@ public:
&rr_child_dname_},
{"example.com. 300 IN A 192.0.2.10", &rr_out_},
{"*.wild.example.org. 300 IN A 192.0.2.1", &rr_wild_},
+ {"foo.wild.example.org. 300 IN A 192.0.2.3", &rr_under_wild_},
{"wild.*.foo.example.org. 300 IN A 192.0.2.1", &rr_emptywild_},
{"wild.*.foo.*.bar.example.org. 300 IN A 192.0.2.1",
&rr_nested_emptywild_},
{"*.nswild.example.org. 300 IN NS nswild.example.", &rr_nswild_},
{"*.dnamewild.example.org. 300 IN DNAME dnamewild.example.",
&rr_dnamewild_},
+ {"*.child.example.org. 300 IN A 192.0.2.1", &rr_child_wild_},
{NULL, NULL}
};
@@ -252,6 +254,8 @@ public:
RRsetPtr rr_emptywild_;
RRsetPtr rr_nested_emptywild_;
RRsetPtr rr_nswild_, rr_dnamewild_;
+ RRsetPtr rr_child_wild_;
+ RRsetPtr rr_under_wild_;
/**
* \brief Test one find query to the zone.
@@ -268,13 +272,18 @@ public:
* \param answer The expected rrset, if any should be returned.
* \param zone Check different MemoryZone object than zone_ (if NULL,
* uses zone_)
+ * \param check_wild_answer Checks that the answer has the same RRs, type
+ * class and TTL as the eqxpected answer and that the name corresponds
+ * to the one searched. It is meant for checking answers for wildcard
+ * queries.
*/
void findTest(const Name& name, const RRType& rrtype, Zone::Result result,
bool check_answer = true,
const ConstRRsetPtr& answer = ConstRRsetPtr(),
RRsetList* target = NULL,
MemoryZone* zone = NULL,
- Zone::FindOptions options = Zone::FIND_DEFAULT)
+ Zone::FindOptions options = Zone::FIND_DEFAULT,
+ bool check_wild_answer = false)
{
if (!zone) {
zone = &zone_;
@@ -288,6 +297,29 @@ public:
EXPECT_EQ(result, find_result.code);
if (check_answer) {
EXPECT_EQ(answer, find_result.rrset);
+ } else if (check_wild_answer) {
+ RdataIteratorPtr expectedIt(answer->getRdataIterator());
+ RdataIteratorPtr actualIt(
+ find_result.rrset->getRdataIterator());
+ while (!expectedIt->isLast() && !actualIt->isLast()) {
+ EXPECT_EQ(0, expectedIt->getCurrent().compare(
+ actualIt->getCurrent())) << "The RRs differ ('" <<
+ expectedIt->getCurrent().toText() << "', '" <<
+ actualIt->getCurrent().toText() << "')";
+ expectedIt->next();
+ actualIt->next();
+ }
+ EXPECT_TRUE(expectedIt->isLast()) <<
+ "Result has less RRs than expected";
+ EXPECT_TRUE(actualIt->isLast()) <<
+ "Result has more RRs than expected";
+ EXPECT_EQ(answer->getClass(),
+ find_result.rrset->getClass());
+ EXPECT_EQ(answer->getType(),
+ find_result.rrset->getType());
+ EXPECT_EQ(answer->getTTL(),
+ find_result.rrset->getTTL());
+ EXPECT_EQ(name, find_result.rrset->getName());
}
});
}
@@ -542,11 +574,6 @@ TEST_F(MemoryZoneTest, glue) {
findTest(Name("www.child.example.org"), RRType::A(), Zone::DELEGATION,
true, rr_child_ns_, NULL, NULL, Zone::FIND_GLUE_OK);
- // TODO:
- // glue name would match a wildcard under a zone cut: wildcard match
- // shouldn't happen under a cut and result must be PARTIALMATCH
- // (This case cannot be tested yet)
-
// nested cut case. The glue should be found.
findTest(rr_grandchild_glue_->getName(), RRType::AAAA(),
Zone::SUCCESS,
@@ -656,11 +683,11 @@ TEST_F(MemoryZoneTest, load) {
MasterLoadError);
}
-// Note: once #507 is merged, findTest() would succeed whether or not
-// we load the wildcard correctly, so the test will become meaningless.
-// The plan is to clean them up when we complete #551 (then the effect of
-// load will be indirectly tested via find() tests).
-TEST_F(MemoryZoneTest, loadWildcard) {
+/*
+ * Test that puts a (simple) wildcard into the zone and checks we can
+ * correctly find the data.
+ */
+TEST_F(MemoryZoneTest, wildcard) {
/*
* example.org.
* |
@@ -669,11 +696,96 @@ TEST_F(MemoryZoneTest, loadWildcard) {
* *
*/
EXPECT_EQ(SUCCESS, zone_.add(rr_wild_));
- findTest(Name("wild.example.org"), RRType::A(), Zone::NXRRSET);
+
+ // Search at the parent. The parent will not have the A, but it will
+ // be in the wildcard (so check the wildcard isn't matched at the parent)
+ {
+ SCOPED_TRACE("Search at parrent");
+ findTest(Name("wild.example.org"), RRType::A(), Zone::NXRRSET);
+ }
+
+ // Search the original name of wildcard
+ {
+ SCOPED_TRACE("Search directly at *");
+ findTest(Name("*.wild.example.org"), RRType::A(), Zone::SUCCESS, true,
+ rr_wild_);
+ }
+ // Search "created" name.
+ {
+ SCOPED_TRACE("Search at created child");
+ findTest(Name("a.wild.example.org"), RRType::A(), Zone::SUCCESS, false,
+ rr_wild_, NULL, NULL, Zone::FIND_DEFAULT, true);
+ }
+
+ // Search another created name, this time little bit lower
+ {
+ SCOPED_TRACE("Search at created grand-child");
+ findTest(Name("a.b.wild.example.org"), RRType::A(), Zone::SUCCESS,
+ false, rr_wild_, NULL, NULL, Zone::FIND_DEFAULT, true);
+ }
+
+ EXPECT_EQ(SUCCESS, zone_.add(rr_under_wild_));
+ {
+ SCOPED_TRACE("Search under non-wildcard");
+ findTest(Name("bar.foo.wild.example.org"), RRType::A(),
+ Zone::NXDOMAIN);
+ }
+}
+
+/*
+ * Test that we don't match a wildcard if we get under delegation.
+ * By 4.3.3 of RFC1034:
+ * "Wildcard RRs do not apply:
+ * - When the query is in another zone. That is, delegation cancels
+ * the wildcard defaults."
+ */
+TEST_F(MemoryZoneTest, delegatedWildcard) {
+ EXPECT_EQ(SUCCESS, zone_.add(rr_child_wild_));
+ EXPECT_EQ(SUCCESS, zone_.add(rr_child_ns_));
+
+ {
+ SCOPED_TRACE("Looking under delegation point");
+ findTest(Name("a.child.example.org"), RRType::A(), Zone::DELEGATION,
+ true, rr_child_ns_);
+ }
+
+ {
+ SCOPED_TRACE("Looking under delegation point in GLUE_OK mode");
+ findTest(Name("a.child.example.org"), RRType::A(), Zone::DELEGATION,
+ true, rr_child_ns_, NULL, NULL, Zone::FIND_GLUE_OK);
+ }
+}
+
+// Tests combination of wildcard and ANY.
+TEST_F(MemoryZoneTest, anyWildcard) {
+ EXPECT_EQ(SUCCESS, zone_.add(rr_wild_));
+
+ // First try directly the name (normal match)
+ {
+ SCOPED_TRACE("Asking direcly for *");
+ RRsetList target;
+ findTest(Name("*.wild.example.org"), RRType::ANY(), Zone::SUCCESS,
+ true, ConstRRsetPtr(), &target);
+ ASSERT_EQ(1, target.size());
+ EXPECT_EQ(RRType::A(), (*target.begin())->getType());
+ EXPECT_EQ(Name("*.wild.example.org"), (*target.begin())->getName());
+ }
+
+ // Then a wildcard match
+ {
+ SCOPED_TRACE("Asking in the wild way");
+ RRsetList target;
+ findTest(Name("a.wild.example.org"), RRType::ANY(), Zone::SUCCESS,
+ true, ConstRRsetPtr(), &target);
+ ASSERT_EQ(1, target.size());
+ EXPECT_EQ(RRType::A(), (*target.begin())->getType());
+ EXPECT_EQ(Name("a.wild.example.org"), (*target.begin())->getName());
+ }
}
-// same note as loadWildcard applies.
-TEST_F(MemoryZoneTest, loadEmptyWildcard) {
+// Test there's nothing in the wildcard in the middle if we load
+// wild.*.foo.example.org.
+TEST_F(MemoryZoneTest, emptyWildcard) {
/*
* example.org.
* foo
@@ -681,17 +793,96 @@ TEST_F(MemoryZoneTest, loadEmptyWildcard) {
* wild
*/
EXPECT_EQ(SUCCESS, zone_.add(rr_emptywild_));
- findTest(Name("*.foo.example.org"), RRType::A(), Zone::NXRRSET);
- findTest(Name("foo.example.org"), RRType::A(), Zone::NXRRSET);
+
+ {
+ SCOPED_TRACE("Asking for the original record under wildcard");
+ findTest(Name("wild.*.foo.example.org"), RRType::A(), Zone::SUCCESS,
+ true, rr_emptywild_);
+ }
+
+ {
+ SCOPED_TRACE("Asking for A record");
+ findTest(Name("a.foo.example.org"), RRType::A(), Zone::NXRRSET);
+ findTest(Name("*.foo.example.org"), RRType::A(), Zone::NXRRSET);
+ findTest(Name("foo.example.org"), RRType::A(), Zone::NXRRSET);
+ }
+
+ {
+ SCOPED_TRACE("Asking for ANY record");
+ RRsetList normalTarget;
+ findTest(Name("*.foo.example.org"), RRType::ANY(), Zone::NXRRSET, true,
+ ConstRRsetPtr(), &normalTarget);
+ EXPECT_EQ(0, normalTarget.size());
+
+ RRsetList wildTarget;
+ findTest(Name("a.foo.example.org"), RRType::ANY(), Zone::NXRRSET, true,
+ ConstRRsetPtr(), &wildTarget);
+ EXPECT_EQ(0, wildTarget.size());
+ }
+
+ {
+ SCOPED_TRACE("Asking on the non-terminal");
+ findTest(Name("wild.bar.foo.example.org"), RRType::A(),
+ Zone::NXRRSET);
+ }
}
-// same note as loadWildcard applies.
-TEST_F(MemoryZoneTest, loadNestedEmptyWildcard) {
+// Same as emptyWildcard, but with multiple * in the path.
+TEST_F(MemoryZoneTest, nestedEmptyWildcard) {
EXPECT_EQ(SUCCESS, zone_.add(rr_nested_emptywild_));
- findTest(Name("*.foo.*.bar.example.org"), RRType::A(), Zone::NXRRSET);
- findTest(Name("foo.*.bar.example.org"), RRType::A(), Zone::NXRRSET);
- findTest(Name("*.bar.example.org"), RRType::A(), Zone::NXRRSET);
- findTest(Name("bar.example.org"), RRType::A(), Zone::NXRRSET);
+
+ {
+ SCOPED_TRACE("Asking for the original record under wildcards");
+ findTest(Name("wild.*.foo.*.bar.example.org"), RRType::A(),
+ Zone::SUCCESS, true, rr_nested_emptywild_);
+ }
+
+ {
+ SCOPED_TRACE("Matching wildcard against empty nonterminal");
+
+ const char* names[] = {
+ "baz.foo.*.bar.example.org",
+ "baz.foo.baz.bar.example.org",
+ "*.foo.baz.bar.example.org",
+ NULL
+ };
+
+ for (const char** name(names); *name != NULL; ++ name) {
+ SCOPED_TRACE(string("Node ") + *name);
+ findTest(Name(*name), RRType::A(), Zone::NXRRSET);
+ }
+ }
+
+ // Domains to test
+ const char* names[] = {
+ "*.foo.*.bar.example.org",
+ "foo.*.bar.example.org",
+ "*.bar.example.org",
+ "bar.example.org",
+ NULL
+ };
+
+ {
+ SCOPED_TRACE("Asking directly for A on parent nodes");
+
+ for (const char** name(names); *name != NULL; ++ name) {
+ SCOPED_TRACE(string("Node ") + *name);
+ findTest(Name(*name), RRType::A(), Zone::NXRRSET);
+ }
+ }
+
+ {
+ SCOPED_TRACE("Asking for ANY on parent nodes");
+
+ for (const char** name(names); *name != NULL; ++ name) {
+ SCOPED_TRACE(string("Node ") + *name);
+
+ RRsetList target;
+ findTest(Name(*name), RRType::ANY(), Zone::NXRRSET, true,
+ ConstRRsetPtr(), &target);
+ EXPECT_EQ(0, target.size());
+ }
+ }
}
TEST_F(MemoryZoneTest, loadBadWildcard) {
More information about the bind10-changes
mailing list