Parcourir la source

[1607] a small extension: Context now takes the finder and the original find
options and remember them. These will be used in the getAdditional() support.

JINMEI Tatuya il y a 13 ans
Parent
commit
a74802e842

+ 77 - 73
src/bin/auth/tests/query_unittest.cc

@@ -399,7 +399,10 @@ public:
                        ConstRRsetPtr rrset)
     {
         nsec_name_ = nsec_name;
-        nsec_context_.reset(new Context(code, rrset, RESULT_NSEC_SIGNED));
+        nsec_context_.reset(new Context(*this,
+                                        FIND_DEFAULT, // a fake value
+                                        ResultContext(code, rrset,
+                                                      RESULT_NSEC_SIGNED)));
     }
 
     // Once called, the findNSEC3 will return the provided result for the next
@@ -436,6 +439,18 @@ public:
     ConstRRsetPtr dname_rrset_; // could be used as an arbitrary bogus RRset
     ConstRRsetPtr empty_nsec_rrset_;
 
+protected:
+    // A convenient shortcut.  Will also be used by further derived mocks.
+    ZoneFinderContextPtr createContext(FindOptions options,
+                                       Result code,
+                                       isc::dns::ConstRRsetPtr rrset,
+                                       FindResultFlags flags = RESULT_DEFAULT)
+    {
+        return (ZoneFinderContextPtr(
+                    new Context(*this, options,
+                                ResultContext(code, rrset, flags))));
+    }
+
 private:
     typedef map<RRType, ConstRRsetPtr> RRsetStore;
     typedef map<Name, RRsetStore> Domains;
@@ -548,7 +563,9 @@ MockZoneFinder::findAll(const Name& name, std::vector<ConstRRsetPtr>& target,
                 // Insert RRs under the domain name into target
                 target.push_back(found_rrset->second);
             }
-            return (ZoneFinderContextPtr(new Context(SUCCESS, RRsetPtr())));
+            return (ZoneFinderContextPtr(
+                        new Context(*this, options,
+                                    ResultContext(SUCCESS, RRsetPtr()))));
         }
     }
 
@@ -618,9 +635,9 @@ MockZoneFinder::find(const Name& name, const RRType& type,
     // Emulating a broken zone: mandatory apex RRs are missing if specifically
     // configured so (which are rare cases).
     if (name == origin_ && type == RRType::SOA() && !has_SOA_) {
-        return (ZoneFinderContextPtr(new Context(NXDOMAIN, RRsetPtr())));
+        return (createContext(options, NXDOMAIN, RRsetPtr()));
     } else if (name == origin_ && type == RRType::NS() && !has_apex_NS_) {
-        return (ZoneFinderContextPtr(new Context(NXDOMAIN, RRsetPtr())));
+        return (createContext(options, NXDOMAIN, RRsetPtr()));
     }
 
     // Special case for names on or under a zone cut and under DNAME
@@ -635,12 +652,11 @@ MockZoneFinder::find(const Name& name, const RRType& type,
         // handled just like an in-zone case below.  Others result in
         // DELEGATION.
         if (type != RRType::DS() || it->first != name) {
-            return (ZoneFinderContextPtr(new Context(DELEGATION,
-                                                     delegation_ns)));
+            return (createContext(options, DELEGATION, delegation_ns));
         }
     } else if (name.compare(dname_name_).getRelation() ==
                NameComparisonResult::SUBDOMAIN) {
-        return (ZoneFinderContextPtr(new Context(DNAME, dname_rrset_)));
+        return (createContext(options, DNAME, dname_rrset_));
     }
 
     // normal cases.  names are searched for only per exact-match basis
@@ -670,37 +686,35 @@ MockZoneFinder::find(const Name& name, const RRType& type,
                 }
                 rrset = noconst;
             }
-            return (ZoneFinderContextPtr(new Context(SUCCESS, rrset)));
+            return (createContext(options, SUCCESS, rrset));
         }
 
         // Otherwise, if this domain name has CNAME, return it.
         found_rrset = found_domain->second.find(RRType::CNAME());
         if (found_rrset != found_domain->second.end()) {
-            return (ZoneFinderContextPtr(new Context(CNAME,
-                                                     found_rrset->second)));
+            return (createContext(options, CNAME, found_rrset->second));
         }
 
         // Otherwise it's NXRRSET case...
         // ...but a special pathological case first:
         if (found_domain->first == bad_signed_delegation_name_ &&
             type == RRType::DS()) {
-            return (ZoneFinderContextPtr(new Context(NXDOMAIN, RRsetPtr())));
+            return (createContext(options, NXDOMAIN, RRsetPtr()));
         }
         // normal cases follow.
         if ((options & FIND_DNSSEC) != 0) {
             if (use_nsec3_) {
-                return (ZoneFinderContextPtr(new Context(NXRRSET, RRsetPtr(),
-                                                         RESULT_NSEC3_SIGNED)));
+                return (createContext(options, NXRRSET, RRsetPtr(),
+                                      RESULT_NSEC3_SIGNED));
             }
             found_rrset = found_domain->second.find(RRType::NSEC());
             if (found_rrset != found_domain->second.end()) {
-                return (ZoneFinderContextPtr(new Context(NXRRSET,
-                                                         found_rrset->second,
-                                                         RESULT_NSEC_SIGNED)));
+                return (createContext(options, NXRRSET, found_rrset->second,
+                                      RESULT_NSEC_SIGNED));
             }
         }
