BIND 10 trac2433, updated. 2d107bd1f98f6a3aed2120213d713111246e6535 [2433] removed def ctor of callbacks; allow passing NULL (empty) instead.
BIND 10 source code commits
bind10-changes at lists.isc.org
Thu Jan 3 18:59:44 UTC 2013
The branch, trac2433 has been updated
via 2d107bd1f98f6a3aed2120213d713111246e6535 (commit)
via 57e0fe723d9769cb893ae168f7d9374280670c4d (commit)
via 28f38670d37fe76c2481df6b8f82284ce4949de2 (commit)
via 9a2fd23cdd58afe5dbc932dead8f10b0ac22605c (commit)
via 385f156f420aa17a1d6f07bcb17a87075f9d4492 (commit)
via dd444334eb873bd925639e3141c3a863fad1e47a (commit)
via 5d3af5f896df69f42590921a44650745411673fa (commit)
via bbb8a8f0ed42862b7e5b54e7611cb0d0e364203b (commit)
via ee424bbc727b754b8030fb2adaa69c578f096de9 (commit)
via bdf19add5fca40dbc91c6ce4c0d87d8bb6080bde (commit)
via cfbb9eada0a6e0ff8a2faead73f870d3ca3400fc (commit)
via 8bca74f57a81fa7e2dc2569692b253dbf19270b4 (commit)
via 34929974f3655f19029d83234e4c5b89b85eaf99 (commit)
from c466b2fb0a4888db16ff0888dc0f8c9875d6f43c (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 2d107bd1f98f6a3aed2120213d713111246e6535
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Thu Jan 3 10:59:32 2013 -0800
[2433] removed def ctor of callbacks; allow passing NULL (empty) instead.
commit 57e0fe723d9769cb893ae168f7d9374280670c4d
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Thu Jan 3 10:40:53 2013 -0800
[2433] use a wrapper functor instead of a separate class.
maybe a matter of taste, but this version would be a bit more concise.
commit 28f38670d37fe76c2481df6b8f82284ce4949de2
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Thu Jan 3 10:20:20 2013 -0800
[2433] adjusted with the latest ver of #2432: type of find(), some param order.
commit 9a2fd23cdd58afe5dbc932dead8f10b0ac22605c
Merge: 385f156 dd44433
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Thu Jan 3 10:15:13 2013 -0800
[2433] Merge remote-tracking branch 'origin/trac2432' into trac2433
commit 385f156f420aa17a1d6f07bcb17a87075f9d4492
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Thu Jan 3 09:01:40 2013 -0800
[2433] corrected minor wording error in a comment.
-----------------------------------------------------------------------
Summary of changes:
src/lib/dns/rrset_collection.cc | 59 ++++++---------
src/lib/dns/rrset_collection.h | 42 +++++++----
src/lib/dns/rrset_collection_base.h | 34 ++++-----
src/lib/dns/tests/rrset_collection_unittest.cc | 55 ++++----------
src/lib/dns/tests/zone_checker_unittest.cc | 18 ++++-
src/lib/dns/zone_checker.cc | 96 ++++++++++++------------
src/lib/dns/zone_checker.h | 33 ++++----
7 files changed, 160 insertions(+), 177 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/lib/dns/rrset_collection.cc b/src/lib/dns/rrset_collection.cc
index 53f9702..f8cfbc3 100644
--- a/src/lib/dns/rrset_collection.cc
+++ b/src/lib/dns/rrset_collection.cc
@@ -15,6 +15,7 @@
#include <dns/rrset_collection.h>
#include <dns/master_loader_callbacks.h>
#include <dns/master_loader.h>
+#include <dns/rrcollator.h>
#include <exceptions/exceptions.h>
@@ -32,16 +33,6 @@ RRsetCollection::loaderCallback(const std::string&, size_t, const std::string&)
}
void
-RRsetCollection::addRRset(const Name& name, const RRClass& rrclass,
- const RRType& rrtype, const RRTTL& rrttl,
- const rdata::RdataPtr& data)
-{
- RRsetPtr rrset(new BasicRRset(name, rrclass, rrtype, rrttl));
- rrset->addRdata(data);
- addRRset(rrset);
-}
-
-void
RRsetCollection::addRRset(RRsetPtr rrset) {
const CollectionKey key(rrset->getClass(), rrset->getType(),
rrset->getName());
@@ -55,41 +46,32 @@ RRsetCollection::addRRset(RRsetPtr rrset) {
rrsets_.insert(std::pair<CollectionKey, RRsetPtr>(key, rrset));
}
-RRsetCollection::RRsetCollection(const char* filename, const Name& origin,
- const RRClass& rrclass)
+template<typename T>
+void
+RRsetCollection::constructHelper(T source, const isc::dns::Name& origin,
+ const isc::dns::RRClass& rrclass)
{
+ RRCollator collator(boost::bind(&RRsetCollection::addRRset, this, _1));
MasterLoaderCallbacks callbacks
(boost::bind(&RRsetCollection::loaderCallback, this, _1, _2, _3),
boost::bind(&RRsetCollection::loaderCallback, this, _1, _2, _3));
- MasterLoader loader(filename, origin, rrclass, callbacks,
- boost::bind(&RRsetCollection::addRRset,
- this, _1, _2, _3, _4, _5),
+ MasterLoader loader(source, origin, rrclass, callbacks,
+ collator.getCallback(),
MasterLoader::DEFAULT);
loader.load();
+ collator.flush();
}
-RRsetCollection::RRsetCollection(std::istream& input_stream, const Name& origin,
+RRsetCollection::RRsetCollection(const char* filename, const Name& origin,
const RRClass& rrclass)
{
- MasterLoaderCallbacks callbacks
- (boost::bind(&RRsetCollection::loaderCallback, this, _1, _2, _3),
- boost::bind(&RRsetCollection::loaderCallback, this, _1, _2, _3));
- MasterLoader loader(input_stream, origin, rrclass, callbacks,
- boost::bind(&RRsetCollection::addRRset,
- this, _1, _2, _3, _4, _5),
- MasterLoader::DEFAULT);
- loader.load();
+ constructHelper<const char*>(filename, origin, rrclass);
}
-const AbstractRRset*
-RRsetCollection::find(const Name& name, const RRType& rrtype,
- const RRClass& rrclass) const {
- const CollectionKey key(rrclass, rrtype, name);
- CollectionMap::const_iterator it = rrsets_.find(key);
- if (it != rrsets_.end()) {
- return (&(*it->second));
- }
- return (NULL);
+RRsetCollection::RRsetCollection(std::istream& input_stream, const Name& origin,
+ const RRClass& rrclass)
+{
+ constructHelper<std::istream&>(input_stream, origin, rrclass);
}
RRsetPtr
@@ -115,12 +97,19 @@ RRsetCollection::find(const Name& name, const RRClass& rrclass,
return (ConstRRsetPtr());
}
-void
+bool
RRsetCollection::removeRRset(const Name& name, const RRClass& rrclass,
const RRType& rrtype)
{
const CollectionKey key(rrclass, rrtype, name);
- rrsets_.erase(key);
+
+ CollectionMap::iterator it = rrsets_.find(key);
+ if (it == rrsets_.end()) {
+ return (false);
+ }
+
+ rrsets_.erase(it);
+ return (true);
}
RRsetCollectionBase::IterPtr
diff --git a/src/lib/dns/rrset_collection.h b/src/lib/dns/rrset_collection.h
index dfa4dd7..49dc820 100644
--- a/src/lib/dns/rrset_collection.h
+++ b/src/lib/dns/rrset_collection.h
@@ -31,6 +31,10 @@ namespace dns {
class RRsetCollection : public RRsetCollectionBase {
public:
/// \brief Constructor.
+ ///
+ /// This constructor creates an empty collection without any data in
+ /// it. RRsets can be added to the collection with the \c addRRset()
+ /// method.
RRsetCollection() {}
/// \brief Constructor.
@@ -73,43 +77,49 @@ public:
/// and managed by the \c RRsetCollection. It throws an
/// \c isc::InvalidParameter exception if an rrset with the same
/// class, type and name already exists.
+ ///
+ /// Callers must not modify the RRset after adding it to the
+ /// collection, as the rrset is indexed internally by the
+ /// collection.
void addRRset(isc::dns::RRsetPtr rrset);
/// \brief Remove an RRset from the collection.
///
/// RRset(s) matching the \c name, \c rrclass and \c rrtype are
/// removed from the collection.
- void removeRRset(const isc::dns::Name& name,
+ ///
+ /// \returns \c true if a matching RRset was deleted, \c false if no
+ /// such RRset exists.
+ bool removeRRset(const isc::dns::Name& name,
const isc::dns::RRClass& rrclass,
const isc::dns::RRType& rrtype);
/// \brief Find a matching RRset in the collection.
///
/// Returns the RRset in the collection that exactly matches the
- /// given \c name and \c rrtype. If no matching RRset is found,
- /// \c NULL is returned.
+ /// given \c name, \c rrclass and \c rrtype. If no matching RRset
+ /// is found, \c NULL is returned.
///
/// \param name The name of the RRset to search for.
- /// \param rrtype The type of the RRset to search for.
/// \param rrclass The class of the RRset to search for.
- /// \returns A pointer to the RRset if found, \c NULL otherwise.
- virtual const isc::dns::AbstractRRset* find
- (const isc::dns::Name& name, const isc::dns::RRType& rrtype,
- const isc::dns::RRClass& rrclass)
- const;
+ /// \param rrtype The type of the RRset to search for.
+ /// \returns The RRset if found, \c NULL otherwise.
+ virtual isc::dns::ConstRRsetPtr find(const isc::dns::Name& name,
+ const isc::dns::RRClass& rrclass,
+ const isc::dns::RRType& rrtype) const;
+ /// \brief Find a matching RRset in the collection (non-const
+ /// variant).
+ ///
+ /// See above for a description of the method and arguments.
isc::dns::RRsetPtr find(const isc::dns::Name& name,
const isc::dns::RRClass& rrclass,
const isc::dns::RRType& rrtype);
- isc::dns::ConstRRsetPtr find(const isc::dns::Name& name,
- const isc::dns::RRClass& rrclass,
- const isc::dns::RRType& rrtype) const;
-
private:
- void addRRset(const isc::dns::Name& name, const isc::dns::RRClass& rrclass,
- const isc::dns::RRType& rrtype, const isc::dns::RRTTL& rrttl,
- const isc::dns::rdata::RdataPtr& data);
+ template<typename T>
+ void constructHelper(T source, const isc::dns::Name& origin,
+ const isc::dns::RRClass& rrclass);
void loaderCallback(const std::string&, size_t, const std::string&);
typedef boost::tuple<isc::dns::RRClass, isc::dns::RRType, isc::dns::Name>
diff --git a/src/lib/dns/rrset_collection_base.h b/src/lib/dns/rrset_collection_base.h
index eae7f6d..38dc76c 100644
--- a/src/lib/dns/rrset_collection_base.h
+++ b/src/lib/dns/rrset_collection_base.h
@@ -41,16 +41,16 @@ public:
/// \brief Find a matching RRset in the collection.
///
/// Returns the RRset in the collection that exactly matches the
- /// given \c name and \c rrtype. If no matching RRset is found,
- /// \c NULL is returned.
+ /// given \c name, \c rrclass and \c rrtype. If no matching RRset
+ /// is found, \c NULL is returned.
///
/// \param name The name of the RRset to search for.
/// \param rrtype The type of the RRset to search for.
/// \param rrclass The class of the RRset to search for.
- /// \returns A pointer to the RRset if found, \c NULL otherwise.
- virtual const isc::dns::AbstractRRset* find
- (const isc::dns::Name& name, const isc::dns::RRType& rrtype,
- const isc::dns::RRClass& rrclass)
+ /// \returns The RRset if found, \c NULL otherwise.
+ virtual isc::dns::ConstRRsetPtr find
+ (const isc::dns::Name& name, const isc::dns::RRClass& rrclass,
+ const isc::dns::RRType& rrtype)
const = 0;
/// \brief Destructor
@@ -105,11 +105,11 @@ public:
///
/// It behaves like a \c std::iterator forward iterator, so please
/// see its documentation for usage.
- class iterator : std::iterator<std::forward_iterator_tag,
+ class Iterator : std::iterator<std::forward_iterator_tag,
const isc::dns::AbstractRRset>
{
public:
- explicit iterator(IterPtr iter) :
+ explicit Iterator(IterPtr iter) :
iter_(iter)
{}
@@ -117,22 +117,22 @@ public:
return (iter_->getValue());
}
- iterator& operator++() {
+ Iterator& operator++() {
iter_ = iter_->getNext();
return (*this);
}
- iterator operator++(int) {
- iterator tmp(iter_);
+ Iterator operator++(int) {
+ Iterator tmp(iter_);
++*this;
return (tmp);
}
- bool operator==(const iterator& other) const {
+ bool operator==(const Iterator& other) const {
return (iter_->equals(*other.iter_));
}
- bool operator!=(const iterator& other) const {
+ bool operator!=(const Iterator& other) const {
return (!iter_->equals(*other.iter_));
}
@@ -142,14 +142,14 @@ public:
/// \brief Returns an iterator pointing to the beginning of the
/// collection.
- iterator begin() {
- return iterator(getBeginning());
+ Iterator begin() {
+ return Iterator(getBeginning());
}
/// \brief Returns an iterator pointing past the end of the
/// collection.
- iterator end() {
- return iterator(getEnd());
+ Iterator end() {
+ return Iterator(getEnd());
}
};
diff --git a/src/lib/dns/tests/rrset_collection_unittest.cc b/src/lib/dns/tests/rrset_collection_unittest.cc
index 7d1b6f6..183ec51 100644
--- a/src/lib/dns/tests/rrset_collection_unittest.cc
+++ b/src/lib/dns/tests/rrset_collection_unittest.cc
@@ -44,8 +44,8 @@ TEST_F(RRsetCollectionTest, istreamConstructor) {
std::ifstream fs(TEST_DATA_SRCDIR "/example.org");
RRsetCollection collection2(fs, origin, rrclass);
- RRsetCollectionBase::iterator iter = collection.begin();
- RRsetCollectionBase::iterator iter2 = collection2.begin();
+ RRsetCollectionBase::Iterator iter = collection.begin();
+ RRsetCollectionBase::Iterator iter2 = collection2.begin();
while (iter != collection.end()) {
EXPECT_TRUE(iter2 != collection2.end());
EXPECT_EQ((*iter).toText(), (*iter2).toText());
@@ -55,34 +55,6 @@ TEST_F(RRsetCollectionTest, istreamConstructor) {
EXPECT_TRUE(iter2 == collection2.end());
}
-TEST_F(RRsetCollectionTest, findBase) {
- // Test the find() that returns isc::dns::AbstractRRset*
- const AbstractRRset* rrset = collection.find(Name("www.example.org"),
- RRType::A(), rrclass);
- EXPECT_NE(static_cast<AbstractRRset*>(NULL), rrset);
- EXPECT_EQ(RRType::A(), rrset->getType());
- EXPECT_EQ(RRTTL(3600), rrset->getTTL());
- EXPECT_EQ(RRClass("IN"), rrset->getClass());
- EXPECT_EQ(Name("www.example.org"), rrset->getName());
-
- // foo.example.org doesn't exist
- rrset = collection.find(Name("foo.example.org"), RRType::A(), rrclass);
- EXPECT_EQ(static_cast<AbstractRRset*>(NULL), rrset);
-
- // www.example.org exists, but not with MX
- rrset = collection.find(Name("www.example.org"), RRType::MX(), rrclass);
- EXPECT_EQ(static_cast<AbstractRRset*>(NULL), rrset);
-
- // www.example.org exists, with AAAA
- rrset = collection.find(Name("www.example.org"), RRType::AAAA(), rrclass);
- EXPECT_NE(static_cast<AbstractRRset*>(NULL), rrset);
-
- // www.example.org with AAAA does not exist in RRClass::CH()
- rrset = collection.find(Name("www.example.org"), RRType::AAAA(),
- RRClass::CH());
- EXPECT_EQ(static_cast<AbstractRRset*>(NULL), rrset);
-}
-
template <typename T, typename TP>
void doFind(T& collection, const RRClass& rrclass) {
// Test the find() that returns ConstRRsetPtr
@@ -152,13 +124,20 @@ doAddAndRemove(RRsetCollection& collection, const RRClass& rrclass) {
collection.addRRset(rrset);
}, isc::InvalidParameter);
- // Remove foo.example.org/A
- collection.removeRRset(Name("foo.example.org"), rrclass, RRType::A());
+ // Remove foo.example.org/A, which should pass
+ bool exists = collection.removeRRset(Name("foo.example.org"),
+ rrclass, RRType::A());
+ EXPECT_TRUE(exists);
// foo.example.org/A should not exist now
rrset_found = collection.find(Name("foo.example.org"), rrclass,
RRType::A());
EXPECT_FALSE(rrset_found);
+
+ // Removing foo.example.org/A should fail now
+ exists = collection.removeRRset(Name("foo.example.org"),
+ rrclass, RRType::A());
+ EXPECT_FALSE(exists);
}
TEST_F(RRsetCollectionTest, addAndRemove) {
@@ -184,7 +163,7 @@ TEST_F(RRsetCollectionTest, iteratorTest) {
// Here, we just count the records and do some basic tests on them.
size_t count = 0;
- for (RRsetCollection::iterator it = collection.begin();
+ for (RRsetCollection::Iterator it = collection.begin();
it != collection.end(); ++it) {
++count;
const AbstractRRset& rrset = *it;
@@ -204,12 +183,10 @@ public:
MyRRsetCollection()
{}
- virtual const isc::dns::AbstractRRset* find
- (const isc::dns::Name&, const isc::dns::RRType&,
- const isc::dns::RRClass&)
- const
- {
- return (NULL);
+ virtual isc::dns::ConstRRsetPtr find(const isc::dns::Name&,
+ const isc::dns::RRClass&,
+ const isc::dns::RRType&) const {
+ return (ConstRRsetPtr());
}
typedef std::list<isc::dns::RRset> MyCollection;
diff --git a/src/lib/dns/tests/zone_checker_unittest.cc b/src/lib/dns/tests/zone_checker_unittest.cc
index 9ded0e5..eb0f750 100644
--- a/src/lib/dns/tests/zone_checker_unittest.cc
+++ b/src/lib/dns/tests/zone_checker_unittest.cc
@@ -113,10 +113,6 @@ TEST_F(ZoneCheckerTest, checkGood) {
EXPECT_TRUE(checkZone(zname_, zclass_, *rrsets_, callbacks_));
checkIssues();
- // We can omit callbacks, in which case the default constructor for
- // the callbacks is used, meaning callbacks are no-op.
- EXPECT_TRUE(checkZone(zname_, zclass_, *rrsets_));
-
// Multiple NS RRs are okay.
rrsets_->removeRRset(zname_, zclass_, RRType::NS());
ns_->addRdata(generic::NS(ns_txt1));
@@ -133,6 +129,13 @@ TEST_F(ZoneCheckerTest, checkSOA) {
expected_errors_.push_back("zone example.com/IN: has 0 SOA records");
checkIssues();
+ // If null callback is specified, checkZone() only returns the final
+ // result.
+ ZoneCheckerCallbacks noerror_callbacks(
+ NULL, boost::bind(&ZoneCheckerTest::callback, this, _1, false));
+ EXPECT_FALSE(checkZone(zname_, zclass_, *rrsets_, noerror_callbacks));
+ checkIssues();
+
// If there are more than 1 SOA RR, it's also an error.
errors_.clear();
soa_->addRdata(generic::SOA(soa_txt));
@@ -190,6 +193,13 @@ TEST_F(ZoneCheckerTest, checkNSData) {
expected_warns_.push_back("zone example.com/IN: NS has no address");
checkIssues();
+ // Same check, but disabling warning callback. Same result, but without
+ // the warning.
+ ZoneCheckerCallbacks nowarn_callbacks(
+ boost::bind(&ZoneCheckerTest::callback, this, _1, true), NULL);
+ EXPECT_TRUE(checkZone(zname_, zclass_, *rrsets_, nowarn_callbacks));
+ checkIssues();
+
// A tricky case: if the name matches a wildcard, it should technically
// be considered valid, but this checker doesn't check that far and still
// warns.
diff --git a/src/lib/dns/zone_checker.cc b/src/lib/dns/zone_checker.cc
index 3e1c47d..15ee296 100644
--- a/src/lib/dns/zone_checker.cc
+++ b/src/lib/dns/zone_checker.cc
@@ -21,6 +21,7 @@
#include <dns/rrset.h>
#include <dns/rrset_collection_base.h>
+#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
#include <string>
@@ -32,30 +33,6 @@ namespace isc {
namespace dns {
namespace {
-// This helper class is a trivial wrapper of ZoneCheckerCallbacks, and
-// remembers it if an error happens at least once.
-class CallbackWrapper {
-public:
- CallbackWrapper(const ZoneCheckerCallbacks& callbacks) :
- callbacks_(callbacks), has_error_(false)
- {}
-
- void error(const string& reason) {
- has_error_ = true;
- callbacks_.error(reason);
- }
-
- void warn(const string& reason) {
- callbacks_.warn(reason);
- }
-
- bool hasError() const { return (has_error_); }
-
-private:
- ZoneCheckerCallbacks callbacks_;
- bool has_error_;
-};
-
std::string
zoneText(const Name& zone_name, const RRClass& zone_class) {
return (zone_name.toText(true) + "/" + zone_class.toText());
@@ -63,11 +40,12 @@ zoneText(const Name& zone_name, const RRClass& zone_class) {
void
checkSOA(const Name& zone_name, const RRClass& zone_class,
- const RRsetCollectionBase& zone_rrsets, CallbackWrapper& callback) {
- const AbstractRRset* rrset =
- zone_rrsets.find(zone_name, RRType::SOA(), zone_class);
+ const RRsetCollectionBase& zone_rrsets,
+ ZoneCheckerCallbacks& callback) {
+ ConstRRsetPtr rrset =
+ zone_rrsets.find(zone_name, zone_class, RRType::SOA());
size_t count = 0;
- if (rrset != NULL) {
+ if (rrset) {
for (RdataIteratorPtr rit = rrset->getRdataIterator();
!rit->isLast();
rit->next(), ++count) {
@@ -88,10 +66,10 @@ checkSOA(const Name& zone_name, const RRClass& zone_class,
}
// Check if a target name is beyond zone cut, either due to delegation or
-// DNAME. Note that DNAME works on the origin but on the name itself, while
-// delegation works on the name itself (but the NS at the origin is not
+// DNAME. Note that DNAME works on the origin but not on the name itself,
+// while delegation works on the name itself (but the NS at the origin is not
// delegation).
-const AbstractRRset*
+ConstRRsetPtr
findZoneCut(const Name& zone_name, const RRClass& zone_class,
const RRsetCollectionBase& zone_rrsets, const Name& target_name) {
const unsigned int origin_count = zone_name.getLabelCount();
@@ -102,19 +80,19 @@ findZoneCut(const Name& zone_name, const RRClass& zone_class,
const Name& mid_name = (l == target_count) ? target_name :
target_name.split(target_count - l);
- const AbstractRRset* found = NULL;
+ ConstRRsetPtr found;
if (l != origin_count &&
- (found = zone_rrsets.find(mid_name, RRType::NS(), zone_class)) !=
+ (found = zone_rrsets.find(mid_name, zone_class, RRType::NS())) !=
NULL) {
return (found);
}
if (l != target_count &&
- (found = zone_rrsets.find(mid_name, RRType::DNAME(), zone_class))
+ (found = zone_rrsets.find(mid_name, zone_class, RRType::DNAME()))
!= NULL) {
return (found);
}
}
- return (NULL);
+ return (ConstRRsetPtr());
}
// Check if each "in-zone" NS name has an address record, identifying some
@@ -122,13 +100,13 @@ findZoneCut(const Name& zone_name, const RRClass& zone_class,
void
checkNSNames(const Name& zone_name, const RRClass& zone_class,
const RRsetCollectionBase& zone_rrsets,
- const AbstractRRset& ns_rrset, CallbackWrapper& callbacks) {
- if (ns_rrset.getRdataCount() == 0) {
+ ConstRRsetPtr ns_rrset, ZoneCheckerCallbacks& callbacks) {
+ if (ns_rrset->getRdataCount() == 0) {
// this should be an implementation bug, not an operational error.
isc_throw(Unexpected, "Zone checker found an empty NS RRset");
}
- for (RdataIteratorPtr rit = ns_rrset.getRdataIterator();
+ for (RdataIteratorPtr rit = ns_rrset->getRdataIterator();
!rit->isLast();
rit->next()) {
const rdata::generic::NS* ns_data =
@@ -145,9 +123,9 @@ checkNSNames(const Name& zone_name, const RRClass& zone_class,
}
// Check if there's a zone cut between the origin and the NS name.
- const AbstractRRset* cut_rrset = findZoneCut(zone_name, zone_class,
- zone_rrsets, ns_name);
- if (cut_rrset != NULL) {
+ ConstRRsetPtr cut_rrset = findZoneCut(zone_name, zone_class,
+ zone_rrsets, ns_name);
+ if (cut_rrset) {
if (cut_rrset->getType() == RRType::NS()) {
continue; // delegation; making the NS name "out of zone".
} else if (cut_rrset->getType() == RRType::DNAME()) {
@@ -161,14 +139,14 @@ checkNSNames(const Name& zone_name, const RRClass& zone_class,
assert(false);
}
}
- if (zone_rrsets.find(ns_name, RRType::CNAME(), zone_class) != NULL) {
+ if (zone_rrsets.find(ns_name, zone_class, RRType::CNAME()) != NULL) {
callbacks.error("zone " + zoneText(zone_name, zone_class) +
": NS '" + ns_name.toText(true) + "' is a CNAME " +
"(illegal per RFC2181)");
continue;
}
- if (zone_rrsets.find(ns_name, RRType::A(), zone_class) == NULL &&
- zone_rrsets.find(ns_name, RRType::AAAA(), zone_class) == NULL) {
+ if (zone_rrsets.find(ns_name, zone_class, RRType::A()) == NULL &&
+ zone_rrsets.find(ns_name, zone_class, RRType::AAAA()) == NULL) {
callbacks.warn("zone " + zoneText(zone_name, zone_class) +
": NS has no address records (A or AAAA)");
}
@@ -177,15 +155,30 @@ checkNSNames(const Name& zone_name, const RRClass& zone_class,
void
checkNS(const Name& zone_name, const RRClass& zone_class,
- const RRsetCollectionBase& zone_rrsets, CallbackWrapper& callbacks) {
- const AbstractRRset* rrset =
- zone_rrsets.find(zone_name, RRType::NS(), zone_class);
+ const RRsetCollectionBase& zone_rrsets,
+ ZoneCheckerCallbacks& callbacks) {
+ ConstRRsetPtr rrset =
+ zone_rrsets.find(zone_name, zone_class, RRType::NS());
if (rrset == NULL) {
callbacks.error("zone " + zoneText(zone_name, zone_class) +
": has no NS records");
return;
}
- checkNSNames(zone_name, zone_class, zone_rrsets, *rrset, callbacks);
+ checkNSNames(zone_name, zone_class, zone_rrsets, rrset, callbacks);
+}
+
+// The following two are simple wrapper of checker callbacks so checkZone()
+// can also remember any critical errors.
+void
+errorWrapper(const string& reason, ZoneCheckerCallbacks& callbacks,
+ bool* had_error) {
+ *had_error = true;
+ callbacks.error(reason);
+}
+
+void
+warnWrapper(const string& reason, ZoneCheckerCallbacks& callbacks) {
+ callbacks.warn(reason);
}
}
@@ -193,12 +186,15 @@ bool
checkZone(const Name& zone_name, const RRClass& zone_class,
const RRsetCollectionBase& zone_rrsets,
const ZoneCheckerCallbacks& callbacks) {
- CallbackWrapper my_callbacks(callbacks);
+ bool had_error = false;
+ ZoneCheckerCallbacks my_callbacks(
+ boost::bind(errorWrapper, _1, callbacks, &had_error),
+ boost::bind(warnWrapper, _1, callbacks));
checkSOA(zone_name, zone_class, zone_rrsets, my_callbacks);
checkNS(zone_name, zone_class, zone_rrsets, my_callbacks);
- return (!my_callbacks.hasError());
+ return (!had_error);
}
} // end namespace dns
diff --git a/src/lib/dns/zone_checker.h b/src/lib/dns/zone_checker.h
index 5b166a8..76deb1e 100644
--- a/src/lib/dns/zone_checker.h
+++ b/src/lib/dns/zone_checker.h
@@ -34,18 +34,14 @@ public:
/// Its parameter indicates the reason for the corresponding issue.
typedef boost::function<void(const std::string& reason)> IssueCallback;
- /// \brief Default constructor.
+ /// \brief Constructor.
///
- /// This is a convenient shortcut to specify callbacks that do nothing.
- /// If, for example, the caller of \c checkZone() is only interested in
- /// the final result, it can use this constructor.
- ///
- /// \throw none
- ZoneCheckerCallbacks() :
- error_callback_(nullCallback), warn_callback_(nullCallback)
- {}
-
- /// \brief Constructor with callbacks.
+ /// Either or both of the callbacks can be empty, in which case the
+ /// corresponding callback will be effectively no-operation. This can be
+ /// used, for example, when the caller of \c checkZone() is only
+ /// interested in the final result. Note that a \c NULL pointer will be
+ /// implicitly converted to an empty functor object, so passing \c NULL
+ /// suffices.
///
/// \throw none
///
@@ -63,7 +59,11 @@ public:
/// thrown from the callback.
///
/// \param reason Textual representation of the reason for the error.
- void error(const std::string& reason) { error_callback_(reason); }
+ void error(const std::string& reason) {
+ if (!error_callback_.empty()) {
+ error_callback_(reason);
+ }
+ }
/// \brief Call the callback for a non critical issue.
///
@@ -71,11 +71,12 @@ public:
/// thrown from the callback.
///
/// \param reason Textual representation of the reason for the issue.
- void warn(const std::string& reason) { warn_callback_(reason); }
+ void warn(const std::string& reason) {
+ if (!warn_callback_.empty())
+ warn_callback_(reason);
+ }
private:
- static void nullCallback(const std::string&) {}
-
IssueCallback error_callback_;
IssueCallback warn_callback_;
};
@@ -150,7 +151,7 @@ private:
bool
checkZone(const Name& zone_name, const RRClass& zone_class,
const RRsetCollectionBase& zone_rrsets,
- const ZoneCheckerCallbacks& callbacks = ZoneCheckerCallbacks());
+ const ZoneCheckerCallbacks& callbacks);
} // namespace dns
} // namespace isc
More information about the bind10-changes
mailing list