Commit 9fecf9fc authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[2429] added basic support for $TTL

parent 606ba69e
......@@ -20,6 +20,8 @@
#include <dns/rrtype.h>
#include <dns/rdata.h>
#include <boost/scoped_ptr.hpp>
#include <string>
#include <memory>
#include <boost/algorithm/string/predicate.hpp> // for iequals
......@@ -137,6 +139,30 @@ public:
pushSource(filename);
}
void setDefaultTTL(const string& ttl_txt) {
if (!default_ttl_) {
default_ttl_.reset(new RRTTL(ttl_txt));
}
//setCurrentTTL(*default_ttl_);
}
void setCurrentTTL(const RRTTL& ttl) {
if (!current_ttl_) {
current_ttl_.reset(new RRTTL(ttl));
} else {
*current_ttl_ = ttl;
}
}
bool setCurrentTTL(const string& ttl_txt) {
try {
setCurrentTTL(RRTTL(ttl_txt));
return (true);
} catch (const InvalidRRTTL&) {
return (false);
}
}
void handleDirective(const char* directive, size_t length) {
if (iequals(directive, "INCLUDE")) {
doInclude();
......@@ -145,9 +171,7 @@ public:
isc_throw(isc::NotImplemented,
"Origin directive not implemented yet");
} else if (iequals(directive, "TTL")) {
// TODO: Implement
isc_throw(isc::NotImplemented,
"TTL directive not implemented yet");
setDefaultTTL(getString());
} else {
isc_throw(InternalException, "Unknown directive '" <<
string(directive, directive + length) << "'");
......@@ -189,6 +213,8 @@ private:
const RRClass zone_class_;
MasterLoaderCallbacks callbacks_;
AddRRCallback add_callback_;
boost::scoped_ptr<RRTTL> default_ttl_;
boost::scoped_ptr<RRTTL> current_ttl_;
const MasterLoader::Options options_;
const std::string master_file_;
std::string string_token_;
......@@ -260,10 +286,24 @@ MasterLoader::MasterLoaderImpl::loadIncremental(size_t count_limit) {
// anything yet
// The parameters
const RRTTL ttl(getString());
const RRClass rrclass(getString());
MasterToken rrparam_token = lexer_.getNextToken();
if (rrparam_token.getType() == MasterToken::STRING) {
// Try TTL
if (setCurrentTTL(rrparam_token.getString())) {
rrparam_token = lexer_.getNextToken();
}
}
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
}
// TODO: Some more validation?
if (rrclass != zone_class_) {
// It doesn't really matter much what type of exception
......@@ -283,7 +323,7 @@ MasterLoader::MasterLoaderImpl::loadIncremental(size_t count_limit) {
// callbacks_ already. We need to decide if we want to continue
// or not.
if (data) {
add_callback_(name, rrclass, rrtype, ttl, data);
add_callback_(name, rrclass, rrtype, *current_ttl_, data);
// Good, we loaded another one
++count;
......
......@@ -17,6 +17,7 @@
#include <dns/rrtype.h>
#include <dns/rrset.h>
#include <dns/rrclass.h>
#include <dns/rrttl.h>
#include <dns/name.h>
#include <dns/rdata.h>
......@@ -102,7 +103,8 @@ public:
// Check the next RR in the ones produced by the loader
// Other than passed arguments are checked to be the default for the tests
void checkRR(const string& name, const RRType& type, const string& data) {
void checkRR(const string& name, const RRType& type, const string& data,
const RRTTL& rrttl = RRTTL(3600)) {
ASSERT_FALSE(rrsets_.empty());
RRsetPtr current = rrsets_.front();
rrsets_.pop_front();
......@@ -110,6 +112,7 @@ public:
EXPECT_EQ(Name(name), current->getName());
EXPECT_EQ(type, current->getType());
EXPECT_EQ(RRClass::IN(), current->getClass());
EXPECT_EQ(rrttl, current->getTTL());
ASSERT_EQ(1, current->getRdataCount());
EXPECT_EQ(0, isc::dns::rdata::createRdata(type, RRClass::IN(), data)->
compare(current->getRdataIterator()->getCurrent()));
......@@ -377,6 +380,19 @@ TEST_F(MasterLoaderTest, includeWithGarbage) {
checkRR("www.example.org", RRType::AAAA(), "2001:db8::1");
}
// Test for "$TTL"
TEST_F(MasterLoaderTest, ttlDirective) {
// Set the default TTL with $TTL followed by an RR omitting the TTL
const string input("$TTL 1800\n"
"example.org. IN A 192.0.2.1\n");
stringstream zone_stream(input);
setLoader(zone_stream, Name("example.org."), RRClass::IN(),
MasterLoader::DEFAULT);
loader_->load();
EXPECT_TRUE(loader_->loadedSucessfully());
checkRR("example.org", RRType::A(), "192.0.2.1", RRTTL(1800));
}
// 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