-        return (ZoneFinderContextPtr(new Context(NXRRSET, RRsetPtr(),
-                                                 RESULT_NSEC_SIGNED)));
+        return (createContext(options, NXRRSET, RRsetPtr(),
+                              RESULT_NSEC_SIGNED));
     }
 
     // query name isn't found in our domains.
@@ -720,18 +734,17 @@ MockZoneFinder::find(const Name& name, const RRType& type,
         --domain;               // reset domain to the "previous name"
         if ((options & FIND_DNSSEC) != 0) {
             if (use_nsec3_) {
-                return (ZoneFinderContextPtr(new Context(NXRRSET, RRsetPtr(),
-                                                         RESULT_NSEC3_SIGNED)));
+                return (createContext(options, NXRRSET, RRsetPtr(),
+                                      RESULT_NSEC3_SIGNED));
             }
             RRsetStore::const_iterator found_rrset =
                 (*domain).second.find(RRType::NSEC());
             if (found_rrset != (*domain).second.end()) {
-                return (ZoneFinderContextPtr(
-                            new Context(NXRRSET, found_rrset->second,
-                                        RESULT_NSEC_SIGNED)));
+                return (createContext(options, NXRRSET, found_rrset->second,
+                                      RESULT_NSEC_SIGNED));
             }
         }
-        return (ZoneFinderContextPtr(new Context(NXRRSET, RRsetPtr())));
+        return (createContext(options, NXRRSET, RRsetPtr()));
     }
 
     // Another possibility is wildcard.  For simplicity we only check
@@ -754,44 +767,37 @@ MockZoneFinder::find(const Name& name, const RRType& type,
                         domain->second.find(type);
                     // Matched the QTYPE
                     if(found_rrset != domain->second.end()) {
-                        return (ZoneFinderContextPtr(
-                                    new Context(SUCCESS,
-                                                substituteWild(
-                                                    *found_rrset->second,
-                                                    name),
-                                                RESULT_WILDCARD |
-                                                (use_nsec3_ ?
-                                                 RESULT_NSEC3_SIGNED :
-                                                 RESULT_NSEC_SIGNED))));
+                        return (createContext(options,SUCCESS, substituteWild(
+                                                  *found_rrset->second, name),
+                                              RESULT_WILDCARD |
+                                              (use_nsec3_ ?
+                                               RESULT_NSEC3_SIGNED :
+                                               RESULT_NSEC_SIGNED)));
                     } else {
                         // No matched QTYPE, this case is for NXRRSET with
                         // WILDCARD
                         if (use_nsec3_) {
-                            return (ZoneFinderContextPtr(
-                                        new Context(NXRRSET, RRsetPtr(),
-                                                    RESULT_WILDCARD |
-                                                    RESULT_NSEC3_SIGNED)));
+                            return (createContext(options, NXRRSET, RRsetPtr(),
+                                                  RESULT_WILDCARD |
+                                                  RESULT_NSEC3_SIGNED));
                         }
                         const Name new_name =
                             Name("*").concatenate(wild_suffix);
                         found_rrset = domain->second.find(RRType::NSEC());
                         assert(found_rrset != domain->second.end());
-                        return (ZoneFinderContextPtr(
-                                    new Context(NXRRSET,
-                                                substituteWild(
-                                                    *found_rrset->second,
-                                                    new_name),
-                                                RESULT_WILDCARD |
-                                                RESULT_NSEC_SIGNED)));
+                        return (createContext(options, NXRRSET, substituteWild(
+                                                  *found_rrset->second,
+                                                  new_name),
+                                              RESULT_WILDCARD |
+                                              RESULT_NSEC_SIGNED));
                     }
                 } else {
                     // This is empty non terminal name case on wildcard.
                     const Name empty_name = Name("*").concatenate(wild_suffix);
                     if (use_nsec3_) {
-                        return (ZoneFinderContextPtr(
-                                    new Context(NXRRSET, RRsetPtr(),
-                                                RESULT_WILDCARD |
-                                                RESULT_NSEC3_SIGNED)));
+                        return (createContext(options, NXRRSET, RRsetPtr(),
+                                              RESULT_WILDCARD |
+                                              RESULT_NSEC3_SIGNED));
                     }
                     for (Domains::reverse_iterator it = domains_.rbegin();
                          it != domains_.rend();
@@ -800,15 +806,15 @@ MockZoneFinder::find(const Name& name, const RRType& type,
                         if ((*it).first < empty_name &&
                             (nsec_it = (*it).second.find(RRType::NSEC()))
                             != (*it).second.end()) {
-                            return (ZoneFinderContextPtr(
-                                        new Context(NXRRSET, (*nsec_it).second,
-                                                    RESULT_WILDCARD |
-                                                    RESULT_NSEC_SIGNED)));
+                            return (createContext(options, NXRRSET,
+                                                  (*nsec_it).second,
+                                                  RESULT_WILDCARD |
+                                                  RESULT_NSEC_SIGNED));
                         }
                     }
                 }
-                return (ZoneFinderContextPtr(new Context(NXRRSET, RRsetPtr(),
-                                                         RESULT_WILDCARD)));
+                return (createContext(options, NXRRSET, RRsetPtr(),
+                                      RESULT_WILDCARD));
              }
         }
         const Name cnamewild_suffix("cnamewild.example.com");
