Commit 3007ba9e authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[1570] added another grandparent case: the server is auth of the child, too.

parent afc721fe
......@@ -406,6 +406,14 @@ Query::process() {
}
break;
case ZoneFinder::DELEGATION:
// If a DS query resulted in delegation, we also need to check
// if we are an authority of the child, too. If so, we need to
// complete the process in the child as specified in Section
// 2.2.1.2. of RFC3658.
if (qtype_ == RRType::DS() && processDSAtChild()) {
return;
}
response_.setHeaderFlag(Message::HEADERFLAG_AA, false);
response_.addRRset(Message::SECTION_AUTHORITY,
boost::const_pointer_cast<RRset>(db_result.rrset),
......
......@@ -202,6 +202,27 @@ getCommonRRSIGText(const string& type) {
"example.com. FAKEFAKEFAKE"));
}
// A helper callback of masterLoad() used in InMemoryZoneFinderTest.
void
setRRset(RRsetPtr rrset, vector<RRsetPtr*>::iterator& it) {
*(*it) = rrset;
++it;
}
// A helper function that converts a textual form of a single RR into a
// RRsetPtr object. If it's SOA, origin must be set to its owner name;
// otherwise masterLoad() will reject it.
RRsetPtr
textToRRset(const string& text_rrset, const Name& origin = Name::ROOT_NAME()) {
stringstream ss(text_rrset);
RRsetPtr rrset;
vector<RRsetPtr*> rrsets;
rrsets.push_back(&rrset);
masterLoad(ss, origin, RRClass::IN(),
boost::bind(setRRset, _1, rrsets.begin()));
return (rrset);
}
// This is a mock Zone Finder class for testing.
// It is a derived class of ZoneFinder for the convenient of tests.
// Its find() method emulates the common behavior of protocol compliant
......@@ -1613,20 +1634,40 @@ TEST_F(QueryTest, findNSEC3) {
// an authoritative answer, not a delegation. This is as described in
// RFC 4035, section 3.1.4.1.
// This mock finder is used for some DS-query test(s) to check if the lookup
// takes place at the parent zone, not at this (broken) zone.
class BrokenChildZoneFinder : public MockZoneFinder {
// This mock finder is used for some DS-query tests to emulate the situation
// where the server has authority for the child side of DS. Only limited
// methods are expected to called on this class object in these tests, which
// are overridden below.
class ChildZoneFinder : public MockZoneFinder {
public:
BrokenChildZoneFinder(const Name& origin) :
ChildZoneFinder(const Name& origin) :
MockZoneFinder(), origin_(origin)
{}
virtual isc::dns::Name getOrigin() const { return (origin_); }
virtual FindResult find(const isc::dns::Name&,
const isc::dns::RRType&,
virtual FindResult find(const isc::dns::Name& name,
const isc::dns::RRType& type,
const FindOptions)
{
isc_throw(isc::Unexpected,
"BrokenChildZoneFinder::find shouldn't be called");
if (name != origin_) {
isc_throw(isc::Unexpected, "Non origin name is asked for "
"ChildZoneFinder: " << name);
}
if (type == RRType::SOA()) {
RRsetPtr soa = textToRRset(origin_.toText() + " 3600 IN SOA . . "
"0 0 0 0 0\n", origin_);
soa->addRRsig(RdataPtr(new generic::RRSIG(
getCommonRRSIGText("SOA"))));
return (FindResult(SUCCESS, soa));
}
if (type == RRType::DS()) {
RRsetPtr nsec = textToRRset(origin_.toText() + " 3600 IN NSEC " +
origin_.toText() + " SOA NSEC RRSIG");
nsec->addRRsig(RdataPtr(new generic::RRSIG(
getCommonRRSIGText("NSEC"))));
return (FindResult(NXRRSET, nsec, RESULT_NSEC_SIGNED));
}
isc_throw(isc::Unexpected, "Unexpected RR type is asked for "
"ChildZoneFinder: " << type);
}
private:
const Name origin_;
......@@ -1634,7 +1675,7 @@ private:
TEST_F(QueryTest, dsAboveDelegation) {
// Pretending to have authority for the child zone, too.
memory_client.addZone(ZoneFinderPtr(new BrokenChildZoneFinder(
memory_client.addZone(ZoneFinderPtr(new ChildZoneFinder(
Name("delegation.example.com"))));
// The following will succeed only if the search goes to the parent
......@@ -1704,6 +1745,22 @@ TEST_F(QueryTest, dsAtGrandParent) {
ns_addrs_and_sig_txt.c_str());
}
TEST_F(QueryTest, dsAtGrandParentAndChild) {
// Pretending to have authority for the grandchild zone, too.
const Name childname("grand.delegation.example.com");
memory_client.addZone(ZoneFinderPtr(
new ChildZoneFinder(childname)));
Query(memory_client, childname, RRType::DS(), response, true).process();
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 4, 0, NULL,
(childname.toText() + " 3600 IN SOA . . 0 0 0 0 0\n" +
childname.toText() + " 3600 IN RRSIG " +
getCommonRRSIGText("SOA") + "\n" +
childname.toText() + " 3600 IN NSEC " +
childname.toText() + " SOA NSEC RRSIG\n" +
childname.toText() + " 3600 IN RRSIG " +
getCommonRRSIGText("NSEC")).c_str(), NULL, childname);
}
// The following are tentative tests until we really add tests for the
// query logic for these cases. At that point it's probably better to
// clean them up.
......
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