Commit 4760fba1 authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[2310] extend findAtOrigin so it can handle use_minttl correctly.

parent 5e9d101a
......@@ -23,10 +23,13 @@
#include <dns/name.h>
#include <dns/rrset.h>
#include <dns/rrtype.h>
#include <dns/rrttl.h>
#include <dns/nsec3hash.h>
#include <datasrc/logger.h>
#include <util/buffer.h>
#include <boost/scoped_ptr.hpp>
#include <boost/bind.hpp>
......@@ -104,14 +107,19 @@ createTreeNodeRRset(const ZoneNode* node,
const RdataSet* rdataset,
const RRClass& rrclass,
ZoneFinder::FindOptions options,
const Name* realname = NULL)
const Name* realname = NULL,
const void* ttl_data = NULL)
{
const bool dnssec = ((options & ZoneFinder::FIND_DNSSEC) != 0);
if (node != NULL && rdataset != NULL) {
if (realname != NULL) {
if (node && rdataset) {
if (realname) {
return (TreeNodeRRsetPtr(new TreeNodeRRset(*realname, rrclass,
node, rdataset,
dnssec)));
} else if (ttl_data) {
assert(!realname); // these two cases should be mixed in our use
return (TreeNodeRRsetPtr(new TreeNodeRRset(rrclass, node, rdataset,
dnssec, ttl_data)));
} else {
return (TreeNodeRRsetPtr(new TreeNodeRRset(rrclass, node, rdataset,
dnssec)));
......@@ -229,6 +237,12 @@ createNSEC3RRset(const ZoneNode* node, const RRClass& rrclass) {
ZoneFinder::FIND_DNSSEC));
}
inline RRTTL
createTTLFromData(const void* ttl_data) {
util::InputBuffer b(ttl_data, sizeof(uint32_t));
return (RRTTL(b));
}
// convenience function to fill in the final details
//
// Set up ZoneFinderResultContext object as a return value of find(),
......@@ -250,7 +264,8 @@ createFindResult(const RRClass& rrclass,
const RdataSet* rdataset,
ZoneFinder::FindOptions options,
bool wild = false,
const Name* qname = NULL)
const Name* qname = NULL,
bool use_minttl = false)
{
ZoneFinder::FindResultFlags flags = ZoneFinder::RESULT_DEFAULT;
const Name* rename = NULL;
......@@ -268,6 +283,15 @@ createFindResult(const RRClass& rrclass,
}
}
if (use_minttl && rdataset &&
createTTLFromData(zone_data.getMinTTLData()) <
createTTLFromData(rdataset->getTTLData())) {
return (ZoneFinderResultContext(
code,
createTreeNodeRRset(node, rdataset, rrclass, options,
rename, zone_data.getMinTTLData()),
flags, zone_data, node, rdataset));
}
return (ZoneFinderResultContext(code, createTreeNodeRRset(node, rdataset,
rrclass, options,
rename),
......@@ -743,7 +767,7 @@ InMemoryZoneFinder::findAll(const isc::dns::Name& name,
boost::shared_ptr<ZoneFinder::Context>
InMemoryZoneFinder::findAtOrigin(const isc::dns::RRType& type,
bool /*use_minttl*/, // not yet supported
bool use_minttl,
const FindOptions options)
{
const ZoneNode* const node = zone_data_.getOriginNode();
......@@ -755,7 +779,8 @@ InMemoryZoneFinder::findAtOrigin(const isc::dns::RRType& type,
return (ZoneFinderContextPtr(
new Context(*this, options, rrclass_,
createFindResult(rrclass_, zone_data_, SUCCESS,
node, found, options))));
node, found, options, false,
NULL, use_minttl))));
}
return (ZoneFinderContextPtr(
new Context(*this, options, rrclass_,
......@@ -764,7 +789,8 @@ InMemoryZoneFinder::findAtOrigin(const isc::dns::RRType& type,
getNSECForNXRRSET(zone_data_,
options,
node),
options))));
options, false, NULL,
use_minttl))));
}
ZoneFinderResultContext
......
......@@ -62,6 +62,10 @@ public:
/// \brief Search for an RRset of given RR type at the zone origin
/// specialized for in-memory data source.
///
/// This specialized version exploits internal data structure to find
/// RRsets at the zone origin and (if \c use_minttl is true) extract
/// the SOA Minimum TTL much more efficiently.
virtual boost::shared_ptr<Context> findAtOrigin(
const isc::dns::RRType& type, bool use_minttl,
FindOptions options);
......
......@@ -63,7 +63,11 @@ using result::EXIST;
/// be a concern here.
ConstRRsetPtr
convertRRset(ConstRRsetPtr src) {
return (textToRRset(src->toText()));
// If the type is SOA, textToRRset performs a stricter check, so we should
// specify the origin.
const Name& origin = (src->getType() == RRType::SOA()) ?
src->getName() : Name::ROOT_NAME();
return (textToRRset(src->toText(), src->getClass(), origin));
}
/// \brief Test fixture for the InMemoryZoneFinder class
......@@ -322,7 +326,7 @@ protected:
memory::InMemoryZoneFinder* zone_finder = NULL,
ZoneFinder::FindOptions options =
ZoneFinder::FIND_DEFAULT,
bool check_wild_answer = false)
bool use_minttl = false)
{
SCOPED_TRACE("findAtOriginTest for " + rrtype.toText());
......@@ -330,9 +334,9 @@ protected:
zone_finder = &zone_finder_;
}
ZoneFinderContextPtr find_result(zone_finder->findAtOrigin(
rrtype, false, options));
rrtype, use_minttl, options));
findTestCommon(origin_, result, find_result, check_answer, answer,
expected_flags, options, check_wild_answer);
expected_flags, options, false);
}
private:
......@@ -627,7 +631,6 @@ TEST_F(InMemoryZoneFinderTest, glue) {
findTest(rr_child_glue_->getName(), RRType::A(), ZoneFinder::DELEGATION,
true, rr_child_ns_);
// If we do it in the "glue OK" mode, we should find the exact match.
findTest(rr_child_glue_->getName(), RRType::A(), ZoneFinder::SUCCESS, true,
rr_child_glue_, ZoneFinder::RESULT_DEFAULT, NULL,
......@@ -701,6 +704,55 @@ TEST_F(InMemoryZoneFinderTest, findAtOrigin) {
ZoneFinder::FIND_DNSSEC);
}
TEST_F(InMemoryZoneFinderTest, findAtOriginWithMinTTL) {
// Install zone's SOA. This also sets internal zone data min TTL field.
addToZoneData(rr_soa_);
// Specify the use of min TTL, then the resulting TTL should be derived
// from the SOA MINTTL (which is smaller).
findAtOriginTest(RRType::SOA(), ZoneFinder::SUCCESS, true,
textToRRset("example.org. 100 IN SOA . . 0 0 0 0 100",
class_, origin_),
ZoneFinder::RESULT_DEFAULT, NULL,
ZoneFinder::FIND_DEFAULT, true);
// Add signed NS for the following test.
RRsetPtr ns_rrset(textToRRset("example.org. 300 IN NS ns.example.org."));
ns_rrset->addRRsig(createRdata(RRType::RRSIG(), RRClass::IN(),
"NS 5 3 3600 20120814220826 20120715220826 "
"1234 example.org. FAKE"));
addToZoneData(ns_rrset);
// If DNSSEC is requested, TTL of the RRSIG should also be the min.
ns_rrset->setTTL(RRTTL(100)); // reset TTL to the expected one
findAtOriginTest(RRType::NS(), ZoneFinder::SUCCESS, true, ns_rrset,
ZoneFinder::RESULT_DEFAULT, NULL,
ZoneFinder::FIND_DEFAULT, true);
// If we don't request the use of min TTL, the original TTL will be used.
findAtOriginTest(RRType::SOA(), ZoneFinder::SUCCESS, true, rr_soa_,
ZoneFinder::RESULT_DEFAULT, NULL,
ZoneFinder::FIND_DEFAULT, false);
// If no RRset is returned, use_minttl doesn't matter (it shouldn't cause
// disruption)
findAtOriginTest(RRType::TXT(), ZoneFinder::NXRRSET, true, ConstRRsetPtr(),
ZoneFinder::RESULT_DEFAULT, NULL,
ZoneFinder::FIND_DEFAULT, true);
// If it results in NXRRSET with NSEC, and if we specify the use of min
// TTL, the NSEC and RRSIG should have the min TTL (again, though, this
// use case is not really the intended one)
rr_nsec_->addRRsig(createRdata(RRType::RRSIG(), RRClass::IN(),
"NSEC 5 3 3600 20120814220826 "
"20120715220826 1234 example.org. FAKE"));
addToZoneData(rr_nsec_);
rr_nsec_->setTTL(RRTTL(100)); // reset it to the expected one
findAtOriginTest(RRType::TXT(), ZoneFinder::NXRRSET, true, rr_nsec_,
ZoneFinder::RESULT_NSEC_SIGNED, NULL,
ZoneFinder::FIND_DNSSEC, true);
}
/**
* \brief Test searching.
*
......
Supports Markdown
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