@@ -819,12 +825,11 @@ MockZoneFinder::find(const Name& name, const RRType& type,
             RRsetStore::const_iterator found_rrset =
                 domain->second.find(RRType::CNAME());
             assert(found_rrset != domain->second.end());
-            return (ZoneFinderContextPtr(
-                        new Context(CNAME,
-                                    substituteWild(*found_rrset->second, name),
-                                    RESULT_WILDCARD |
-                                    (use_nsec3_ ? RESULT_NSEC3_SIGNED :
-                                     RESULT_NSEC_SIGNED))));
+            return (createContext(options, CNAME,
+                                  substituteWild(*found_rrset->second, name),
+                                  RESULT_WILDCARD |
+                                  (use_nsec3_ ? RESULT_NSEC3_SIGNED :
+                                   RESULT_NSEC_SIGNED)));
         }
     }
 
@@ -837,8 +842,8 @@ MockZoneFinder::find(const Name& name, const RRType& type,
     // than the origin)
     if ((options & FIND_DNSSEC) != 0) {
         if (use_nsec3_) {
-            return (ZoneFinderContextPtr(new Context(NXDOMAIN, RRsetPtr(),
-                                                     RESULT_NSEC3_SIGNED)));
+            return (createContext(options, NXDOMAIN, RRsetPtr(),
+                                  RESULT_NSEC3_SIGNED));
         }
 
         // Emulate a broken DataSourceClient for some special names.
@@ -856,13 +861,12 @@ MockZoneFinder::find(const Name& name, const RRType& type,
             if ((*it).first < name &&
                 (nsec_it = (*it).second.find(RRType::NSEC()))
                 != (*it).second.end()) {
-                return (ZoneFinderContextPtr(new Context(NXDOMAIN,
-                                                         (*nsec_it).second,
-                                                         RESULT_NSEC_SIGNED)));
+                return (createContext(options, NXDOMAIN, (*nsec_it).second,
+                                      RESULT_NSEC_SIGNED));
             }
         }
     }
-    return (ZoneFinderContextPtr(new Context(NXDOMAIN, RRsetPtr())));
+    return (createContext(options,NXDOMAIN, RRsetPtr()));
 }
 
 class QueryTest : public ::testing::Test {
@@ -1982,21 +1986,21 @@ public:
     virtual isc::dns::Name getOrigin() const { return (origin_); }
     virtual ZoneFinderContextPtr find(const isc::dns::Name&,
                                       const isc::dns::RRType& type,
-                                      const FindOptions)
+                                      const FindOptions options)
     {
         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 (ZoneFinderContextPtr(new Context(SUCCESS, soa)));
+            return (createContext(options, SUCCESS, soa));
         }
         if (type == RRType::NS()) {
             RRsetPtr ns = textToRRset(origin_.toText() + " 3600 IN NS " +
                                       Name("ns").concatenate(origin_).toText());
             ns->addRRsig(RdataPtr(new generic::RRSIG(
                                       getCommonRRSIGText("NS"))));
-            return (ZoneFinderContextPtr(new Context(SUCCESS, ns)));
+            return (createContext(options, SUCCESS, ns));
         }
         if (type == RRType::DS()) {
             if (have_ds_) {
@@ -2006,7 +2010,7 @@ public:
                                           "3CD34AC1AFE51DE");
                 ds->addRRsig(RdataPtr(new generic::RRSIG(
                                           getCommonRRSIGText("DS"))));
-                return (ZoneFinderContextPtr(new Context(SUCCESS, ds)));
+                return (createContext(options, SUCCESS, ds));
             } else {
                 RRsetPtr nsec = textToRRset(origin_.toText() +
                                             " 3600 IN NSEC " +
@@ -2014,13 +2018,13 @@ public:
                                             " SOA NSEC RRSIG");
                 nsec->addRRsig(RdataPtr(new generic::RRSIG(
                                             getCommonRRSIGText("NSEC"))));
-                return (ZoneFinderContextPtr(new Context(NXRRSET, nsec,
-                                                         RESULT_NSEC_SIGNED)));
+                return (createContext(options, NXRRSET, nsec,
+                                      RESULT_NSEC_SIGNED));
             }
         }
 
         // Returning NXDOMAIN is not correct, but doesn't matter for our tests.
