BIND 10 master, updated. 86f34c57590a06696b1651a155569d9bef9c8164 [master] update Changelog for merge of #2178
BIND 10 source code commits
bind10-changes at lists.isc.org
Mon Aug 27 07:57:08 UTC 2012
The branch, master has been updated
via 86f34c57590a06696b1651a155569d9bef9c8164 (commit)
via a75ed413e8a1c8e3702beea4811a46a1bf519bbd (commit)
via 092430baa3e8b2ed9ed297718c3a8e50cf928b3d (commit)
via bca8812cd6c77607b21536f7ef1a9496c7e210cc (commit)
via 4c3cdc7b492272d6606034a0796dc0a150f04aae (commit)
via 3e0eaa46295536f7ed4175fd6d9caeb5f5192a5c (commit)
via 33c57e4cefbd3948e5527d34f0a56a4f4a50a308 (commit)
via d99645b48e66cee78ea12b8e1d62efd8f07e14bc (commit)
from 59273bb9b43d0a2c757e68ce36f834f5c2b5fd49 (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 86f34c57590a06696b1651a155569d9bef9c8164
Author: Jelte Jansen <jelte at isc.org>
Date: Mon Aug 27 09:37:32 2012 +0200
[master] update Changelog for merge of #2178
commit a75ed413e8a1c8e3702beea4811a46a1bf519bbd
Merge: 59273bb 092430b
Author: Jelte Jansen <jelte at isc.org>
Date: Mon Aug 27 09:34:56 2012 +0200
[master] Merge branch 'trac2178'
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 30 ++++++----
src/lib/datasrc/client_list.cc | 23 +++++---
src/lib/datasrc/datasrc_messages.mes | 5 ++
src/lib/datasrc/tests/client_list_unittest.cc | 62 ++++++++++++++------
.../tests/testdata/example.com.flattened} | 0
src/lib/dns/masterload.cc | 40 ++++++++-----
src/lib/dns/masterload.h | 8 ++-
7 files changed, 116 insertions(+), 52 deletions(-)
copy src/lib/{testutils/testdata/example.com.zone => datasrc/tests/testdata/example.com.flattened} (100%)
-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index d8bdce4..0f899fc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,13 +1,23 @@
-468. [func]* naokikambe, fujiwara
- b10-stats polls bind10 and b10-auth for statistics data. The
- "poll-interval" parameter in b10-stats is for configuring the polling
- interval. All statistics data collected once are preserved while
- b10-stats is running. The "sendstats" command was removed from bind10
- and b10-auth. The "statistics-interval" configuration item was removed
- from b10-auth.
- (Trac #2136, git dcb5ce50b4b4e50d28247d5f8b5cb8d90bda942a)
- (Trac #2137, git d53bb65a43f6027b15a6edc08c137951e3ce5e0e)
- (Trac #2138, git TBD)
+469. [bug] jelte
+ libdatasrc: the data source client list class now ignores zone
+ content problems (such as out-of-zone data) in MasterFiles type
+ zones, instead of aborting the entire configuration. It only logs
+ an error, and all other zones and datasources are still loaded. The
+ error log message has been improved to include the zone origin and
+ source file name. As a result of this change, b10-auth no longer
+ exits upon encountering such errors during startup.
+ (Trac #2178, git a75ed413e8a1c8e3702beea4811a46a1bf519bbd)
+
+468. [func]* naokikambe, fujiwara
+ b10-stats polls bind10 and b10-auth for statistics data. The
+ "poll-interval" parameter in b10-stats is for configuring the
+ polling interval. All statistics data collected once are preserved
+ while b10-stats is running. The "sendstats" command was removed
+ from bind10 and b10-auth. The "statistics-interval" configuration
+ item was removed from b10-auth.
+ (Trac #2136, git dcb5ce50b4b4e50d28247d5f8b5cb8d90bda942a)
+ (Trac #2137, git d53bb65a43f6027b15a6edc08c137951e3ce5e0e)
+ (Trac #2138, git TBD)
bind10-devel-20120816 released on August 16, 2012
diff --git a/src/lib/datasrc/client_list.cc b/src/lib/datasrc/client_list.cc
index a50a752..3c0ea19 100644
--- a/src/lib/datasrc/client_list.cc
+++ b/src/lib/datasrc/client_list.cc
@@ -17,6 +17,7 @@
#include "factory.h"
#include "memory_datasrc.h"
#include "logger.h"
+#include <dns/masterload.h>
#include <memory>
#include <boost/foreach.hpp>
@@ -144,23 +145,29 @@ ConfigurableClientList::configure(const ConstElementPtr& config,
finder(new
InMemoryZoneFinder(rrclass_, origin));
if (type == "MasterFiles") {
- finder->load(paramConf->get(*it)->stringValue());
+ try {
+ finder->load(paramConf->get(*it)->stringValue());
+ cache->addZone(finder);
+ } catch (const isc::dns::MasterLoadError& mle) {
+ LOG_ERROR(logger, DATASRC_MASTERLOAD_ERROR)
+ .arg(mle.what());
+ }
} else {
ZoneIteratorPtr iterator;
try {
iterator = client->getIterator(origin);
- }
- catch (const DataSourceError&) {
- isc_throw(ConfigurationError, "Unable to cache "
- "non-existent zone " << origin);
+ } catch (const DataSourceError&) {
+ isc_throw(ConfigurationError, "Unable to "
+ "cache non-existent zone "
+ << origin);
}
if (!iterator) {
- isc_throw(isc::Unexpected, "Got NULL iterator for "
- "zone " << origin);
+ isc_throw(isc::Unexpected, "Got NULL iterator "
+ "for zone " << origin);
}
finder->load(*iterator);
+ cache->addZone(finder);
}
- cache->addZone(finder);
}
}
}
diff --git a/src/lib/datasrc/datasrc_messages.mes b/src/lib/datasrc/datasrc_messages.mes
index 6ae744e..6837476 100644
--- a/src/lib/datasrc/datasrc_messages.mes
+++ b/src/lib/datasrc/datasrc_messages.mes
@@ -305,6 +305,11 @@ Therefore, the zone will not be available for this process. If this is
a problem, you should move the zone to some database backend (sqlite3, for
example) and use it from there.
+% DATASRC_MASTERLOAD_ERROR %1
+An error was found in the zone data for a MasterFiles zone. The zone
+is not loaded. The specific error is shown in the message, and should
+be addressed.
+
% DATASRC_MEM_ADD_RRSET adding RRset '%1/%2' into zone '%3'
Debug information. An RRset is being added to the in-memory data source.
diff --git a/src/lib/datasrc/tests/client_list_unittest.cc b/src/lib/datasrc/tests/client_list_unittest.cc
index 64eb347..3ca906b 100644
--- a/src/lib/datasrc/tests/client_list_unittest.cc
+++ b/src/lib/datasrc/tests/client_list_unittest.cc
@@ -332,7 +332,7 @@ public:
shared_ptr<InMemoryClient>());
}
shared_ptr<TestedList> list_;
- const ClientList::FindResult negativeResult_;
+ const ClientList::FindResult negative_result_;
vector<shared_ptr<MockDataSourceClient> > ds_;
vector<ConfigurableClientList::DataSourceInfo> ds_info_;
const ConstElementPtr config_elem_, config_elem_zones_;
@@ -349,7 +349,7 @@ TEST_F(ListTest, selfTest) {
EXPECT_EQ(result::NOTFOUND, ds_[0]->findZone(Name("zzz")).code);
// Nothing to keep alive here.
EXPECT_EQ(shared_ptr<ClientList::FindResult::LifeKeeper>(),
- negativeResult_.life_keeper_);
+ negative_result_.life_keeper_);
}
// Test the list we create with empty configuration is, in fact, empty
@@ -365,14 +365,14 @@ TEST_F(ListTest, emptySearch) {
// Note: we don't have operator<< for the result class, so we cannot use
// EXPECT_EQ. Same for other similar cases.
- EXPECT_TRUE(negativeResult_ == list_->find(Name("example.org"), false,
- false));
- EXPECT_TRUE(negativeResult_ == list_->find(Name("example.org"), false,
- true));
- EXPECT_TRUE(negativeResult_ == list_->find(Name("example.org"), true,
- false));
- EXPECT_TRUE(negativeResult_ == list_->find(Name("example.org"), true,
- true));
+ EXPECT_TRUE(negative_result_ == list_->find(Name("example.org"), false,
+ false));
+ EXPECT_TRUE(negative_result_ == list_->find(Name("example.org"), false,
+ true));
+ EXPECT_TRUE(negative_result_ == list_->find(Name("example.org"), true,
+ false));
+ EXPECT_TRUE(negative_result_ == list_->find(Name("example.org"), true,
+ true));
}
// Put a single data source inside the list and check it can find an
@@ -380,21 +380,21 @@ TEST_F(ListTest, emptySearch) {
TEST_F(ListTest, singleDSExactMatch) {
list_->getDataSources().push_back(ds_info_[0]);
// This zone is not there
- EXPECT_TRUE(negativeResult_ == list_->find(Name("org."), true));
+ EXPECT_TRUE(negative_result_ == list_->find(Name("org."), true));
// But this one is, so check it.
positiveResult(list_->find(Name("example.org"), true), ds_[0],
Name("example.org"), true, "Exact match");
// When asking for a sub zone of a zone there, we get nothing
// (we want exact match, this would be partial one)
- EXPECT_TRUE(negativeResult_ == list_->find(Name("sub.example.org."),
- true));
+ EXPECT_TRUE(negative_result_ == list_->find(Name("sub.example.org."),
+ true));
}
// When asking for a partial match, we get all that the exact one, but more.
TEST_F(ListTest, singleDSBestMatch) {
list_->getDataSources().push_back(ds_info_[0]);
// This zone is not there
- EXPECT_TRUE(negativeResult_ == list_->find(Name("org.")));
+ EXPECT_TRUE(negative_result_ == list_->find(Name("org.")));
// But this one is, so check it.
positiveResult(list_->find(Name("example.org")), ds_[0],
Name("example.org"), true, "Exact match");
@@ -417,7 +417,7 @@ TEST_F(ListTest, multiExactMatch) {
SCOPED_TRACE(test_names[i]);
multiConfiguration(i);
// Something that is nowhere there
- EXPECT_TRUE(negativeResult_ == list_->find(Name("org."), true));
+ EXPECT_TRUE(negative_result_ == list_->find(Name("org."), true));
// This one is there exactly.
positiveResult(list_->find(Name("example.org"), true), ds_[0],
Name("example.org"), true, "Exact match");
@@ -425,7 +425,7 @@ TEST_F(ListTest, multiExactMatch) {
positiveResult(list_->find(Name("sub.example.org."), true), ds_[1],
Name("sub.example.org"), true, "Subdomain match");
// But this one is in neither data source.
- EXPECT_TRUE(negativeResult_ ==
+ EXPECT_TRUE(negative_result_ ==
list_->find(Name("sub.example.com."), true));
}
}
@@ -436,7 +436,7 @@ TEST_F(ListTest, multiBestMatch) {
SCOPED_TRACE(test_names[i]);
multiConfiguration(i);
// Something that is nowhere there
- EXPECT_TRUE(negativeResult_ == list_->find(Name("org.")));
+ EXPECT_TRUE(negative_result_ == list_->find(Name("org.")));
// This one is there exactly.
positiveResult(list_->find(Name("example.org")), ds_[0],
Name("example.org"), true, "Exact match");
@@ -712,7 +712,7 @@ TEST_F(ListTest, cacheZones) {
positiveResult(list_->find(Name("sub.example.com.")), ds_[0],
Name("example.com."), false, "Subdomain of com", true);
// For now, the ones not cached are ignored.
- EXPECT_TRUE(negativeResult_ == list_->find(Name("example.cz.")));
+ EXPECT_TRUE(negative_result_ == list_->find(Name("example.cz.")));
}
// Check the caching handles misbehaviour from the data source and
@@ -786,6 +786,32 @@ TEST_F(ListTest, masterFiles) {
EXPECT_EQ(0, list_->getDataSources().size());
}
+TEST_F(ListTest, BadMasterFile) {
+ // Configure two zone correctly, and one with the wrong origin
+ // (resulting in an out-of-zone data error)
+ // Configuration should succeed, and the correct zones should
+ // be loaded. Neither the 'bad' origin or the zone it used
+ // should be loaded
+ const ConstElementPtr elem(Element::fromJSON("["
+ "{"
+ " \"type\": \"MasterFiles\","
+ " \"cache-enable\": true,"
+ " \"params\": {"
+ " \"example.com.\": \"" TEST_DATA_DIR "/example.com.flattened\","
+ " \"foo.bar.\": \"" TEST_DATA_DIR "/example.org.nsec3-signed\","
+ " \".\": \"" TEST_DATA_DIR "/root.zone\""
+ " }"
+ "}]"));
+ list_->configure(elem, true);
+
+ positiveResult(list_->find(Name("example.com."), true), ds_[0],
+ Name("example.com."), true, "example.com", true);
+ EXPECT_TRUE(negative_result_ == list_->find(Name("example.org."), true));
+ EXPECT_TRUE(negative_result_ == list_->find(Name("foo.bar"), true));
+ positiveResult(list_->find(Name(".")), ds_[0], Name("."), true, "root",
+ true);
+}
+
// Test we can reload a zone
TEST_F(ListTest, reloadSuccess) {
list_->configure(config_elem_zones_, true);
diff --git a/src/lib/datasrc/tests/testdata/example.com.flattened b/src/lib/datasrc/tests/testdata/example.com.flattened
new file mode 100644
index 0000000..92d1f45
--- /dev/null
+++ b/src/lib/datasrc/tests/testdata/example.com.flattened
@@ -0,0 +1,3 @@
+example.com. 3600 IN SOA ns.example.com. admin.example.com. 1234 3600 1800 2419200 7200
+example.com. 3600 IN NS ns.example.com.
+ns.example.com. 3600 IN A 192.0.2.1
diff --git a/src/lib/dns/masterload.cc b/src/lib/dns/masterload.cc
index 3deae19..53a2b8d 100644
--- a/src/lib/dns/masterload.cc
+++ b/src/lib/dns/masterload.cc
@@ -75,23 +75,28 @@ masterLoad(const char* const filename, const Name& origin,
isc_throw(MasterLoadError, "Failed to open master file: " <<
filename << ": " << strerror(errno));
}
- masterLoad(ifs, origin, zone_class, callback);
+ masterLoad(ifs, origin, zone_class, callback, filename);
ifs.close();
}
void
masterLoad(istream& input, const Name& origin, const RRClass& zone_class,
- MasterLoadCallback callback)
+ MasterLoadCallback callback, const char* source)
{
RRsetPtr rrset;
ConstRdataPtr prev_rdata; // placeholder for special case of RRSIGs
string line;
unsigned int line_count = 1;
+ if (source == NULL) {
+ source = "<unknown>";
+ }
+
do {
getline(input, line);
if (input.bad() || (input.fail() && !input.eof())) {
- isc_throw(MasterLoadError, "Unexpectedly failed to read a line");
+ isc_throw(MasterLoadError, "Unexpectedly failed to read a line in "
+ << source);
}
// blank/comment lines should be simply skipped.
@@ -102,7 +107,8 @@ masterLoad(istream& input, const Name& origin, const RRClass& zone_class,
// The line shouldn't have leading space (which means omitting the
// owner name).
if (isspace(line[0])) {
- isc_throw(MasterLoadError, "Leading space at line " << line_count);
+ isc_throw(MasterLoadError, "Leading space in " << source
+ << " at line " << line_count);
}
// Parse a single RR
@@ -111,15 +117,15 @@ masterLoad(istream& input, const Name& origin, const RRClass& zone_class,
stringbuf rdatabuf;
iss >> owner_txt >> ttl_txt >> rrclass_txt >> rrtype_txt >> &rdatabuf;
if (iss.bad() || iss.fail()) {
- isc_throw(MasterLoadError, "Parse failure for a valid RR at line "
- << line_count);
+ isc_throw(MasterLoadError, "Parse failure for a valid RR in "
+ << source << " at line " << line_count);
}
// This simple version doesn't support relative owner names with a
// separate origin.
if (owner_txt.empty() || *(owner_txt.end() - 1) != '.') {
- isc_throw(MasterLoadError, "Owner name is not absolute at line "
- << line_count);
+ isc_throw(MasterLoadError, "Owner name is not absolute in "
+ << source << " at line " << line_count);
}
// XXX: this part is a bit tricky (and less efficient). We are going
@@ -151,8 +157,9 @@ masterLoad(istream& input, const Name& origin, const RRClass& zone_class,
rdata = createRdata(*rrtype, *rrclass, stripLine(rdtext, ex));
}
} catch (const Exception& ex) {
- isc_throw(MasterLoadError, "Invalid RR text at line " << line_count
- << ": " << ex.what());
+ isc_throw(MasterLoadError, "Invalid RR text in " << source <<
+ " at line " << line_count << ": "
+ << ex.what());
}
// Origin related validation:
@@ -161,20 +168,22 @@ masterLoad(istream& input, const Name& origin, const RRClass& zone_class,
const NameComparisonResult cmp_result = owner->compare(origin);
if (cmp_result.getRelation() != NameComparisonResult::EQUAL &&
cmp_result.getRelation() != NameComparisonResult::SUBDOMAIN) {
- isc_throw(MasterLoadError, "Out-of-zone data at line "
- << line_count);
+ isc_throw(MasterLoadError, "Out-of-zone data for " << origin
+ << "/" << rrclass_txt << " in "
+ << source << " at line "
+ << line_count);
}
if (*rrtype == RRType::SOA() &&
cmp_result.getRelation() != NameComparisonResult::EQUAL) {
- isc_throw(MasterLoadError, "SOA not at top of zone at line "
- << line_count);
+ isc_throw(MasterLoadError, "SOA not at top of zone in "
+ << source << " at line " << line_count);
}
// Reject RR class mismatching
if (*rrclass != zone_class) {
isc_throw(MasterLoadError, "RR class (" << rrclass_txt
<< ") does not match the zone class (" << zone_class
- << ") at line " << line_count);
+ << ") in " << source << " at line " << line_count);
}
// Everything is okay. Now create/update RRset with the new RR.
@@ -209,5 +218,6 @@ masterLoad(istream& input, const Name& origin, const RRClass& zone_class,
callback(rrset);
}
}
+
} // namespace dns
} // namespace isc
diff --git a/src/lib/dns/masterload.h b/src/lib/dns/masterload.h
index 41d145b..e252285 100644
--- a/src/lib/dns/masterload.h
+++ b/src/lib/dns/masterload.h
@@ -232,9 +232,15 @@ void masterLoad(const char* const filename, const Name& origin,
/// \param zone_class The RR class of the zone.
/// \param callback A callback functor or function that is to be called for
/// each RRset.
+/// \param source A string to use in error messages if zone content is bad
+/// (e.g. the file name when reading from a file). If this value is NULL,
+/// or left out, the error will use the string '<unknown>'
void masterLoad(std::istream& input, const Name& origin,
- const RRClass& zone_class, MasterLoadCallback callback);
+ const RRClass& zone_class, MasterLoadCallback callback,
+ const char* source = NULL);
}
+
+
//@}
}
More information about the bind10-changes
mailing list