From: Michal 'vorner' Vaner Date: Fri, 4 Jan 2013 17:28:05 +0000 (+0100) Subject: [2436] Perform the validation in ZoneLoader X-Git-Tag: bind10-1.0.0-rc-release~99^2~16 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f4e6ab2a98e80e8832b201a6ed2db716bd1d4ee1;p=thirdparty%2Fkea.git [2436] Perform the validation in ZoneLoader TODO: Modify this commit and use the datasource RRsetCollection. This way it doesn't work. --- diff --git a/src/lib/datasrc/datasrc_messages.mes b/src/lib/datasrc/datasrc_messages.mes index 6983459339..cfe52a0a5b 100644 --- a/src/lib/datasrc/datasrc_messages.mes +++ b/src/lib/datasrc/datasrc_messages.mes @@ -844,3 +844,14 @@ data source. % DATASRC_UNEXPECTED_QUERY_STATE unexpected query state This indicates a programming error. An internal task of unknown type was generated. + +% DATASRC_VALIDATE_ERROR validation of zone %1/%2 failed: %3 +The zone was loaded into the data source successfully, but the content fails +basic sanity checks. See the message if you want to know what exactly is wrong +with the data. The data can not be used and previous version, if any, will be +preserved. + +% DATASRC_VALIDATE_WARNING %1/%2: %3 +The zone was loaded, but there's some problem with the content. The problem +is not serious enough to make the zone unusable, but it should still be checked +and fixed. See the message to know what exactly is wrong with the data. diff --git a/src/lib/datasrc/tests/zone_loader_unittest.cc b/src/lib/datasrc/tests/zone_loader_unittest.cc index 9f4cf2b937..fc17361f2d 100644 --- a/src/lib/datasrc/tests/zone_loader_unittest.cc +++ b/src/lib/datasrc/tests/zone_loader_unittest.cc @@ -82,9 +82,9 @@ public: // and this way, it is much simpler. class Updater : public ZoneUpdater { public: - Updater(MockClient* client) : + Updater(MockClient* client, const Name& name) : client_(client), - finder_(client_->rrclass_) + finder_(client_->rrclass_, name) {} virtual ZoneFinder& getFinder() { return (finder_); @@ -105,14 +105,15 @@ private: MockClient* client_; class Finder : public ZoneFinder { public: - Finder(const RRClass& rrclass) : - class_(rrclass) + Finder(const RRClass& rrclass, const Name& name) : + class_(rrclass), + name_(name) {} virtual RRClass getClass() const { return (class_); } virtual Name getOrigin() const { - isc_throw(isc::NotImplemented, "Method not used in tests"); + return (name_); } virtual shared_ptr find(const Name&, const RRType&, const FindOptions) @@ -130,6 +131,7 @@ private: } private: const RRClass class_; + const Name name_; } finder_; }; @@ -144,7 +146,7 @@ MockClient::getUpdater(const Name& name, bool replace, bool journaling) const { // const_cast is bad. But the const on getUpdater seems wrong in the first // place, since updater will be modifying the data there. And the updater // wants to store data into the client so we can examine it later. - return (ZoneUpdaterPtr(new Updater(const_cast(this)))); + return (ZoneUpdaterPtr(new Updater(const_cast(this), name))); } class ZoneLoaderTest : public ::testing::Test { diff --git a/src/lib/datasrc/zone_loader.cc b/src/lib/datasrc/zone_loader.cc index 01f216e1d4..d9204d1f03 100644 --- a/src/lib/datasrc/zone_loader.cc +++ b/src/lib/datasrc/zone_loader.cc @@ -19,8 +19,13 @@ #include #include #include +#include +#include #include +#include + +#include using isc::dns::Name; using isc::dns::ConstRRsetPtr; @@ -99,6 +104,22 @@ copyRRsets(const ZoneUpdaterPtr& destination, const ZoneIteratorPtr& source, return (false); // Not yet, there may be more } +void +logWarning(const dns::Name* zone_name, const dns::RRClass* rrclass, + const std::string& reason) +{ + LOG_WARN(logger, DATASRC_VALIDATE_WARNING).arg(*zone_name).arg(*rrclass). + arg(reason); +} + +void +logError(const dns::Name* zone_name, const dns::RRClass* rrclass, + const std::string& reason) +{ + LOG_ERROR(logger, DATASRC_VALIDATE_ERROR).arg(*zone_name).arg(*rrclass). + arg(reason); +} + } // end unnamed namespace bool @@ -123,6 +144,19 @@ ZoneLoader::loadIncremental(size_t limit) { } if (complete_) { + // Everything is loaded. Perform some basic sanity checks on the zone. + RRsetCollection collection(updater_); + dns::Name zone_name(updater_->getFinder().getOrigin()); + dns::RRClass zone_class(updater_->getFinder().getClass()); + dns::ZoneCheckerCallbacks + callbacks(boost::bind(&logError, &zone_name, &zone_class, _1), + boost::bind(&logWarning, &zone_name, &zone_class, _1)); + if (!dns::checkZone(zone_name, zone_class, collection, callbacks)) { + // Validation failed. + loaded_ok_ = false; + isc_throw(ZoneContentError, "Errors found when validating zone " << + zone_name << "/" << zone_class); + } updater_->commit(); } return (complete_);