Commit 2e12dd60 authored by Stephen Morris's avatar Stephen Morris
Browse files

[1198] Extracted search for delegation point into a separate method.

parent 24c2111e
......@@ -14,6 +14,7 @@
#include <string>
#include <vector>
#include <iostream>
#include <datasrc/database.h>
#include <datasrc/data_source.h>
......@@ -389,55 +390,55 @@ DatabaseClient::Finder::findNSECCover(const Name& name) {
return (RRsetPtr());
}
ZoneFinder::FindResult
DatabaseClient::Finder::find(const isc::dns::Name& name,
const isc::dns::RRType& type,
isc::dns::RRsetList*,
const FindOptions options)
{
// This variable is used to determine the difference between
// NXDOMAIN and NXRRSET
bool records_found = false;
bool glue_ok((options & FIND_GLUE_OK) != 0);
const bool dnssec_data((options & FIND_DNSSEC) != 0);
bool get_cover(false);
DatabaseClient::Finder::DelegationSearchResult
DatabaseClient::Finder::findDelegationPoint(const isc::dns::Name& name,
const FindOptions options) {
// Result of search
isc::dns::RRsetPtr result_rrset;
ZoneFinder::Result result_status = SUCCESS;
FoundRRsets found;
logger.debug(DBG_TRACE_DETAILED, DATASRC_DATABASE_FIND_RECORDS)
.arg(accessor_->getDBName()).arg(name).arg(type);
// In case we are in GLUE_OK mode and start matching wildcards,
// we can't do it under NS, so we store it here to check
isc::dns::RRsetPtr first_ns;
// Are we searching for glue?
bool glue_ok((options & FIND_GLUE_OK) != 0);
// First, do we have any kind of delegation (NS/DNAME) here?
const Name origin(getOrigin());
const size_t origin_label_count(origin.getLabelCount());
// Number of labels in the last known non-empty domain
size_t last_known(origin_label_count);
const size_t current_label_count(name.getLabelCount());
// This is how many labels we remove to get origin
const size_t remove_labels(current_label_count - origin_label_count);
// Now go trough all superdomains from origin down
for (int i(remove_labels); i > 0; --i) {
// Go through all superdomains from the origin down searching for nodes
// that indicate a delegation (NS or DNAME).
for (int i = remove_labels; i > 0; --i) {
Name superdomain(name.split(i));
// Note if this is the origin.
bool not_origin = (i != remove_labels);
// Look if there's NS or DNAME (but ignore the NS in origin)
found = getRRsets(superdomain.toText(), DELEGATION_TYPES(),
i != remove_labels);
FoundRRsets found = getRRsets(superdomain.toText(), DELEGATION_TYPES(),
not_origin);
if (found.first) {
// It contains some RRs, so it exists.
last_known = superdomain.getLabelCount();
const FoundIterator nsi(found.second.find(RRType::NS()));
const FoundIterator dni(found.second.find(RRType::DNAME()));
// In case we are in GLUE_OK mode, we want to store the
// highest encountered NS (but not apex)
if (glue_ok && !first_ns && i != remove_labels &&
nsi != found.second.end()) {
if (glue_ok && !first_ns && not_origin && nsi != found.second.end()) {
first_ns = nsi->second;
} else if (!glue_ok && i != remove_labels &&
nsi != found.second.end()) {
} else if (!glue_ok && not_origin && nsi != found.second.end()) {
// Do a NS delegation, but ignore NS in glue_ok mode. Ignore
// delegation in apex
LOG_DEBUG(logger, DBG_TRACE_DETAILED,
......@@ -447,6 +448,7 @@ DatabaseClient::Finder::find(const isc::dns::Name& name,
result_status = DELEGATION;
// No need to go lower, found
break;
} else if (dni != found.second.end()) {
// Very similar with DNAME
LOG_DEBUG(logger, DBG_TRACE_DETAILED,
......@@ -463,6 +465,46 @@ DatabaseClient::Finder::find(const isc::dns::Name& name,
}
}
}
return (DelegationSearchResult(result_status, result_rrset, first_ns,
last_known));
}
ZoneFinder::FindResult
DatabaseClient::Finder::find(const isc::dns::Name& name,
const isc::dns::RRType& type,
isc::dns::RRsetList*,
const FindOptions options)
{
// This variable is used to determine the difference between
// NXDOMAIN and NXRRSET
bool records_found = false;
bool glue_ok((options & FIND_GLUE_OK) != 0);
const bool dnssec_data((options & FIND_DNSSEC) != 0);
bool get_cover(false);
isc::dns::RRsetPtr result_rrset;
ZoneFinder::Result result_status = SUCCESS;
FoundRRsets found;
logger.debug(DBG_TRACE_DETAILED, DATASRC_DATABASE_FIND_RECORDS)
.arg(accessor_->getDBName()).arg(name).arg(type);
// First, do we have any kind of delegation (NS/DNAME) here?
const Name origin(getOrigin());
// Number of labels in the last known non-empty domain
const size_t current_label_count(name.getLabelCount());
// This is how many labels we remove to get origin
//const size_t remove_labels(current_label_count - origin_label_count);
// First stage: go throught all superdomains from the origin down,
// searching for nodes that indicate a delegation (NS or DNAME).
DelegationSearchResult dresult = findDelegationPoint(name, options);
result_status = dresult.code;
result_rrset = dresult.rrset;
// In case we are in GLUE_OK mode and start matching wildcards,
// we can't do it under NS, so we store it here to check
isc::dns::RRsetPtr first_ns = dresult.first_ns;
size_t last_known = dresult.last_known;
if (!result_rrset) { // Only if we didn't find a redirect already
// Try getting the final result and extract it
......
......@@ -18,6 +18,7 @@
#include <string>
#include <boost/scoped_ptr.hpp>
#include <boost/tuple/tuple.hpp>
#include <dns/rrclass.h>
#include <dns/rrclass.h>
......@@ -814,6 +815,40 @@ public:
const DatabaseAccessor& getAccessor() const {
return (*accessor_);
}
/// \brief Search result of \c findDelegationPoint().
///
/// This is a tuple combining the result of the search - a status code
/// and a pointer to the RRset found - together with additional
/// information needed for subsequent processing, an indication of
/// the first NS RRset found in the search and the number of labels
/// in the last non-empty domain encountered in the search. It is
/// used by \c findDelegationPoint().
///
/// The last two items are located naturally in the search and although
/// not strictly part of the result, they are passed back to avoid
/// another (duplicate) search later in the processing.
///
/// Note that the code and rrset elements are the same as that in
/// the \c ZoneFinder::FindResult struct: this structure could be
/// derived from that one, but as it is used just once in the code and
/// will never be treated as a \c FindResult, the obscurity involved in
/// deriving it from a parent class was deemed not worthwhile.
struct DelegationSearchResult {
DelegationSearchResult(const ZoneFinder::Result param_code,
const isc::dns::RRsetPtr param_rrset,
const isc::dns::RRsetPtr param_ns,
size_t param_last_known) :
code(param_code), rrset(param_rrset),
first_ns(param_ns),
last_known(param_last_known)
{}
const ZoneFinder::Result code; ///< Result code
const isc::dns::RRsetPtr rrset; ///< Pointer to RRset found
const isc::dns::RRsetPtr first_ns; ///< Pointer to first NS found
const size_t last_known; ///< No. labels in last non-empty domain
};
private:
boost::shared_ptr<DatabaseAccessor> accessor_;
const int zone_id_;
......@@ -824,6 +859,7 @@ public:
FoundRRsets;
/// \brief Just shortcut for set of types
typedef std::set<dns::RRType> WantedTypes;
/**
* \brief Searches database for RRsets of one domain.
*
......@@ -854,6 +890,34 @@ public:
FoundRRsets getRRsets(const std::string& name,
const WantedTypes& types, bool check_ns,
const std::string* construct_name = NULL);
/**
* \brief Find delegation point
*
* Given a name, searches through the superdomains from the origin
* down, searching for a point that indicates a delegation (i.e. an
* NS record or a DNAME).
*
* \param name The name to find
* \param type The RRType to find
* \param target Unused at this moment
* \param options Options about how to search. See
* ZoneFinder::FindOptions.
*
* \return Tuple holding the result of the search - the RRset of the
* delegation point and the type of the point (DELEGATION or
* DNAME) - and associated information. This latter item
* comprises two pieces of data: a pointer to the highest
* encountered NS, and the number of labels in the last known
* non-empty domain. The associated information is found as
* a natural part of the search for the delegation point and
* is used later in the find() processing; it is passed back
* to avoid the need to perform a second search toi obtain it.
*/
DelegationSearchResult
findDelegationPoint(const isc::dns::Name& name,
const FindOptions options = FIND_DEFAULT);
/**
* \brief Checks if something lives below this domain.
*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment