FoundRRsets getRRsets(const std::string& name,
const WantedTypes& types, bool check_ns,
const std::string* construct_name = NULL,
- bool any = false);
+ bool any = false,
+ DatabaseAccessor::IteratorContextPtr srcContext =
+ DatabaseAccessor::IteratorContextPtr());
+ /// \brief DNSSEC related context for ZoneFinder::findInternal.
+ ///
+ /// This class is a helper for the ZoneFinder::findInternal method,
+ /// encapsulating DNSSEC related information and processing logic.
+ /// Specifically, it tells the finder whether the zone under search
+ /// is DNSSEC signed or not, and if it is, whether it's with NSEC or
+ /// with NSEC3. It also provides a RRset DNSSEC proof RRset for some
+ /// specific situations (in practice, this means an NSEC RRs for
+ /// negative proof when they are needed and expected).
+ ///
+ /// The purpose of this class is to keep the main finder implementation
+ /// unaware of DNSSEC related details. It's also intended to help
+ /// avoid unnecessary lookup for DNSSEC proof RRsets; this class
+ /// doesn't look into the DB for these RRsets unless it's known to
+ /// be needed. The same optimization could be implemented in the
+ /// main code, but it will result in duplicate similar code logic
+ /// and make the code more complicated. By encapsulating and unifying
+ /// the logic in a single separate class, we can keep the main
+ /// search logic readable.
+ class FindDNSSECContext {
+ public:
+ /// \brief Constructor for FindDNSSECContext class.
+ ///
+ /// This constructor doesn't involve any expensive operation such
+ /// as database lookups. It only initializes some internal
+ /// states (in a cheap way) and remembers if DNSSEC proof
+ /// is requested.
+ ///
+ /// \param finder The Finder for the findInternal that uses this
+ /// context.
+ /// \param options Find options given to the finder.
+ FindDNSSECContext(Finder& finder, const FindOptions options);
+
+ /// \brief Return DNSSEC related result flags for the context.
+ ///
+ /// This method returns a FindResultFlags value related to
+ /// DNSSEC, based on the context. If DNSSEC proof is requested
+ /// and the zone is signed with NSEC/NSEC3, it returns
+ /// RESULT_NSEC_SIGNED/RESULT_NSEC3_SIGNED, respectively;
+ /// otherwise it returns RESULT_DEFAULT. So the caller can simply
+ /// take a logical OR for the returned value of this method and
+ /// whatever other flags it's going to set, without knowing
+ /// DNSSEC specific information.
+ ///
+ /// If it's not yet identified whether and how the zone is DNSSEC
+ /// signed at the time of the call, it now detects that via
+ /// database lookups (if necessary). (And this is because why
+ /// this method cannot be a const member function).
+ ZoneFinder::FindResultFlags getResultFlags();
+
+ /// \brief Get DNSSEC negative proof for a given name.
+ ///
+ /// If the zone is considered NSEC-signed and the context
+ /// requested DNSSEC proofs, this method tries to find NSEC RRs
+ /// for the give name. If \c covering is true, it means a
+ /// "no name" proof is requested, so it calls findPreviousName on
+ /// the given name and extracts an NSEC record on the result;
+ /// otherwise it tries to get NSEC RRs for the given name. If
+ /// the NSEC is found, this method returns it; otherwise it returns
+ /// NULL.
+ ///
+ /// In all other cases this method simply returns NULL.
+ ///
+ /// \param name The name which the NSEC RRset belong to.
+ /// \param covering true if a covering NSEC is required; false if
+ /// a matching NSEC is required.
+ /// \return Any found DNSSEC proof RRset or NULL
+ isc::dns::ConstRRsetPtr getDNSSECRRset(
+ const isc::dns::Name& name, bool covering);
+
+ /// \brief Get DNSSEC negative proof for a given name.
+ ///
+ /// If the zone is considered NSEC-signed and the context
+ /// requested DNSSEC proofs, this method tries to find NSEC RRset
+ /// from the given set (\c found_set) and returns it if found;
+ /// in other cases this method simply returns NULL.
+ ///
+ /// \param found_set The RRset which may contain an NSEC RRset.
+ /// \return Any found DNSSEC proof RRset or NULL
+ isc::dns::ConstRRsetPtr getDNSSECRRset(const FoundRRsets&
+ found_set);
+
+ private:
+ /// \brief Returns whether the zone is signed with NSEC3.
+ ///
+ /// This method returns true if the zone for the finder that
+ /// uses this context is considered DNSSEC signed with NSEC3;
+ /// otherwise it returns false. If it's not yet detected,
+ /// this method now detects that via database lookups (if
+ /// necessary).
+ bool isNSEC3();
+
+ /// \brief Returns whether the zone is signed with NSEC.
+ ///
+ /// This is similar to isNSEC3(), but works for NSEC.
+ bool isNSEC();
+
+ /// \brief Probe into the database to see if/how the zone is
+ /// signed.
+ ///
+ /// This is a subroutine of isNSEC3() and isNSEC(), and performs
+ /// delayed database probe to detect whether the zone used by
+ /// the finder is DNSSEC signed, and if it is, with NSEC or NSEC3.
+ void probe();
+
+ DatabaseClient::Finder& finder_;
+ const bool need_dnssec_;
+
+ bool is_nsec3_;
+ bool is_nsec_;
+ bool probed_;
+ };
+
/// \brief Search result of \c findDelegationPoint().
///
/// This is a tuple combining the result of the search - a status code