|
@@ -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.
|