deal with the flag.
-If using git (not the tarball), build the "configure" file:
+f using git (not the tarball), build the "configure" file:
autoreconf --install
To then build from source:
std::vector<isc::dns::ConstRRsetPtr>& target,
const FindOptions options)
{
- const bool need_nsec3 = (((options & FIND_DNSSEC) != 0) && isNSEC3());
- if (need_nsec3 && isNSEC()) {
- isc_throw(DataSourceError, "nsec and nsec3 coexist");
- }
- // If the zone is signed with NSEC3, need to add RESULT_NSEC3_SIGNED to the
- // flags in FindContext when NXRRSET NXDOMAIN or WILDCARD in the DNSSEC
- // query, no need NSEC RRset at the same time.
return (ZoneFinderContextPtr(new Context(*this, options,
findInternal(name, RRType::ANY(),
- &target, options,
- need_nsec3),
+ &target, options),
target)));
}
if (type == RRType::ANY()) {
isc_throw(isc::Unexpected, "Use findAll to answer ANY");
}
- // If the zone is signed with NSEC3, need to add RESULT_NSEC3_SIGNED to the
- // flags in FindContext when NXRRSET NXDOMAIN or WILDCARD in the DNSSEC
- // query, no need NSEC RRset at the same time.
- const bool need_nsec3 = (((options & FIND_DNSSEC) != 0) && isNSEC3());
- if (need_nsec3 && isNSEC()) {
- isc_throw(DataSourceError, "nsec and nsec3 coexist");
- }
return (ZoneFinderContextPtr(new Context(*this, options,
findInternal(name, type, NULL,
- options,
- need_nsec3))));
+ options))));
}
DatabaseClient::Finder::DelegationSearchResult
//
// If none of the above applies in any level, the search fails with NXDOMAIN.
ZoneFinder::ResultContext
-DatabaseClient::Finder::findWildcardMatch(
- const isc::dns::Name& name, const isc::dns::RRType& type,
- const FindOptions options, const DelegationSearchResult& dresult,
- std::vector<isc::dns::ConstRRsetPtr>* target, const bool need_nsec3)
+DatabaseClient::Finder::findWildcardMatch(const isc::dns::Name& name,
+ const isc::dns::RRType& type,
+ const DelegationSearchResult& dresult,
+ std::vector<isc::dns::ConstRRsetPtr>*
+ target, FindDNSSECContext& dnssec_ctx)
{
// Note that during the search we are going to search not only for the
// requested type, but also for types that indicate a delegation -
// NS and DNAME.
- WantedTypes final_types(need_nsec3 ? FINAL_TYPES_NO_NSEC() : FINAL_TYPES());
+ WantedTypes final_types(dnssec_ctx.isNSEC3() ? FINAL_TYPES_NO_NSEC() :
+ FINAL_TYPES());
final_types.insert(type);
const size_t remove_labels = name.getLabelCount() - dresult.last_known;
if (dresult.first_ns) {
// About to use first_ns. The only way this can be set is if
// we are searching for glue, so do a sanity check.
- if ((options & FIND_GLUE_OK) == 0) {
+ if ((dnssec_ctx.getOptions() & FIND_GLUE_OK) == 0) {
isc_throw(Unexpected, "Inconsistent conditions during "
"cancel of wilcard search for " <<
name.toText() << ": find_ns non-null when not "
} 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.
- return (findOnNameResult(name, type, options, false,
- found, &wildcard, target, need_nsec3));
+ return (findOnNameResult(name, type, found, &wildcard,
+ target, dnssec_ctx));
} else {
// more specified match found, cancel wildcard match
LOG_DEBUG(logger, DBG_TRACE_DETAILED,
DATASRC_DATABASE_WILDCARD_EMPTY).
arg(accessor_->getDBName()).arg(wildcard).arg(name);
- if (((options & FIND_DNSSEC) != 0) && !need_nsec3) {
+ FindResultFlags flags = (RESULT_WILDCARD |
+ dnssec_ctx.getResultFlags());
+ if (dnssec_ctx.isNSEC()) {
ConstRRsetPtr nsec = findNSECCover(Name(wildcard));
if (nsec) {
- return (ResultContext(NXRRSET, nsec,
- RESULT_WILDCARD |
- RESULT_NSEC_SIGNED));
+ return (ResultContext(NXRRSET, nsec, flags));
}
}
- return (ResultContext(NXRRSET, ConstRRsetPtr(), need_nsec3 ?
- (RESULT_WILDCARD | RESULT_NSEC3_SIGNED) :
- RESULT_WILDCARD));
+ return (ResultContext(NXRRSET, ConstRRsetPtr(), flags));
}
}
return (ResultContext(code, rrset, flags));
}
+DatabaseClient::Finder::FindDNSSECContext::FindDNSSECContext(
+ DatabaseClient::Finder* finderp,
+ const isc::datasrc::ZoneFinder::FindOptions options,
+ const Name& origin) :
+ finderp_(finderp),
+ options_(options),
+ origin_(origin),
+ initialized_(false)
+{}
+
+ZoneFinder::FindOptions
+DatabaseClient::Finder::FindDNSSECContext::getOptions() const
+{
+ return options_;
+}
+
+void
+DatabaseClient::Finder::FindDNSSECContext::init()
+{
+ if (finderp_ == NULL) {
+ isc_throw(DataSourceError, "no Finder to query");
+ }
+ if (!initialized_) {
+ initialized_ = true;
+ // If NSEC3PARAM rrset exists, the zone looks like signed with NSEC3
+ is_nsec3_ = ((options_ & FIND_DNSSEC) == 0) ? false :
+ finderp_->isNSEC3();
+ if (is_nsec3_) {
+ // If the zone is signed with NSEC3, no need to check NSEC. If NSEC
+ // and NSEC3 coexist, according to RFC 5155 10-4, it should return
+ // result as NSEC3.
+ is_nsec_ = false;
+ } else {
+ // If no NSEC3PARAM and it is DNSSEC query, check whether NSEC
+ // exist in apex of zone
+ is_nsec_ = ((options_ & FIND_DNSSEC) == 0) ? false :
+ finderp_->isNSEC();
+ }
+ }
+}
+
+bool
+DatabaseClient::Finder::FindDNSSECContext::isInited()
+{
+ return initialized_;
+}
+
+bool
+DatabaseClient::Finder::FindDNSSECContext::isNSEC3()
+{
+ if (isInited()) {
+ return is_nsec3_;
+ } else {
+ init();
+ return is_nsec3_;
+ }
+}
+
+bool
+DatabaseClient::Finder::FindDNSSECContext::isNSEC()
+{
+ if (isInited()) {
+ return is_nsec_;
+ } else {
+ init();
+ return is_nsec_;
+ }
+}
+
+isc::dns::ConstRRsetPtr
+DatabaseClient::Finder::FindDNSSECContext::getNSECRRset(
+ const FoundRRsets& found_set) const
+{
+ const FoundIterator nci = found_set.second.find(RRType::NSEC());
+ if (nci != found_set.second.end()) {
+ return nci->second;
+ } else {
+ return ConstRRsetPtr();
+ }
+}
+
+isc::dns::ConstRRsetPtr
+DatabaseClient::Finder::FindDNSSECContext::getNSECRRset(const Name &name) const
+{
+ if (finderp_ == NULL) {
+ isc_throw(DataSourceError, "no Finder to query");
+ }
+ const FoundRRsets wfound = finderp_->getRRsets(name.toText(), NSEC_TYPES(),
+ true);
+ const FoundIterator nci = wfound.second.find(RRType::NSEC());
+ if (nci != wfound.second.end()) {
+ return nci->second;
+ } else {
+ return ConstRRsetPtr();
+ }
+}
+
+DatabaseClient::Finder::FoundRRsets
+DatabaseClient::Finder::FindDNSSECContext::getDNSSECRRset(const Name& name,
+ const RRType& type)
+{
+ if (finderp_ == NULL) {
+ isc_throw(DataSourceError, "no Finder to query");
+ }
+ const bool is_origin = isOrigin(name);
+ bool is_nsec = isNSEC();
+ WantedTypes final_types(is_nsec ? FINAL_TYPES() : FINAL_TYPES_NO_NSEC());
+ final_types.insert(type);
+ return (finderp_->getRRsets(name.toText(), final_types, !is_origin, NULL,
+ type == RRType::ANY()));
+}
+
+bool
+DatabaseClient::Finder::FindDNSSECContext::isOrigin(const Name &name) const
+{
+ return (name == origin_);
+}
+
+ZoneFinder::FindResultFlags
+DatabaseClient::Finder::FindDNSSECContext::getResultFlags()
+{
+ // If it is not DNSSEC query, it should return RESULT_DEFAULT
+ if ((options_ & FIND_DNSSEC) == 0) {
+ return RESULT_DEFAULT;
+ }
+ // If it is a DNSSEC query and the zone is signed with NSEC3, it should
+ // return RESULT_NSEC3_SIGNED
+ if (isNSEC3()) {
+ return RESULT_NSEC3_SIGNED;
+ } else {
+ // If it is a DNSSEC query and the zone is signed with NSEC, it should
+ // return RESULT_NSEC_SIGNED, other else, return RESULT_DEFAULT
+ return (isNSEC() ? RESULT_NSEC_SIGNED : RESULT_DEFAULT);
+ }
+}
+
ZoneFinder::ResultContext
DatabaseClient::Finder::findOnNameResult(const Name& name,
const RRType& type,
- const FindOptions options,
- const bool is_origin,
const FoundRRsets& found,
const string* wildname,
std::vector<isc::dns::ConstRRsetPtr>*
- target, const bool need_nsec3)
+ target, FindDNSSECContext& dnssec_ctx)
{
const bool wild = (wildname != NULL);
- FindResultFlags flags;
- if (need_nsec3) {
- flags = wild ? (RESULT_WILDCARD | RESULT_NSEC3_SIGNED) :
- RESULT_DEFAULT;
- } else {
- flags = wild ? RESULT_WILDCARD : RESULT_DEFAULT;
+ FindResultFlags flags = wild ? RESULT_WILDCARD : RESULT_DEFAULT;
+ // If the zone file is signed with NSEC3, need to set RESULT_NSEC3_SIGNED
+ // flag in the flags. It is good for upper caller to deal with the query
+ // response message.
+ if (wild & dnssec_ctx.isNSEC3()) {
+ flags = (flags | RESULT_NSEC3_SIGNED);
}
// Get iterators for the different types of records we are interested in -
// CNAME, NS and Wanted types.
// For wildcard case with DNSSEC required, the caller would need to know
// whether it's NSEC or NSEC3 signed. So we need to do an additional
// search here, even though the NSEC RR may not be returned.
- // TODO: this part should be revised when we support NSEC3; ideally we
- // should use more effective and efficient way to identify (whether and)
- // in which way the zone is signed.
- if (wild && (options & FIND_DNSSEC) != 0 && !need_nsec3 &&
+ if (wild && dnssec_ctx.isNSEC() &&
found.second.find(RRType::NSEC()) != found.second.end()) {
- flags = flags | RESULT_NSEC_SIGNED;
+ flags = (flags | RESULT_NSEC_SIGNED);
}
- if (!is_origin && ((options & FIND_GLUE_OK) == 0) &&
+ if (!dnssec_ctx.isOrigin(name) &&
+ ((dnssec_ctx.getOptions() & FIND_GLUE_OK) == 0) &&
nsi != found.second.end()) {
// A NS RRset was found at the domain we were searching for. As it is
// not at the origin of the zone, it is a delegation and indicates that
// NSEC records in the name of the wildcard, not the substituted one,
// so we need to search the tree again.
ConstRRsetPtr nsec_rrset; // possibly used with DNSSEC, otherwise NULL
- if ((options & FIND_DNSSEC) != 0 && !need_nsec3) {
- if (wild) {
- const FoundRRsets wfound = getRRsets(*wildname, NSEC_TYPES(),
- true);
- const FoundIterator nci = wfound.second.find(RRType::NSEC());
- if (nci != wfound.second.end()) {
- nsec_rrset = nci->second;
- }
- } else {
- const FoundIterator nci = found.second.find(RRType::NSEC());
- if (nci != found.second.end()) {
- nsec_rrset = nci->second;
- }
- }
+ if (dnssec_ctx.isNSEC()) {
+ nsec_rrset = wild ? dnssec_ctx.getNSECRRset(Name(*wildname)) :
+ dnssec_ctx.getNSECRRset(found);
}
if (nsec_rrset) {
// This log message covers both normal and wildcard cases, so we pass
// NULL for 'wildname'.
return (logAndCreateResult(name, NULL, type, NXRRSET, nsec_rrset,
DATASRC_DATABASE_FOUND_NXRRSET_NSEC,
- flags | RESULT_NSEC_SIGNED));
+ (flags | RESULT_NSEC_SIGNED)));
}
return (logAndCreateResult(name, wildname, type, NXRRSET, nsec_rrset,
wild ? DATASRC_DATABASE_WILDCARD_NXRRSET :
- DATASRC_DATABASE_FOUND_NXRRSET, need_nsec3 ?
- (flags | RESULT_NSEC3_SIGNED) : flags));
+ DATASRC_DATABASE_FOUND_NXRRSET,
+ (flags | dnssec_ctx.getResultFlags())));
}
ZoneFinder::ResultContext
DatabaseClient::Finder::findNoNameResult(const Name& name, const RRType& type,
- FindOptions options,
const DelegationSearchResult& dresult,
std::vector<isc::dns::ConstRRsetPtr>*
- target, const bool need_nsec3)
+ target, FindDNSSECContext& dnssec_ctx)
{
- const bool dnssec_data = ((options & FIND_DNSSEC) != 0);
- const bool need_nsec = (dnssec_data && !need_nsec3);
// On entry to this method, we know that the database doesn't have any
// entry for this name. Before returning NXDOMAIN, we need to check
// for special cases.
if (hasSubdomains(name.toText())) {
- // Does the domain have a subdomain (i.e. it is an empty non-terminal)?
+ // Does the domain have a subdomain (i.e. it is an empty non-terminal)
// If so, return NXRRSET instead of NXDOMAIN (as although the name does
// not exist in the database, it does exist in the DNS tree).
LOG_DEBUG(logger, DBG_TRACE_DETAILED,
DATASRC_DATABASE_FOUND_EMPTY_NONTERMINAL).
arg(accessor_->getDBName()).arg(name);
- const ConstRRsetPtr nsec = need_nsec ? findNSECCover(name) :
+ const ConstRRsetPtr nsec = dnssec_ctx.isNSEC() ? findNSECCover(name) :
ConstRRsetPtr();
- return (ResultContext(NXRRSET, nsec, nsec ? RESULT_NSEC_SIGNED :
- (need_nsec3 ? RESULT_NSEC3_SIGNED : RESULT_DEFAULT)));
- } else if ((options & NO_WILDCARD) == 0) {
+ if(dnssec_ctx.isNSEC() && (!nsec)){
+ isc_throw(DataSourceError,
+ "no NSEC RR covers in the NSEC signed zone");
+ }
+ return (ResultContext(NXRRSET, nsec, dnssec_ctx.getResultFlags()));
+ } else if ((dnssec_ctx.getOptions() & 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 ResultContext wcontext =
- findWildcardMatch(name, type, options, dresult, target,
- need_nsec3);
+ findWildcardMatch(name, type, dresult, target, dnssec_ctx);
if (wcontext.code != NXDOMAIN) {
return (wcontext);
}
// NSEC records if requested).
LOG_DEBUG(logger, DBG_TRACE_DETAILED, DATASRC_DATABASE_NO_MATCH).
arg(accessor_->getDBName()).arg(name).arg(type).arg(getClass());
- const ConstRRsetPtr nsec = need_nsec ? findNSECCover(name) :
+ const ConstRRsetPtr nsec = dnssec_ctx.isNSEC() ? findNSECCover(name) :
ConstRRsetPtr();
- return (ResultContext(NXDOMAIN, nsec,
- nsec ? RESULT_NSEC_SIGNED : (need_nsec3 ?
- RESULT_NSEC3_SIGNED : RESULT_DEFAULT)));
+ if(dnssec_ctx.isNSEC() && (!nsec)){
+ isc_throw(DataSourceError, "no NSEC RR covers in the NSEC signed zone");
+ }
+ return (ResultContext(NXDOMAIN, nsec, dnssec_ctx.getResultFlags()));
}
bool
bool
DatabaseClient::Finder::isNSEC() {
- // If an NSEC RRsets exists at the zone apex, it's quite likely that
- // the zone is signed with NSEC. (If not the zone is more or less broken,
- // but it's caller's responsibility how to handle such cases)
+ // If an NSEC RR exists at the zone apex, it's quite likely that
+ // the zone is signed with NSEC. (If not the zone is more or less broken,
+ // but it's caller's responsibility how to handle such cases).
const FoundRRsets nsec_found = getRRsets(origin_.toText(),
NSEC_TYPES(), false);
const FoundIterator nfi(nsec_found.second.find(RRType::NSEC()));
ZoneFinder::ResultContext
DatabaseClient::Finder::findInternal(const Name& name, const RRType& type,
std::vector<ConstRRsetPtr>* target,
- const FindOptions options,
- const bool is_nsec3)
+ const FindOptions options)
{
LOG_DEBUG(logger, DBG_TRACE_DETAILED, DATASRC_DATABASE_FIND_RECORDS)
.arg(accessor_->getDBName()).arg(name).arg(type).arg(getClass());
// - Requested name is a delegation point (NS only but not at the zone
// apex - DNAME is ignored here as it redirects DNS names subordinate to
// the owner name - the owner name itself is not redirected.)
- const bool is_origin = (name == getOrigin());
- WantedTypes final_types(is_nsec3 ? FINAL_TYPES_NO_NSEC() : FINAL_TYPES());
- final_types.insert(type);
- const FoundRRsets found = getRRsets(name.toText(), final_types,
- !is_origin, NULL,
- type == RRType::ANY());
+ FindDNSSECContext dnssec_ctx(this, options, getOrigin());
+ const FoundRRsets found = dnssec_ctx.getDNSSECRRset(name, type);
if (found.first) {
// Something found at the domain name. Look into it further to get
// the final result.
- return (findOnNameResult(name, type, options, is_origin, found,
- NULL, target, is_nsec3));
+ return (findOnNameResult(name, type, found, NULL, target, dnssec_ctx));
} else {
// Did not find anything at all at the domain name, so check for
// subdomains or wildcards.
- return (findNoNameResult(name, type, options, dresult, target,
- is_nsec3));
+ return (findNoNameResult(name, type, dresult, target, dnssec_ctx));
}
}
DatabaseClient(isc::dns::RRClass rrclass,
boost::shared_ptr<DatabaseAccessor> accessor);
+
/// \brief Corresponding ZoneFinder implementation
///
/// The zone finder implementation for database data sources. Similarly
///
/// Methods directly corresponds to the ones in ZoneFinder.
class Finder : public ZoneFinder {
- public:
+
+ /// \brief Helper to the findInterval.
+ ///
+ /// Get the ResultFlags for findInterval. If the zone is signed with
+ /// NSEC3, it will return RESULT_NSEC3_SIGNED. If it is signed with
+ /// NSEC, it wll return RESULT_NSEC_SIGNED. Other else it will return
+ /// RESULT_DEFAULT. It wraps getRRsets function to do some special
+ /// search, like searching NSEC RRset by getNSECRRset function,
+ /// searching DNSSEC related RRset and RRsig by getNSECRRset.
+ class FindDNSSECContext{
+ public:
+
+ /// \brief Constructor for FindDNSSECContext class.
+ ///
+ /// It initalize a helper for findInterval function.
+ ///
+ /// \param finderp The Finder piont for search.
+ /// \param options Search options.
+ /// \param origin The origin name for this finder.
+ FindDNSSECContext(Finder* finderp, const FindOptions options,
+ const isc::dns::Name& origin);
+
+ /// \brief Get result flags of this query.
+ /// \return ResultFlags for this query. If the zone file is
+ /// signed with NSEC, is will return RESULT_NSEC_SIGNED with
+ /// dnssec query. If the zone file is signed with NSEC3, it
+ /// will return RESULT_NSEC3_SIGNED with dnssec query, others
+ /// it should return RESULT_DEFAULT.
+ ZoneFinder::FindResultFlags getResultFlags();
+
+ typedef std::pair<bool, std::map<dns::RRType, dns::RRsetPtr> >
+ FoundRRsets;
+ /// \brief Get DNSSEC RRset for the queried name.
+ ///
+ /// It should return the RRsets and RRsigs for the queried
+ /// name with designated type.
+ ///
+ /// \param name The queried name.
+ /// \param type The queried type.
+ /// \return RRsets and RRsigs that are matched.
+ FoundRRsets getDNSSECRRset(const isc::dns::Name& name,
+ const isc::dns::RRType& type);
+
+ /// \brief Get the needed NSEC RRset.
+ ///
+ /// It should return the needed NSEC RRset.
+ ///
+ /// \param name The name which the NSEC RRset belong to.
+ /// \return the needed NSEC RRsets.
+ isc::dns::ConstRRsetPtr getNSECRRset(const isc::dns::Name&
+ name) const;
+
+ /// \brief Get the needed NSEC RRset.
+ ///
+ /// It should return the needed NSEC RRset.
+ ///
+ /// \param found_set The RRset which contain the NSEC an other
+ /// type RRs.
+ /// \return the needed NSEC RRsets.
+ isc::dns::ConstRRsetPtr getNSECRRset(const FoundRRsets&
+ found_set) const;
+
+ /// \brief Check whether the zone file is signed with NSECi3.
+ ///
+ /// It checks whether the zone file is signed with NSEC3. If
+ /// yes, return true, other else return false.
+ ///
+ /// \return True for NSEC3, false for other else.
+ bool isNSEC3();
+
+ /// \brief Check whether the zone file is signed with NSEC.
+ ///
+ /// It checks whether the zone file is signed with NSEC, If
+ /// yes, return true, other else return false.
+ ///
+ /// \return True for NSEC, false for other else.
+ bool isNSEC();
+
+ /// \brief Check whether the name is origin name of the zone.
+ ///
+ /// It checks whether the name is origin name of the zone. Yes
+ /// for the origin name, false for not.
+ ///
+ /// \param name The queried name.
+ /// \return True for origin name, false for not.
+ bool isOrigin(const isc::dns::Name& name) const;
+
+ /// \brief get the options of queried.
+ ///
+ /// It return the queried options.
+ ///
+ /// \return It return the queried options.
+ ZoneFinder::FindOptions getOptions() const;
+ private:
+
+ /// \brief Init the attributes in this entity.
+ ///
+ /// It should init the attributes of this entity. Check whether
+ /// it is the NSEC or NSEC3 zone file if it is a dnssec query.
+ ///
+ /// \note If the entity is initalized, no need to init it again.
+ void init();
+
+ /// \brief Check whether the entity is initalized.
+ ///
+ /// It should return true if the entity is inited, else return
+ /// false.
+ ///
+ /// \return True for inited, else return false.
+ bool isInited();
+ DatabaseClient::Finder* finderp_;
+ ZoneFinder::ZoneFinder::FindOptions options_;
+ FindResultFlags flags_;
+ isc::dns::Name origin_;
+ bool is_nsec3_;
+ bool is_nsec_;
+ bool initialized_;
+ };
+
+ public:
/// \brief Constructor
///
/// \param database The database (shared with DatabaseClient) to
virtual isc::dns::Name getOrigin() const;
virtual isc::dns::RRClass getClass() const;
-
- /// \brief check whether zone is signed with nsec3
- ///
- /// searches the NSEC3PARAM RRset in the zone apex, if it exists, the
- /// zone looks signed with nsec3
- bool isNSEC3();
-
- /// \brief check whether zone is signed with nsec
- ///
- /// searches the NSEC RRset in the zone apex, if it exists, the
- /// zone looks signed with nsec
- bool isNSEC();
-
/// \brief Find an RRset in the datasource
///
/// Searches the datasource for an RRset of the given name and
return (*accessor_);
}
+ /// \brief check whether zone is signed with nsec
+ ///
+ /// searches the NSEC3PARAM RRset in the zone apex, if it exists, the
+ /// zone looks signed with nsec
+ bool isNSEC();
+ /// \brief check whether zone is signed with nsec3
+ ///
+ /// searches the NSEC3PARAM RRset in the zone apex, if it exists, the
+ /// zone looks signed with nsec3
+ bool isNSEC3();
+
private:
boost::shared_ptr<DatabaseAccessor> accessor_;
const int zone_id_;
const isc::dns::Name origin_;
+
/// \brief Shortcut name for the result of getRRsets
typedef std::pair<bool, std::map<dns::RRType, dns::RRsetPtr> >
FoundRRsets;
const isc::dns::RRType& type,
std::vector<isc::dns::ConstRRsetPtr>*
target,
- const FindOptions options = FIND_DEFAULT,
- const bool need_nsec3 = false);
-
+ const FindOptions options = FIND_DEFAULT);
+ public:
/// \brief Searches database for RRsets of one domain.
///
/// This method scans RRs of single domain specified by name and
const std::string* construct_name = NULL,
bool any = false);
+ private:
/// \brief Search result of \c findDelegationPoint().
///
/// This is a tuple combining the result of the search - a status code
///
/// \param name The name to find
/// \param type The RRType to find
- /// \param options Options about how to search. See the documentation
- /// for ZoneFinder::FindOptions.
/// \param dresult Result of the search through the zone for a
/// delegation.
/// \param target If the type happens to be ANY, it will insert all
/// the RRsets of the found name (if any is found) here instead
/// of being returned by the result.
- /// \param need_nsec3 When zone is signed with nsec3, no need to find
- /// nsec rrset
+ /// \param dnssec_ctx The dnssec context, it is a DNSSEC wrapper for
+ /// find function.
/// \return Tuple holding the result of the search - the RRset of the
/// wildcard records matching the name, together with a status
/// indicating the match type (e.g. CNAME at the wildcard
/// 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.
- ResultContext findWildcardMatch(
- const isc::dns::Name& name,
- const isc::dns::RRType& type,
- const FindOptions options,
- const DelegationSearchResult& dresult,
- std::vector<isc::dns::ConstRRsetPtr>* target,
- const bool need_nsec3);
+ ResultContext findWildcardMatch(const isc::dns::Name& name,
+ const isc::dns::RRType& type,
+ const DelegationSearchResult& dresult,
+ std::vector<isc::dns::ConstRRsetPtr>*
+ target, FindDNSSECContext& dnssec_ctx);
/// \brief Handle matching results for name
///
///
/// \param name The name to find
/// \param type The RRType to find
- /// \param options Options about how to search. See the documentation
- /// for ZoneFinder::FindOptions.
- /// \param is_origin If name is the zone's origin name.
/// \param found A set of found RRsets in the search for the name
/// and type. It could contain one or more of the requested
/// type, CNAME, NS, and NSEC RRsets of the name.
/// it's NULL in the case of non wildcard match.
/// \param target When the query is any, this must be set to a vector
/// where the result will be stored.
- /// \param need_nsec3 When zone is signed with nsec3, no need to find
- /// nsec rrset
+ /// \param dnssec_ctx The dnssec context, it is a DNSSEC wrapper for
+ /// find function.
+
/// \return Tuple holding the result of the search - the RRset of the
/// wildcard records matching the name, together with a status
/// indicating the match type (corresponding to the each of
/// method.
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, const bool need_nsec3);
+ target, FindDNSSECContext& dnssec_ctx);
/// \brief Handle no match for name
///
/// \param target If the query is for type ANY, the successfull result,
/// if there happens to be one, will be returned through the
/// parameter, as it doesn't fit into the result.
- /// \param need_nsec3 When zone is signed with nsec3, no need to find
- /// nsec rrset
+ /// \param dnssec_ctx The dnssec context, it is a DNSSEC wrapper for
+ /// find function.
/// \return Tuple holding the result of the search - the RRset of the
/// wildcard records matching the name, together with a status
/// indicating the match type (e.g. CNAME at the wildcard
/// success due to an exact match).
ResultContext findNoNameResult(const isc::dns::Name& name,
const isc::dns::RRType& type,
- FindOptions options,
const DelegationSearchResult& dresult,
std::vector<isc::dns::ConstRRsetPtr>*
- targeti, const bool need_nsec3);
+ target, FindDNSSECContext& dnssec_ctx);
/// Logs condition and creates result
///
/// To find stuff in the result of getRRsets.
typedef std::map<dns::RRType, dns::RRsetPtr>::const_iterator
FoundIterator;
+
+
};
/// \brief Find a zone in the database
Name("*.wild.example.org"), ZoneFinder::FIND_DNSSEC);
}
-TYPED_TEST(DatabaseClientTest, dbNegativeCaseFind) {
- // ZoneFinder::find() for negative cases should show whether the zone is
- // signed with NSEC or NSEC3, that is good for upper layer caller.
+TYPED_TEST(DatabaseClientTest, nsec3FlagFindDB) {
+ // ZoneFinder::find() for negative cases and wildcard cases should check
+ // whether the zone is signed with NSEC or NSEC3. If it is signed with
+ // NSEC3, RESULT_NSEC3_SIGNED flag should be returned. That is good for
+ // upper layer caller.
- // First off, everything should be okay if no NSEC3PARAM rrset
+ // First off, everything should be okay if no NSEC3PARAM rrset. If
+ // NSEC3PARAM RRset doesn't exist and NSEC RRset exist at apex, it looks
+ // like signed with NSEC, and the RESULT_NSEC_SIGNED flag should be return.
+
+ // Check NXDOMAIN case in NSEC signed zone, and RESULT_NSEC_SIGNED flag
+ // should be returned to upper layer caller.
this->expected_rdatas_.clear();
this->expected_sig_rdatas_.clear();
this->expected_rdatas_.push_back("www2.example.org. A AAAA NSEC RRSIG");
ZoneFinder::NXDOMAIN, this->expected_rdatas_,
this->expected_sig_rdatas_, ZoneFinder::RESULT_NSEC_SIGNED,
Name("www.example.org."), ZoneFinder::FIND_DNSSEC);
+
+ // Check NXRRSET case in NSEC signed zone, and RESULT_NSEC_SIGNED flag
+ // should be return.
this->expected_rdatas_.clear();
this->expected_sig_rdatas_.clear();
this->expected_rdatas_.push_back("www2.example.org. A AAAA NSEC RRSIG");
"20000201000000 12345 example.org. "
"FAKEFAKEFAKE");
doFindTest(*finder, isc::dns::Name("www.example.org."),
- isc::dns::RRType::TXT(), isc::dns::RRType::NSEC(),
- this->rrttl_, ZoneFinder::NXRRSET,
- this->expected_rdatas_, this->expected_sig_rdatas_,
- ZoneFinder::RESULT_NSEC_SIGNED, isc::dns::Name::ROOT_NAME(),
- ZoneFinder::FIND_DNSSEC);
+ isc::dns::RRType::TXT(), isc::dns::RRType::NSEC(), this->rrttl_,
+ ZoneFinder::NXRRSET, this->expected_rdatas_,
+ this->expected_sig_rdatas_, ZoneFinder::RESULT_NSEC_SIGNED,
+ isc::dns::Name::ROOT_NAME(), ZoneFinder::FIND_DNSSEC);
+
+ // Check wildcase cases, and the RESULT_NSEC_SIGNED should be return.
this->expected_rdatas_.clear();
this->expected_sig_rdatas_.clear();
this->expected_rdatas_.push_back("192.0.2.5");
this->expected_sig_rdatas_,
(ZoneFinder::RESULT_WILDCARD | ZoneFinder::RESULT_NSEC_SIGNED),
Name("*.wild.example.org"), ZoneFinder::FIND_DNSSEC);
- this->updater_ = this->client_->getUpdater(this->zname_, false);
- this->rrset_.reset(new RRset(this->zname_, this->qclass_,
- isc::dns::RRType::NSEC3PARAM(), this->rrttl_));
- this->rrset_->addRdata(rdata::createRdata(isc::dns::RRType::NSEC3PARAM(),
- this->rrset_->getClass(), "1 0 12 aabbccdd"));
- this->updater_->addRRset(*this->rrset_);
- this->updater_->commit();
- try {
- this->expected_rdatas_.clear();
- this->expected_sig_rdatas_.clear();
- doFindTest(this->updater_->getFinder(), Name("www1.example.org."),
- this->qtype_, this->qtype_, this->rrttl_,
- ZoneFinder::NXDOMAIN, this->expected_rdatas_,
- this->expected_sig_rdatas_, ZoneFinder::RESULT_NSEC3_SIGNED,
- Name::ROOT_NAME(), ZoneFinder::FIND_DNSSEC);
- } catch (const DataSourceError&) {}
- // The following test should be tested in zone which is signed by NSEC3
-#if 0
- // Then, if NSEC3PARAM exists at the origin, the flags of result should
+
+ // Then, if NSEC3PARAM exists at the apex, the flags of result should
// contain RESULT_NSEC3_SIGNED flag when NXDOMAIN NXRRSET or wildcard
+ // cases.
// Add NSEC3PARAM RRSET at the apex of the zone. It looks weird if the
// zone only has NSEC3PARM RRset (but no NSEC3s), but it is okay for unit
this->rrset_->getClass(),
"1 0 12 aabbccdd"));
this->updater_->addRRset(*this->rrset_);
- // check NXDOMAIN
+
+ // check NXDOMAIN, it should set RESULT_NSEC3_SIGNED in the flags.
this->expected_rdatas_.clear();
this->expected_sig_rdatas_.clear();
- doFindTest(this->updater_->getFinder(),
- isc::dns::Name("www1.example.org."), this->qtype_, this->qtype_,
- this->rrttl_, ZoneFinder::NXDOMAIN, this->expected_rdatas_,
- this->expected_sig_rdatas_, ZoneFinder::RESULT_NSEC3_SIGNED,
- isc::dns::Name::ROOT_NAME(), ZoneFinder::FIND_DNSSEC);
- // check NXRRSET
+ doFindTest(this->updater_->getFinder(), Name("www1.example.org."),
+ this->qtype_, this->qtype_, this->rrttl_, ZoneFinder::NXDOMAIN,
+ this->expected_rdatas_, this->expected_sig_rdatas_,
+ ZoneFinder::RESULT_NSEC3_SIGNED,Name::ROOT_NAME(),
+ ZoneFinder::FIND_DNSSEC);
+
+ // check NXRRSET, it should set RESULT_NSEC3_SIGNED in the flags.
this->expected_rdatas_.clear();
this->expected_sig_rdatas_.clear();
doFindTest(this->updater_->getFinder(), Name("www.example.org."),
RRType::TXT(), RRType::TXT(), this->rrttl_,
ZoneFinder::NXRRSET, this->expected_rdatas_,
this->expected_sig_rdatas_, ZoneFinder::RESULT_NSEC3_SIGNED,
- isc::dns::Name::ROOT_NAME(), ZoneFinder::FIND_DNSSEC);
- // check flags if wildcard matches
+ Name::ROOT_NAME(), ZoneFinder::FIND_DNSSEC);
+
+ // check flags if wildcard matches, it should set RESULT_NSEC3_SIGNED in
+ // the flags.
this->expected_rdatas_.push_back("192.0.2.5");
this->expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 "
"20000201000000 12345 example.org. "
this->expected_rdatas_, this->expected_sig_rdatas_,
ZoneFinder::RESULT_WILDCARD | ZoneFinder::RESULT_NSEC3_SIGNED,
Name::ROOT_NAME(), ZoneFinder::FIND_DNSSEC);
- // check flags if NXRRSET in wildcard case
+
+ // check flags if NXRRSET in wildcard case, it should set
+ // RESULT_NSEC3_SIGNED in the flags.
this->expected_rdatas_.clear();
this->expected_sig_rdatas_.clear();
doFindTest(this->updater_->getFinder(), Name("b.a.wild.example.org"),
RRType::TXT(), RRType::TXT(), this->rrttl_,
ZoneFinder::NXRRSET, this->expected_rdatas_,
this->empty_rdatas_, (ZoneFinder::RESULT_WILDCARD |
- ZoneFinder::RESULT_NSEC3_SIGNED),
- Name::ROOT_NAME(), ZoneFinder::FIND_DNSSEC);
-#endif
+ ZoneFinder::RESULT_NSEC3_SIGNED), Name::ROOT_NAME(),
+ ZoneFinder::FIND_DNSSEC);
}
TYPED_TEST(DatabaseClientTest, NXDOMAIN_NSEC) {
if (!this->is_mock_) {
return; // We don't make the real DB to throw
}
- EXPECT_NO_THROW(doFindTest(*finder,
+ // If the zone is signed with NSEC, find function should throw an error
+ // when no NSEC RRset for NXDOMAIN case.
+ EXPECT_THROW(doFindTest(*finder,
isc::dns::Name("notimplnsec.example.org."),
isc::dns::RRType::TXT(),
isc::dns::RRType::NSEC(), this->rrttl_,
ZoneFinder::NXDOMAIN, this->empty_rdatas_,
this->empty_rdatas_,
ZoneFinder::RESULT_DEFAULT,
- Name::ROOT_NAME(), ZoneFinder::FIND_DNSSEC));
+ Name::ROOT_NAME(), ZoneFinder::FIND_DNSSEC),
+ DataSourceError);
}
TYPED_TEST(DatabaseClientTest, emptyNonterminalNSEC) {
if (!this->is_mock_) {
return; // We don't make the real DB to throw
}
- EXPECT_NO_THROW(doFindTest(*finder,
+ // If the zone is signed with NSEC, find function should throw an error
+ // when no NSEC RRset for NXRRset case
+ EXPECT_THROW(doFindTest(*finder,
isc::dns::Name("here.wild.example.org."),
isc::dns::RRType::TXT(),
isc::dns::RRType::NSEC(),
this->rrttl_, ZoneFinder::NXRRSET,
this->empty_rdatas_, this->empty_rdatas_,
ZoneFinder::RESULT_DEFAULT,
- Name::ROOT_NAME(), ZoneFinder::FIND_DNSSEC));
+ Name::ROOT_NAME(), ZoneFinder::FIND_DNSSEC),
+ DataSourceError);
}
TYPED_TEST(DatabaseClientTest, anyFromFind) {