BIND 10 master, updated. c86612cd4120b9ad3d00978c04ea252e7d501e44 Merge #1176
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Sep 7 08:34:21 UTC 2011
The branch, master has been updated
via c86612cd4120b9ad3d00978c04ea252e7d501e44 (commit)
via c1c2ddf5be4556e6e8cd52a314ddd6d026c7e540 (commit)
via 04b04226b726b6e1fea6bba970556b9ed5cc3446 (commit)
via 3a838eb454ed0de4f073b99e94e02014eca63a56 (commit)
via 38c8e9a9ccfd7fd57bc5fa5090c86cf7b7920d28 (commit)
via ddf9da5175b1182810838861f1464fb05fe00104 (commit)
via b131dd71ce147b4efcece9dd8fba16c51fefa492 (commit)
via 84d83c1d8979e2906971af79f2e41083299beb7e (commit)
via 8d380bb47dd24c7fd2c4880a4106835d871bf4d5 (commit)
via 77ba8639c274865c762eee688383c321f18ef889 (commit)
from 75e756cdf9d5b08e859afac5cef38bd818a90e60 (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 c86612cd4120b9ad3d00978c04ea252e7d501e44
Merge: 75e756cdf9d5b08e859afac5cef38bd818a90e60 c1c2ddf5be4556e6e8cd52a314ddd6d026c7e540
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Wed Sep 7 10:28:31 2011 +0200
Merge #1176
RRSIG support for database DataSources
commit c1c2ddf5be4556e6e8cd52a314ddd6d026c7e540
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Wed Sep 7 10:24:23 2011 +0200
[1176] Check no DNSSEC_OK means no RRSIGs
-----------------------------------------------------------------------
Summary of changes:
src/bin/auth/query.cc | 38 ++++++----
src/bin/auth/query.h | 10 ++-
src/bin/auth/tests/query_unittest.cc | 102 +++++++++++++++++++++++++++-
src/lib/datasrc/tests/database_unittest.cc | 8 ++
src/lib/datasrc/zone.h | 19 +++++-
5 files changed, 156 insertions(+), 21 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/bin/auth/query.cc b/src/bin/auth/query.cc
index 3fe03c8..898fff7 100644
--- a/src/bin/auth/query.cc
+++ b/src/bin/auth/query.cc
@@ -67,20 +67,21 @@ Query::findAddrs(ZoneFinder& zone, const Name& qname,
// Find A rrset
if (qname_ != qname || qtype_ != RRType::A()) {
ZoneFinder::FindResult a_result = zone.find(qname, RRType::A(), NULL,
- options);
+ options | dnssec_opt_);
if (a_result.code == ZoneFinder::SUCCESS) {
response_.addRRset(Message::SECTION_ADDITIONAL,
- boost::const_pointer_cast<RRset>(a_result.rrset));
+ boost::const_pointer_cast<RRset>(a_result.rrset), dnssec_);
}
}
// Find AAAA rrset
if (qname_ != qname || qtype_ != RRType::AAAA()) {
ZoneFinder::FindResult aaaa_result =
- zone.find(qname, RRType::AAAA(), NULL, options);
+ zone.find(qname, RRType::AAAA(), NULL, options | dnssec_opt_);
if (aaaa_result.code == ZoneFinder::SUCCESS) {
response_.addRRset(Message::SECTION_ADDITIONAL,
- boost::const_pointer_cast<RRset>(aaaa_result.rrset));
+ boost::const_pointer_cast<RRset>(aaaa_result.rrset),
+ dnssec_);
}
}
}
@@ -88,7 +89,7 @@ Query::findAddrs(ZoneFinder& zone, const Name& qname,
void
Query::putSOA(ZoneFinder& zone) const {
ZoneFinder::FindResult soa_result(zone.find(zone.getOrigin(),
- RRType::SOA()));
+ RRType::SOA(), NULL, dnssec_opt_));
if (soa_result.code != ZoneFinder::SUCCESS) {
isc_throw(NoSOA, "There's no SOA record in zone " <<
zone.getOrigin().toText());
@@ -99,7 +100,7 @@ Query::putSOA(ZoneFinder& zone) const {
* to insist.
*/
response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<RRset>(soa_result.rrset));
+ boost::const_pointer_cast<RRset>(soa_result.rrset), dnssec_);
}
}
@@ -107,14 +108,15 @@ void
Query::getAuthAdditional(ZoneFinder& zone) const {
// Fill in authority and addtional sections.
ZoneFinder::FindResult ns_result = zone.find(zone.getOrigin(),
- RRType::NS());
+ RRType::NS(), NULL,
+ dnssec_opt_);
// zone origin name should have NS records
if (ns_result.code != ZoneFinder::SUCCESS) {
isc_throw(NoApexNS, "There's no apex NS records in zone " <<
zone.getOrigin().toText());
} else {
response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<RRset>(ns_result.rrset));
+ boost::const_pointer_cast<RRset>(ns_result.rrset), dnssec_);
// Handle additional for authority section
getAdditional(zone, *ns_result.rrset);
}
@@ -147,12 +149,14 @@ Query::process() const {
keep_doing = false;
std::auto_ptr<RRsetList> target(qtype_is_any ? new RRsetList : NULL);
const ZoneFinder::FindResult db_result(
- result.zone_finder->find(qname_, qtype_, target.get()));
+ result.zone_finder->find(qname_, qtype_, target.get(),
+ dnssec_opt_));
switch (db_result.code) {
case ZoneFinder::DNAME: {
// First, put the dname into the answer
response_.addRRset(Message::SECTION_ANSWER,
- boost::const_pointer_cast<RRset>(db_result.rrset));
+ boost::const_pointer_cast<RRset>(db_result.rrset),
+ dnssec_);
/*
* Empty DNAME should never get in, as it is impossible to
* create one in master file.
@@ -188,7 +192,7 @@ Query::process() const {
qname_.getLabelCount() -
db_result.rrset->getName().getLabelCount()).
concatenate(dname.getDname())));
- response_.addRRset(Message::SECTION_ANSWER, cname);
+ response_.addRRset(Message::SECTION_ANSWER, cname, dnssec_);
break;
}
case ZoneFinder::CNAME:
@@ -202,20 +206,23 @@ Query::process() const {
* So, just put it there.
*/
response_.addRRset(Message::SECTION_ANSWER,
- boost::const_pointer_cast<RRset>(db_result.rrset));
+ boost::const_pointer_cast<RRset>(db_result.rrset),
+ dnssec_);
break;
case ZoneFinder::SUCCESS:
if (qtype_is_any) {
// If quety type is ANY, insert all RRs under the domain
// into answer section.
BOOST_FOREACH(RRsetPtr rrset, *target) {
- response_.addRRset(Message::SECTION_ANSWER, rrset);
+ response_.addRRset(Message::SECTION_ANSWER, rrset,
+ dnssec_);
// Handle additional for answer section
getAdditional(*result.zone_finder, *rrset.get());
}
} else {
response_.addRRset(Message::SECTION_ANSWER,
- boost::const_pointer_cast<RRset>(db_result.rrset));
+ boost::const_pointer_cast<RRset>(db_result.rrset),
+ dnssec_);
// Handle additional for answer section
getAdditional(*result.zone_finder, *db_result.rrset);
}
@@ -233,7 +240,8 @@ Query::process() const {
case ZoneFinder::DELEGATION:
response_.setHeaderFlag(Message::HEADERFLAG_AA, false);
response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<RRset>(db_result.rrset));
+ boost::const_pointer_cast<RRset>(db_result.rrset),
+ dnssec_);
getAdditional(*result.zone_finder, *db_result.rrset);
break;
case ZoneFinder::NXDOMAIN:
diff --git a/src/bin/auth/query.h b/src/bin/auth/query.h
index 13523e8..0ebbed8 100644
--- a/src/bin/auth/query.h
+++ b/src/bin/auth/query.h
@@ -139,11 +139,15 @@ public:
/// \param qname The query name
/// \param qtype The RR type of the query
/// \param response The response message to store the answer to the query.
+ /// \param dnssec If the answer should include signatures and NSEC/NSEC3 if
+ /// possible.
Query(const isc::datasrc::DataSourceClient& datasrc_client,
const isc::dns::Name& qname, const isc::dns::RRType& qtype,
- isc::dns::Message& response) :
+ isc::dns::Message& response, bool dnssec = false) :
datasrc_client_(datasrc_client), qname_(qname), qtype_(qtype),
- response_(response)
+ response_(response), dnssec_(dnssec),
+ dnssec_opt_(dnssec ? isc::datasrc::ZoneFinder::FIND_DNSSEC :
+ isc::datasrc::ZoneFinder::FIND_DEFAULT)
{}
/// Process the query.
@@ -211,6 +215,8 @@ private:
const isc::dns::Name& qname_;
const isc::dns::RRType& qtype_;
isc::dns::Message& response_;
+ const bool dnssec_;
+ const isc::datasrc::ZoneFinder::FindOptions dnssec_opt_;
};
}
diff --git a/src/bin/auth/tests/query_unittest.cc b/src/bin/auth/tests/query_unittest.cc
index 68f0a1d..4b8f013 100644
--- a/src/bin/auth/tests/query_unittest.cc
+++ b/src/bin/auth/tests/query_unittest.cc
@@ -111,7 +111,8 @@ public:
dname_name_("dname.example.com"),
has_SOA_(true),
has_apex_NS_(true),
- rrclass_(RRClass::IN())
+ rrclass_(RRClass::IN()),
+ include_rrsig_anyway_(false)
{
stringstream zone_stream;
zone_stream << soa_txt << zone_ns_txt << ns_addrs_txt <<
@@ -137,11 +138,14 @@ public:
// the apex NS.
void setApexNSFlag(bool on) { has_apex_NS_ = on; }
+ // Turn this on if you want it to return RRSIGs regardless of FIND_GLUE_OK
+ void setIncludeRRSIGAnyway(bool on) { include_rrsig_anyway_ = on; }
+
private:
typedef map<RRType, ConstRRsetPtr> RRsetStore;
typedef map<Name, RRsetStore> Domains;
Domains domains_;
- void loadRRset(ConstRRsetPtr rrset) {
+ void loadRRset(RRsetPtr rrset) {
domains_[rrset->getName()][rrset->getType()] = rrset;
if (rrset->getName() == delegation_name_ &&
rrset->getType() == RRType::NS()) {
@@ -149,6 +153,26 @@ private:
} else if (rrset->getName() == dname_name_ &&
rrset->getType() == RRType::DNAME()) {
dname_rrset_ = rrset;
+ // Add some signatures
+ } else if (rrset->getName() == Name("example.com.") &&
+ rrset->getType() == RRType::NS()) {
+ rrset->addRRsig(RdataPtr(new generic::RRSIG("NS 5 3 3600 "
+ "20000101000000 "
+ "20000201000000 "
+ "12345 example.com. "
+ "FAKEFAKEFAKE")));
+ } else if (rrset->getType() == RRType::A()) {
+ rrset->addRRsig(RdataPtr(new generic::RRSIG("A 5 3 3600 "
+ "20000101000000 "
+ "20000201000000 "
+ "12345 example.com. "
+ "FAKEFAKEFAKE")));
+ } else if (rrset->getType() == RRType::AAAA()) {
+ rrset->addRRsig(RdataPtr(new generic::RRSIG("AAAA 5 3 3600 "
+ "20000101000000 "
+ "20000201000000 "
+ "12345 example.com. "
+ "FAKEFAKEFAKE")));
}
}
@@ -161,6 +185,7 @@ private:
ConstRRsetPtr delegation_rrset_;
ConstRRsetPtr dname_rrset_;
const RRClass rrclass_;
+ bool include_rrsig_anyway_;
};
ZoneFinder::FindResult
@@ -195,7 +220,26 @@ MockZoneFinder::find(const Name& name, const RRType& type,
RRsetStore::const_iterator found_rrset =
found_domain->second.find(type);
if (found_rrset != found_domain->second.end()) {
- return (FindResult(SUCCESS, found_rrset->second));
+ ConstRRsetPtr rrset;
+ // Strip whatever signature there is in case DNSSEC is not required
+ // Just to make sure the Query asks for it when it is needed
+ if (options & ZoneFinder::FIND_DNSSEC ||
+ include_rrsig_anyway_ ||
+ !found_rrset->second->getRRsig()) {
+ rrset = found_rrset->second;
+ } else {
+ RRsetPtr noconst(new RRset(found_rrset->second->getName(),
+ found_rrset->second->getClass(),
+ found_rrset->second->getType(),
+ found_rrset->second->getTTL()));
+ for (RdataIteratorPtr
+ i(found_rrset->second->getRdataIterator());
+ !i->isLast(); i->next()) {
+ noconst->addRdata(i->getCurrent());
+ }
+ rrset = noconst;
+ }
+ return (FindResult(SUCCESS, rrset));
}
// If not found but we have a target, fill it with all RRsets here
@@ -304,6 +348,58 @@ TEST_F(QueryTest, exactMatch) {
www_a_txt, zone_ns_txt, ns_addrs_txt);
}
+TEST_F(QueryTest, exactMatchIgnoreSIG) {
+ // Check that we do not include the RRSIG when not requested even when
+ // we receive it from the data source.
+ mock_finder->setIncludeRRSIGAnyway(true);
+ Query query(memory_client, qname, qtype, response);
+ EXPECT_NO_THROW(query.process());
+ // find match rrset
+ responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 3,
+ www_a_txt, zone_ns_txt, ns_addrs_txt);
+}
+
+TEST_F(QueryTest, dnssecPositive) {
+ // Just like exactMatch, but the signatures should be included as well
+ Query query(memory_client, qname, qtype, response, true);
+ EXPECT_NO_THROW(query.process());
+ // find match rrset
+ // We can't let responseCheck to check the additional section as well,
+ // it gets confused by the two RRs for glue.delegation.../RRSIG due
+ // to it's design and fixing it would be hard. Therefore we simply
+ // check manually this one time.
+ responseCheck(response, Rcode::NOERROR(), AA_FLAG, 2, 4, 6,
+ (www_a_txt + std::string("www.example.com. 3600 IN RRSIG "
+ "A 5 3 3600 20000101000000 "
+ "20000201000000 12345 example.com. "
+ "FAKEFAKEFAKE\n")).c_str(),
+ (zone_ns_txt + std::string("example.com. 3600 IN RRSIG NS 5 "
+ "3 3600 20000101000000 "
+ "20000201000000 12345 "
+ "example.com. FAKEFAKEFAKE\n")).
+ c_str(), NULL);
+ RRsetIterator iterator(response.beginSection(Message::SECTION_ADDITIONAL));
+ const char* additional[] = {
+ "glue.delegation.example.com. 3600 IN A 192.0.2.153\n",
+ "glue.delegation.example.com. 3600 IN RRSIG A 5 3 3600 20000101000000 "
+ "20000201000000 12345 example.com. FAKEFAKEFAKE\n",
+ "glue.delegation.example.com. 3600 IN AAAA 2001:db8::53\n",
+ "glue.delegation.example.com. 3600 IN RRSIG AAAA 5 3 3600 "
+ "20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE\n",
+ "noglue.example.com. 3600 IN A 192.0.2.53\n",
+ "noglue.example.com. 3600 IN RRSIG A 5 3 3600 20000101000000 "
+ "20000201000000 12345 example.com. FAKEFAKEFAKE\n",
+ NULL
+ };
+ for (const char** rr(additional); *rr != NULL; ++ rr) {
+ ASSERT_FALSE(iterator ==
+ response.endSection(Message::SECTION_ADDITIONAL));
+ EXPECT_EQ(*rr, (*iterator)->toText());
+ iterator ++;
+ }
+ EXPECT_TRUE(iterator == response.endSection(Message::SECTION_ADDITIONAL));
+}
+
TEST_F(QueryTest, exactAddrMatch) {
// find match rrset, omit additional data which has already been provided
// in the answer section from the additional.
diff --git a/src/lib/datasrc/tests/database_unittest.cc b/src/lib/datasrc/tests/database_unittest.cc
index 1fb79bc..cf671bb 100644
--- a/src/lib/datasrc/tests/database_unittest.cc
+++ b/src/lib/datasrc/tests/database_unittest.cc
@@ -470,6 +470,7 @@ private:
// Something for wildcards
addRecord("A", "3600", "", "192.0.2.5");
+ addRecord("RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
addCurName("*.wild.example.org.");
addRecord("AAAA", "3600", "", "2001:db8::5");
addCurName("cancel.here.wild.example.org.");
@@ -1167,7 +1168,10 @@ TEST_F(DatabaseClientTest, wildcard) {
shared_ptr<DatabaseClient::Finder> finder(getFinder());
// First, simple wildcard match
+ // Check also that the RRSIG is added from the wildcard (not modified)
expected_rdatas_.push_back("192.0.2.5");
+ expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 20000201000000 "
+ "12345 example.org. FAKEFAKEFAKE");
doFindTest(finder, isc::dns::Name("a.wild.example.org"),
isc::dns::RRType::A(), isc::dns::RRType::A(),
isc::dns::RRTTL(3600), ZoneFinder::SUCCESS, expected_rdatas_,
@@ -1177,6 +1181,7 @@ TEST_F(DatabaseClientTest, wildcard) {
isc::dns::RRTTL(3600), ZoneFinder::SUCCESS, expected_rdatas_,
expected_sig_rdatas_);
expected_rdatas_.clear();
+ expected_sig_rdatas_.clear();
doFindTest(finder, isc::dns::Name("a.wild.example.org"),
isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
isc::dns::RRTTL(3600), ZoneFinder::NXRRSET, expected_rdatas_,
@@ -1188,11 +1193,14 @@ TEST_F(DatabaseClientTest, wildcard) {
// Direct request for thi wildcard
expected_rdatas_.push_back("192.0.2.5");
+ expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 20000201000000 "
+ "12345 example.org. FAKEFAKEFAKE");
doFindTest(finder, isc::dns::Name("*.wild.example.org"),
isc::dns::RRType::A(), isc::dns::RRType::A(),
isc::dns::RRTTL(3600), ZoneFinder::SUCCESS, expected_rdatas_,
expected_sig_rdatas_);
expected_rdatas_.clear();
+ expected_sig_rdatas_.clear();
doFindTest(finder, isc::dns::Name("*.wild.example.org"),
isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
isc::dns::RRTTL(3600), ZoneFinder::NXRRSET, expected_rdatas_,
diff --git a/src/lib/datasrc/zone.h b/src/lib/datasrc/zone.h
index 0dacc5d..989b250 100644
--- a/src/lib/datasrc/zone.h
+++ b/src/lib/datasrc/zone.h
@@ -107,7 +107,11 @@ public:
/// performed on these values to express compound options.
enum FindOptions {
FIND_DEFAULT = 0, ///< The default options
- FIND_GLUE_OK = 1 ///< Allow search under a zone cut
+ FIND_GLUE_OK = 1, ///< Allow search under a zone cut
+ FIND_DNSSEC = 2 ///< Require DNSSEC data in the answer
+ ///< (RRSIG, NSEC, etc.). The implementation
+ ///< is allowed to include it even if it is
+ ///< not set.
};
///
@@ -201,6 +205,19 @@ public:
//@}
};
+/// \brief Operator to combine FindOptions
+///
+/// We would need to manually static-cast the options if we put or
+/// between them, which is undesired with bit-flag options. Therefore
+/// we hide the cast here, which is the simplest solution and it still
+/// provides reasonable level of type safety.
+inline ZoneFinder::FindOptions operator |(ZoneFinder::FindOptions a,
+ ZoneFinder::FindOptions b)
+{
+ return (static_cast<ZoneFinder::FindOptions>(static_cast<unsigned>(a) |
+ static_cast<unsigned>(b)));
+}
+
/// \brief A pointer-like type pointing to a \c ZoneFinder object.
typedef boost::shared_ptr<ZoneFinder> ZoneFinderPtr;
More information about the bind10-changes
mailing list