From: JINMEI Tatuya Date: Thu, 2 Feb 2012 23:06:45 +0000 (-0800) Subject: [1570] added another grandparent case: the server is auth of the child, too. X-Git-Tag: trac2351_base~263^2~10 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3007ba9ef2cffdf4903b43a14ccf52a0c1d3ec65;p=thirdparty%2Fkea.git [1570] added another grandparent case: the server is auth of the child, too. --- diff --git a/src/bin/auth/query.cc b/src/bin/auth/query.cc index 0674975387..900a48dc71 100644 --- a/src/bin/auth/query.cc +++ b/src/bin/auth/query.cc @@ -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(db_result.rrset), diff --git a/src/bin/auth/tests/query_unittest.cc b/src/bin/auth/tests/query_unittest.cc index 4b9b538175..4d096d0059 100644 --- a/src/bin/auth/tests/query_unittest.cc +++ b/src/bin/auth/tests/query_unittest.cc @@ -202,6 +202,27 @@ getCommonRRSIGText(const string& type) { "example.com. FAKEFAKEFAKE")); } +// A helper callback of masterLoad() used in InMemoryZoneFinderTest. +void +setRRset(RRsetPtr rrset, vector::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 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.