Commit f7470975 authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[2429] use SOA's minimum TTL as a last resort default TTL

parent 1f1d6219
......@@ -15,6 +15,7 @@
#include <dns/master_loader.h>
#include <dns/master_lexer.h>
#include <dns/name.h>
#include <dns/rdataclass.h>
#include <dns/rrttl.h>
#include <dns/rrclass.h>
#include <dns/rrtype.h>
......@@ -139,12 +140,16 @@ public:
pushSource(filename);
}
void setDefaultTTL(const string& ttl_txt) {
void setDefaultTTL(const RRTTL& ttl) {
if (!default_ttl_) {
default_ttl_.reset(new RRTTL(ttl_txt));
default_ttl_.reset(new RRTTL(ttl));
} else {
*default_ttl_ = RRTTL(ttl_txt);
*default_ttl_ = ttl;
}
}
void setDefaultTTL(const string& ttl_txt) {
setDefaultTTL(RRTTL(ttl_txt));
eatUntilEOL(true);
}
......@@ -302,15 +307,6 @@ MasterLoader::MasterLoaderImpl::loadIncremental(size_t count_limit) {
const RRClass rrclass(rrparam_token.getString());
const RRType rrtype(getString());
// If the TTL is not yet determined, complete it.
if (!current_ttl_) {
if (default_ttl_) {
setCurrentTTL(*default_ttl_);
} // TBD: else: try SOA min TTL for default, then error
} else if (!explicit_ttl && default_ttl_) {
setCurrentTTL(*default_ttl_);
}
// TODO: Some more validation?
if (rrclass != zone_class_) {
// It doesn't really matter much what type of exception
......@@ -330,6 +326,25 @@ MasterLoader::MasterLoaderImpl::loadIncremental(size_t count_limit) {
// callbacks_ already. We need to decide if we want to continue
// or not.
if (data) {
// If the TTL is not yet determined, complete it.
if (!current_ttl_ && !default_ttl_) {
if (rrtype == RRType::SOA()) {
callbacks_.warning(lexer_.getSourceName(),
lexer_.getSourceLine(),
"no TTL specified; "
"using SOA MINTTL instead");
const uint32_t ttl_val =
dynamic_cast<const rdata::generic::SOA&>(*data).
getMinimum();
setDefaultTTL(RRTTL(ttl_val));
setCurrentTTL(*default_ttl_);
}
} else if (!explicit_ttl && default_ttl_) {
setCurrentTTL(*default_ttl_);
} else if (!explicit_ttl) {
; // warn it
} // else, explicit_ttl, that's used
add_callback_(name, rrclass, rrtype, *current_ttl_, data);
// Good, we loaded another one
......
......@@ -407,6 +407,25 @@ TEST_F(MasterLoaderTest, ttlDirective) {
checkRR("a2.example.org", RRType::A(), "192.0.2.3", RRTTL(3600));
}
TEST_F(MasterLoaderTest, ttlFromSOA) {
// No $TTL, and the SOA doesn't have an explicit TTL field. Its minimum
// TTL field will be used as the RR's TTL, and it'll be used as the
// default TTL for others.
stringstream zone_stream("example.org. IN SOA . . 0 0 0 0 1800\n"
"a.example.org. IN A 192.0.2.1\n");
setLoader(zone_stream, Name("example.org."), RRClass::IN(),
MasterLoader::DEFAULT);
loader_->load();
EXPECT_TRUE(loader_->loadedSucessfully());
checkRR("example.org", RRType::SOA(), ". . 0 0 0 0 1800", RRTTL(1800));
checkRR("a.example.org", RRType::A(), "192.0.2.1", RRTTL(1800));
// The use of SOA minimum TTL should have caused a warning.
EXPECT_EQ(1, warnings_.size());
EXPECT_EQ(0, warnings_.at(0).find(
"no TTL specified; using SOA MINTTL instead"));
}
// Test the constructor rejects empty add callback.
TEST_F(MasterLoaderTest, emptyCallback) {
EXPECT_THROW(MasterLoader(TEST_DATA_SRCDIR "/example.org",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment