#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>
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);
}
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
// 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
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",