-        return (ZoneFinderContextPtr(new Context(NXDOMAIN, ConstRRsetPtr())));
+        return (createContext(options, NXDOMAIN, ConstRRsetPtr()));
     }
 private:
     const Name origin_;

+ 25 - 23
src/lib/datasrc/database.cc

@@ -401,9 +401,9 @@ DatabaseClient::Finder::findAll(const isc::dns::Name& name,
                                 std::vector<isc::dns::ConstRRsetPtr>& target,
                                 const FindOptions options)
 {
-    return (ZoneFinderContextPtr(new Context(
-                                     findInternal(name, RRType::ANY(),
-                                                  &target, options))));
+    return (ZoneFinderContextPtr(new Context(*this, options,
+                                             findInternal(name, RRType::ANY(),
+                                                          &target, options))));
 }
 
 ZoneFinderContextPtr
@@ -414,8 +414,9 @@ DatabaseClient::Finder::find(const isc::dns::Name& name,
     if (type == RRType::ANY()) {
         isc_throw(isc::Unexpected, "Use findAll to answer ANY");
     }
-    return (ZoneFinderContextPtr(new Context(
-                                     findInternal(name, type, NULL, options))));
+    return (ZoneFinderContextPtr(new Context(*this, options,
+                                             findInternal(name, type,
+                                                          NULL, options))));
 }
 
 DatabaseClient::Finder::DelegationSearchResult
@@ -576,7 +577,7 @@ DatabaseClient::Finder::findDelegationPoint(const isc::dns::Name& name,
 // covering NSEC record.
 //
 // If none of the above applies in any level, the search fails with NXDOMAIN.
-ZoneFinder::Context
+ZoneFinder::ResultContext
 DatabaseClient::Finder::findWildcardMatch(
     const isc::dns::Name& name, const isc::dns::RRType& type,
     const FindOptions options, const DelegationSearchResult& dresult,
@@ -619,7 +620,7 @@ DatabaseClient::Finder::findWildcardMatch(
                           DATASRC_DATABASE_WILDCARD_CANCEL_NS).
                     arg(accessor_->getDBName()).arg(wildcard).
                     arg(dresult.first_ns->getName());
-                return (Context(DELEGATION, dresult.first_ns));
+                return (ResultContext(DELEGATION, dresult.first_ns));
             } else if (!hasSubdomains(name.split(i - 1).toText())) {
                 // The wildcard match is the best one, find the final result
                 // at it.  Note that wildcard should never be the zone origin.
@@ -632,7 +633,7 @@ DatabaseClient::Finder::findWildcardMatch(
                           DATASRC_DATABASE_WILDCARD_CANCEL_SUB).
                     arg(accessor_->getDBName()).arg(wildcard).
                     arg(name).arg(superdomain);
-                return (Context(NXDOMAIN, ConstRRsetPtr()));
+                return (ResultContext(NXDOMAIN, ConstRRsetPtr()));
             }
 
         } else if (hasSubdomains(wildcard)) {
@@ -643,19 +644,20 @@ DatabaseClient::Finder::findWildcardMatch(
             if ((options & FIND_DNSSEC) != 0) {
                 ConstRRsetPtr nsec = findNSECCover(Name(wildcard));
                 if (nsec) {
-                    return (Context(NXRRSET, nsec,
-                                    RESULT_WILDCARD | RESULT_NSEC_SIGNED));
+                    return (ResultContext(NXRRSET, nsec,
+                                          RESULT_WILDCARD |
+                                          RESULT_NSEC_SIGNED));
                 }
             }
-            return (Context(NXRRSET, ConstRRsetPtr(), RESULT_WILDCARD));
+            return (ResultContext(NXRRSET, ConstRRsetPtr(), RESULT_WILDCARD));
         }
     }
 
     // Nothing found at any level.
-    return (Context(NXDOMAIN, ConstRRsetPtr()));
+    return (ResultContext(NXDOMAIN, ConstRRsetPtr()));
 }
 
-ZoneFinder::Context
+ZoneFinder::ResultContext
 DatabaseClient::Finder::logAndCreateResult(
     const Name& name, const string* wildname, const RRType& type,
     ZoneFinder::Result code, ConstRRsetPtr rrset,
@@ -682,10 +684,10 @@ DatabaseClient::Finder::logAndCreateResult(
                 arg(getClass()).arg(*wildname);
         }
     }
