From: Mukund Sivaraman Date: Fri, 14 Dec 2012 02:18:52 +0000 (+0530) Subject: [2431] Support flexible order of TTL, type and class X-Git-Tag: bind10-1.0.0-beta-release~13^2~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=48a559472ac908be3bf697b11c01fb1a0fe13273;p=thirdparty%2Fkea.git [2431] Support flexible order of TTL, type and class --- diff --git a/src/lib/dns/master_loader.cc b/src/lib/dns/master_loader.cc index 949d09dab4..ecbf66deab 100644 --- a/src/lib/dns/master_loader.cc +++ b/src/lib/dns/master_loader.cc @@ -382,12 +382,26 @@ MasterLoader::MasterLoaderImpl::loadIncremental(size_t count_limit) { const Name name(name_string.beg, name_string.len, &zone_origin_); - // TODO: Some more flexibility. We don't allow omitting - // anything yet + + // Find TTL, class and type. Both TTL and class are + // optional and may occur in any order if they exist. TTL + // and class come before type which must exist. + // + // [] [] + // [] [] // The parameters MasterToken rrparam_token = lexer_.getNextToken(); + boost::scoped_ptr rrclass; + try { + rrclass.reset(new RRClass(rrparam_token.getString())); + rrparam_token = lexer_.getNextToken(); + } catch (InvalidRRClass& e) { + // If it's not an rrclass here, continue and try again + // after the TTL below. + } + bool explicit_ttl = false; if (rrparam_token.getType() == MasterToken::STRING) { // Try TTL @@ -397,19 +411,31 @@ MasterLoader::MasterLoaderImpl::loadIncremental(size_t count_limit) { } } - const RRClass rrclass(rrparam_token.getString()); + if (!rrclass) { + try { + rrclass.reset(new RRClass(rrparam_token.getString())); + rrparam_token = lexer_.getNextToken(); + } catch (InvalidRRClass& e) { + // If it's not an rrclass here, use the zone's class. + rrclass.reset(new RRClass(zone_class_)); + } + } + + // Return the last token + lexer_.ungetToken(); + const RRType rrtype(getString()); // TODO: Some more validation? - if (rrclass != zone_class_) { + if (*rrclass != zone_class_) { // It doesn't really matter much what type of exception // we throw, we catch it just below. - isc_throw(isc::BadValue, "Class mismatch: " << rrclass << + isc_throw(isc::BadValue, "Class mismatch: " << *rrclass << "vs. " << zone_class_); } // TODO: Check if it is SOA, it should be at the origin. - const rdata::RdataPtr rdata(rdata::createRdata(rrtype, rrclass, + const rdata::RdataPtr rdata(rdata::createRdata(rrtype, *rrclass, lexer_, &zone_origin_, options_, @@ -419,7 +445,7 @@ MasterLoader::MasterLoaderImpl::loadIncremental(size_t count_limit) { // callbacks_ already. We need to decide if we want to continue // or not. if (rdata) { - add_callback_(name, rrclass, rrtype, + add_callback_(name, *rrclass, rrtype, getCurrentTTL(explicit_ttl, rrtype, rdata), rdata); diff --git a/src/lib/dns/tests/master_loader_unittest.cc b/src/lib/dns/tests/master_loader_unittest.cc index 912a0b4534..8c9269de99 100644 --- a/src/lib/dns/tests/master_loader_unittest.cc +++ b/src/lib/dns/tests/master_loader_unittest.cc @@ -471,6 +471,40 @@ TEST_F(MasterLoaderTest, ttlFromPrevious) { checkCallbackMessage(warnings_.at(0), "using RFC1035 TTL semantics", 2); } +TEST_F(MasterLoaderTest, ttlClassTypeOrder) { + // We test the order and lack of TTL, class and type. Both TTL and + // class are optional and may occur in any order if they exist. TTL + // and class come before type which must exist. + // + // [] [] + // [] [] + + stringstream zone_stream; + // + zone_stream << "a.example.org. 1800 IN A 192.0.2.1\n"; + // + zone_stream << "b.example.org. A 192.0.2.2\n"; + // + zone_stream << "c.example.org. IN 3600 A 192.0.2.3\n"; + // + zone_stream << "d.example.org. 7200 A 192.0.2.4\n"; + // + zone_stream << "e.example.org. IN A 192.0.2.5\n"; + + setLoader(zone_stream, Name("example.org."), RRClass::IN(), + MasterLoader::DEFAULT); + loader_->load(); + EXPECT_TRUE(loader_->loadedSucessfully()); + checkRR("a.example.org", RRType::A(), "192.0.2.1", RRTTL(1800)); + checkRR("b.example.org", RRType::A(), "192.0.2.2", RRTTL(1800)); + checkRR("c.example.org", RRType::A(), "192.0.2.3", RRTTL(3600)); + checkRR("d.example.org", RRType::A(), "192.0.2.4", RRTTL(7200)); + checkRR("e.example.org", RRType::A(), "192.0.2.5", RRTTL(7200)); + + EXPECT_EQ(1, warnings_.size()); + checkCallbackMessage(warnings_.at(0), "using RFC1035 TTL semantics", 2); +} + TEST_F(MasterLoaderTest, ttlFromPreviousSOA) { // Mixture of the previous two cases: SOA has explicit TTL, followed by // an RR without an explicit TTL. In this case the minimum TTL won't be