-    return (Context(code, rrset, flags));
+    return (ResultContext(code, rrset, flags));
 }
 
-ZoneFinder::Context
+ZoneFinder::ResultContext
 DatabaseClient::Finder::findOnNameResult(const Name& name,
                                          const RRType& type,
                                          const FindOptions options,
@@ -801,7 +803,7 @@ DatabaseClient::Finder::findOnNameResult(const Name& name,
                                DATASRC_DATABASE_FOUND_NXRRSET, flags));
 }
 
-ZoneFinder::Context
+ZoneFinder::ResultContext
 DatabaseClient::Finder::findNoNameResult(const Name& name, const RRType& type,
                                          FindOptions options,
                                          const DelegationSearchResult& dresult,
@@ -823,14 +825,14 @@ DatabaseClient::Finder::findNoNameResult(const Name& name, const RRType& type,
             arg(accessor_->getDBName()).arg(name);
         const ConstRRsetPtr nsec = dnssec_data ? findNSECCover(name) :
             ConstRRsetPtr();
-        return (Context(NXRRSET, nsec,
+        return (ResultContext(NXRRSET, nsec,
                         nsec ? RESULT_NSEC_SIGNED : RESULT_DEFAULT));
     } else if ((options & NO_WILDCARD) == 0) {
         // It's not an empty non-terminal and wildcard matching is not
         // disabled, so check for wildcards. If there is a wildcard match
         // (i.e. all results except NXDOMAIN) return it; otherwise fall
         // through to the NXDOMAIN case below.
-        const Context wcontext =
+        const ResultContext wcontext =
             findWildcardMatch(name, type, options, dresult, target);
         if (wcontext.code != NXDOMAIN) {
             return (wcontext);
@@ -843,11 +845,11 @@ DatabaseClient::Finder::findNoNameResult(const Name& name, const RRType& type,
               arg(accessor_->getDBName()).arg(name).arg(type).arg(getClass());
     const ConstRRsetPtr nsec = dnssec_data ? findNSECCover(name) :
         ConstRRsetPtr();
-    return (Context(NXDOMAIN, nsec,
-                    nsec ? RESULT_NSEC_SIGNED : RESULT_DEFAULT));
+    return (ResultContext(NXDOMAIN, nsec,
+                          nsec ? RESULT_NSEC_SIGNED : RESULT_DEFAULT));
 }
 
-ZoneFinder::Context
+ZoneFinder::ResultContext
 DatabaseClient::Finder::findInternal(const Name& name, const RRType& type,
                                      std::vector<ConstRRsetPtr>* target,
                                      const FindOptions options)
@@ -862,7 +864,7 @@ DatabaseClient::Finder::findInternal(const Name& name, const RRType& type,
         name.compare(getOrigin()).getRelation();
     if (reln != NameComparisonResult::SUBDOMAIN &&
         reln != NameComparisonResult::EQUAL) {
-        return (Context(NXDOMAIN, ConstRRsetPtr()));
+        return (ResultContext(NXDOMAIN, ConstRRsetPtr()));
     }
 
     // First, go through all superdomains from the origin down, searching for
@@ -879,7 +881,7 @@ DatabaseClient::Finder::findInternal(const Name& name, const RRType& type,
     const DelegationSearchResult dresult = findDelegationPoint(name, options);
     if (dresult.rrset) {
         // In this case no special flags are needed.
-        return (Context(dresult.code, dresult.rrset));
+        return (ResultContext(dresult.code, dresult.rrset));
     }
 
     // If there is no delegation, look for the exact match to the request

+ 28 - 25
src/lib/datasrc/database.h

@@ -787,6 +787,7 @@ public:
             FoundRRsets;
         /// \brief Just shortcut for set of types
         typedef std::set<dns::RRType> WantedTypes;
+
         /// \brief Internal logit of find and findAll methods.
         ///
         /// Most of their handling is in the "error" cases and delegations
@@ -796,10 +797,11 @@ public:
         /// Parameters and behaviour is like of those combined together.
         /// Unexpected parameters, like type != ANY and having the target, are
         /// just that - unexpected and not checked.
-        Context findInternal(const isc::dns::Name& name,
-                             const isc::dns::RRType& type,
-                             std::vector<isc::dns::ConstRRsetPtr>* target,
-                             const FindOptions options = FIND_DEFAULT);
+        ResultContext findInternal(const isc::dns::Name& name,
+                                   const isc::dns::RRType& type,
+                                   std::vector<isc::dns::ConstRRsetPtr>*
+                                   target,
+                                   const FindOptions options = FIND_DEFAULT);
 
         /// \brief Searches database for RRsets of one domain.
         ///
@@ -945,7 +947,7 @@ public:
         ///         success due to an exact match).  Also returned if there
         ///         is no match is an indication as to whether there was an
         ///         NXDOMAIN or an NXRRSET.
-        Context findWildcardMatch(
+        ResultContext findWildcardMatch(
             const isc::dns::Name& name,
             const isc::dns::RRType& type,
             const FindOptions options,
@@ -990,13 +992,14 @@ public:
         ///         the above 4 cases).  The return value is intended to be
         ///         usable as a return value of the caller of this helper
         ///         method.
-        Context findOnNameResult(const isc::dns::Name& name,
-                                 const isc::dns::RRType& type,
-                                 const FindOptions options,
-                                 const bool is_origin,
-                                 const FoundRRsets& found,
-                                 const std::string* wildname,
-                                 std::vector<isc::dns::ConstRRsetPtr>* target);
+        ResultContext findOnNameResult(const isc::dns::Name& name,
+                                       const isc::dns::RRType& type,
+                                       const FindOptions options,
+                                       const bool is_origin,
+                                       const FoundRRsets& found,
+                                       const std::string* wildname,
+                                       std::vector<isc::dns::ConstRRsetPtr>*
+                                       target);
 
         /// \brief Handle no match for name
         ///
@@ -1027,12 +1030,12 @@ public:
         ///         indicating the match type (e.g. CNAME at the wildcard
         ///         match, no RRs of the requested type at the wildcard,
         ///         success due to an exact match).
-        Context findNoNameResult(const isc::dns::Name& name,
-                                 const isc::dns::RRType& type,
-                                 FindOptions options,
-                                 const DelegationSearchResult& dresult,
-                                 std::vector<isc::dns::ConstRRsetPtr>*
-                                 target);
+        ResultContext findNoNameResult(const isc::dns::Name& name,
+                                       const isc::dns::RRType& type,
+                                       FindOptions options,
+                                       const DelegationSearchResult& dresult,
+                                       std::vector<isc::dns::ConstRRsetPtr>*
+                                       target);
 
         /// Logs condition and creates result
         ///
@@ -1055,13 +1058,13 @@ public:
         ///
         /// \return FindResult object constructed from the code and rrset
         ///         arguments.
-        Context logAndCreateResult(const isc::dns::Name& name,
-                                   const std::string* wildname,
-                                   const isc::dns::RRType& type,
-                                   ZoneFinder::Result code,
-                                   isc::dns::ConstRRsetPtr rrset,
-                                   const isc::log::MessageID& log_id,
-                                   FindResultFlags flags) const;
+        ResultContext logAndCreateResult(const isc::dns::Name& name,
+                                         const std::string* wildname,
+                                         const isc::dns::RRType& type,
+                                         ZoneFinder::Result code,
+                                         isc::dns::ConstRRsetPtr rrset,
+                                         const isc::log::MessageID& log_id,
+                                         FindResultFlags flags) const;
 
         /// \brief Checks if something lives below this domain.
         ///

+ 33 - 29
src/lib/datasrc/memory_datasrc.cc

@@ -649,8 +649,8 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
     // account wildcard matches and DNSSEC information.  We set the NSEC/NSEC3
     // flag when applicable regardless of the find option; the caller would
     // simply ignore these when they didn't request DNSSEC related results.
-    ZoneFinderContextPtr createFindContext(Result code, ConstRRsetPtr rrset,
-                                           bool wild = false) const
+    ResultContext createFindResult(Result code, ConstRRsetPtr rrset,
+                                   bool wild = false) const
     {
         FindResultFlags flags = RESULT_DEFAULT;
         if (wild) {
@@ -660,13 +660,13 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
             zone_data_->nsec3_data_) {
             flags = flags | RESULT_NSEC3_SIGNED;
         }
-        return (ZoneFinderContextPtr(new Context(code, rrset, flags)));
+        return (ZoneFinder::ResultContext(code, rrset, flags));
     }
 
     // Implementation of InMemoryZoneFinder::find
-    ZoneFinderContextPtr find(const Name& name, RRType type,
-                              std::vector<ConstRRsetPtr>* target,
-                              const FindOptions options) const
+    ZoneFinder::ResultContext find(const Name& name, RRType type,
+                                   std::vector<ConstRRsetPtr>* target,
+                                   const FindOptions options) const
     {
         LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_MEM_FIND).arg(name).
             arg(type);
@@ -701,16 +701,16 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
                         arg(state.rrset_->getName());
                     // We were traversing a DNAME node (and wanted to go
                     // lower below it), so return the DNAME
-                    return (createFindContext(DNAME,
-                                              prepareRRset(name, state.rrset_,
-                                                           false, options)));
+                    return (createFindResult(DNAME,
+                                             prepareRRset(name, state.rrset_,
+                                                          false, options)));
                 }
                 if (state.zonecut_node_ != NULL) {
                     LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_MEM_DELEG_FOUND).
                         arg(state.rrset_->getName());
-                    return (createFindContext(DELEGATION,
-                                              prepareRRset(name, state.rrset_,
-                                                           false, options)));
+                    return (createFindResult(DELEGATION,
+                                             prepareRRset(name, state.rrset_,
+                                                          false, options)));
                 }
 
                 // If the RBTree search stopped at a node for a super domain
@@ -720,7 +720,7 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
                     NameComparisonResult::SUPERDOMAIN) {
                     LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_MEM_SUPER_STOP).
                         arg(name);
-                    return (createFindContext(NXRRSET, ConstRRsetPtr()));
+                    return (createFindResult(NXRRSET, ConstRRsetPtr()));
                 }
 
                 /*
@@ -759,8 +759,8 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
                         getLastComparisonResult().getCommonLabels() > 1) {
                         LOG_DEBUG(logger, DBG_TRACE_DATA,
                                      DATASRC_MEM_WILDCARD_CANCEL).arg(name);
-                        return (createFindContext(NXDOMAIN, ConstRRsetPtr(),
-                                                  false));
+                        return (createFindResult(NXDOMAIN, ConstRRsetPtr(),
+                                                 false));
                     }
                     const Name wildcard(Name("*").concatenate(
                         node_path.getAbsoluteName()));
@@ -785,7 +785,7 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
             case DomainTree::NOTFOUND:
                 LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_MEM_NOT_FOUND).
                     arg(name);
-                return (createFindContext(NXDOMAIN, ConstRRsetPtr(), false));
+                return (createFindResult(NXDOMAIN, ConstRRsetPtr(), false));
             case DomainTree::EXACTMATCH: // This one is OK, handle it
                 break;
             default:
@@ -798,7 +798,7 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
         if (node->isEmpty()) {
             LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_MEM_DOMAIN_EMPTY).
                 arg(name);
-            return (createFindContext(NXRRSET, ConstRRsetPtr(), rename));
+            return (createFindResult(NXRRSET, ConstRRsetPtr(), rename));
         }
 
         Domain::const_iterator found;
@@ -813,9 +813,9 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
             if (found != node->getData()->end()) {
                 LOG_DEBUG(logger, DBG_TRACE_DATA,
                           DATASRC_MEM_EXACT_DELEGATION).arg(name);
-                return (createFindContext(DELEGATION,
-                                          prepareRRset(name, found->second,
-                                                       rename, options)));
+                return (createFindResult(DELEGATION,
+                                         prepareRRset(name, found->second,
+                                                      rename, options)));
             }
         }
 
@@ -830,7 +830,7 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
             }
             LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_MEM_ANY_SUCCESS).
                 arg(name);
-            return (createFindContext(SUCCESS, ConstRRsetPtr(), rename));
+            return (createFindResult(SUCCESS, ConstRRsetPtr(), rename));
         }
 
         found = node->getData()->find(type);
@@ -838,16 +838,16 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
             // Good, it is here
             LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_MEM_SUCCESS).arg(name).
                 arg(type);
-            return (createFindContext(SUCCESS, prepareRRset(name,
-                                                            found->second,
-                                                            rename, options),
-                                      rename));
+            return (createFindResult(SUCCESS, prepareRRset(name,
+                                                           found->second,
+                                                           rename, options),
+                                     rename));
         } else {
             // Next, try CNAME.
             found = node->getData()->find(RRType::CNAME());
             if (found != node->getData()->end()) {
                 LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_MEM_CNAME).arg(name);
-                return (createFindContext(CNAME,
+                return (createFindResult(CNAME,
                                           prepareRRset(name, found->second,
                                                        rename, options),
                                           rename));
@@ -856,7 +856,7 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
         // No exact match or CNAME.  Return NXRRSET.
         LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_MEM_NXRRSET).arg(type).
             arg(name);
-        return (createFindContext(NXRRSET, ConstRRsetPtr(), rename));
+        return (createFindResult(NXRRSET, ConstRRsetPtr(), rename));
     }
 };
 
@@ -887,7 +887,9 @@ ZoneFinderContextPtr
 InMemoryZoneFinder::find(const Name& name, const RRType& type,
                          const FindOptions options)
 {
-    return (impl_->find(name, type, NULL, options));
+    return (ZoneFinderContextPtr(
+                new Context(*this, options,
+                            impl_->find(name, type, NULL, options))));
 }
 
 ZoneFinderContextPtr
@@ -895,7 +897,9 @@ InMemoryZoneFinder::findAll(const Name& name,
                             std::vector<ConstRRsetPtr>& target,
                             const FindOptions options)
 {
-    return (impl_->find(name, RRType::ANY(), &target, options));
+    return (ZoneFinderContextPtr(
+                new Context(*this, options, impl_->find(name, RRType::ANY(),
+                                                        &target, options))));
 }
 
 ZoneFinder::FindNSEC3Result

+ 51 - 25
src/lib/datasrc/zone.h

@@ -15,8 +15,9 @@
 #ifndef __ZONE_H
 #define __ZONE_H 1
 
+#include <dns/name.h>
 #include <dns/rrset.h>
-#include <dns/rrsetlist.h>
+#include <dns/rrtype.h>
 
 #include <datasrc/result.h>
 
@@ -90,7 +91,40 @@ public:
         RESULT_NSEC3_SIGNED = 4   ///< The zone is signed with NSEC3 RRs
     };
 
-    /// A helper structure to represent the search result of \c find().
+    /// Find options.
+    ///
+    /// The option values are used as a parameter for \c find().
+    /// These are values of a bitmask type.  Bitwise operations can be
+    /// performed on these values to express compound options.
+    enum FindOptions {
+        FIND_DEFAULT = 0,       ///< The default options
+        FIND_GLUE_OK = 1,       ///< Allow search under a zone cut
+        FIND_DNSSEC = 2,        ///< Require DNSSEC data in the answer
+                                ///< (RRSIG, NSEC, etc.). The implementation
+                                ///< is allowed to include it even if it is
+                                ///< not set.
+        NO_WILDCARD = 4         ///< Do not try wildcard matching.
+    };
+
+protected:
+    /// \brief A convenient tuple representing a set of find() results.
+    ///
+    /// This helper structure is specifically expected to be used as an input
+    /// for the construct of the \c Context class object used by derived
+    /// ZoneFinder implementations.  This is therefore defined as protected.
+    struct ResultContext {
+        ResultContext(Result code_param,
+                      isc::dns::ConstRRsetPtr rrset_param,
+                      FindResultFlags flags_param = RESULT_DEFAULT) :
+            code(code_param), rrset(rrset_param), flags(flags_param)
+        {}
+        const Result code;
+        const isc::dns::ConstRRsetPtr rrset;
+        const FindResultFlags flags;
+    };
+
+public:
+    /// \brief A helper structure to represent the search result of \c find().
     ///
     /// This is a straightforward tuple of the result code and a pointer
     /// (and optionally special flags) to the found RRset to represent the
@@ -114,16 +148,16 @@ public:
     /// optimize including the NSEC for no-wildcard proof (FWIW NSD does that).
     class Context {
     public:
-        Context(Result param_code,
-                const isc::dns::ConstRRsetPtr param_rrset,
-                FindResultFlags param_flags = RESULT_DEFAULT) :
-            code(param_code), rrset(param_rrset), flags(param_flags)
+        Context(ZoneFinder& finder, FindOptions options,
+                const ResultContext& result) :
+            code(result.code), rrset(result.rrset),
+            finder_(finder), flags_(result.flags), options_(options)
         {}
         const Result code;
         const isc::dns::ConstRRsetPtr rrset;
 
         /// Return true iff find() results in a wildcard match.
-        bool isWildcard() const { return ((flags & RESULT_WILDCARD) != 0); }
+        bool isWildcard() const { return ((flags_ & RESULT_WILDCARD) != 0); }
 
         /// Return true when the underlying zone is signed with NSEC.
         ///
@@ -135,7 +169,7 @@ public:
         /// that \c rrset be a valid NSEC RRset as described in \c find()
         /// documentation.
         bool isNSECSigned() const {
-            return ((flags & RESULT_NSEC_SIGNED) != 0);
+            return ((flags_ & RESULT_NSEC_SIGNED) != 0);
         }
 
         /// Return true when the underlying zone is signed with NSEC3.
@@ -144,25 +178,17 @@ public:
         /// \c FIND_DNSSEC isn't specified regardless of whether the zone
         /// is signed or which of NSEC/NSEC3 is used.
         bool isNSEC3Signed() const {
-            return ((flags & RESULT_NSEC3_SIGNED) != 0);
+            return ((flags_ & RESULT_NSEC3_SIGNED) != 0);
         }
-    private:
-        FindResultFlags flags;
-    };
 
-    /// Find options.
-    ///
-    /// The option values are used as a parameter for \c find().
-    /// These are values of a bitmask type.  Bitwise operations can be
-    /// performed on these values to express compound options.
-    enum FindOptions {
-        FIND_DEFAULT = 0,       ///< The default options
-        FIND_GLUE_OK = 1,       ///< Allow search under a zone cut
-        FIND_DNSSEC = 2,        ///< Require DNSSEC data in the answer
-                                ///< (RRSIG, NSEC, etc.). The implementation
-                                ///< is allowed to include it even if it is
-                                ///< not set.
-        NO_WILDCARD = 4         ///< Do not try wildcard matching.
+        virtual void getAdditional(
+            const std::vector<isc::dns::RRType>& requested_types,
+            std::vector<isc::dns::ConstRRsetPtr>& result);
+
+    private:
+        ZoneFinder& finder_;
+        const FindResultFlags flags_;
+        const FindOptions options_;
     };
 
     ///