Commit 243b5644 authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

initial implementation of trac #418:

 - make the zone class inheritable
 - introduced the fine method


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac418@3670 e5f2f494-b856-4b98-b285-d166d9295462
parent ab83eac1
......@@ -35,6 +35,12 @@ TEST(ZoneTest, init) {
EXPECT_EQ(RRClass::CH(), ch_zone.getClass());
}
TEST(ZoneTest, find) {
Zone zone(RRClass::IN(), Name("example.com"));
EXPECT_EQ(AbstractZone::NXDOMAIN,
zone.find(Name("www.example.com"), RRType::A()).code);
}
class ZoneTableTest : public ::testing::Test {
protected:
ZoneTableTest() : zone1(new Zone(RRClass::IN(), Name("example.com"))),
......
......@@ -54,6 +54,12 @@ Zone::getClass() const {
return (impl_->zone_class_);
}
AbstractZone::FindResult
Zone::find(const Name&, const RRType&) const {
// This is a tentative implementation that always returns NXDOMAIN.
return (FindResult(NXDOMAIN, RRsetPtr()));
}
// This is a temporary, inefficient implementation using std::map and handmade
// iteration to realize longest match.
......
......@@ -17,6 +17,8 @@
#include <boost/shared_ptr.hpp>
#include <dns/rrset.h>
namespace isc {
namespace dns {
class Name;
......@@ -25,19 +27,148 @@ class RRClass;
namespace datasrc {
/// \brief A single authoritative zone
/// \brief The base class for a single authoritative zone
///
/// The \c Zone class represents a DNS zone as part of %data source.
/// The \c AbstractZone class is an abstract base class for representing
/// a DNS zone as part of data source.
///
/// At the moment this is provided mainly for making the \c ZoneTable class
/// testable, and only provides a minimal set of features.
/// and the authoritative query logic testable, and only provides a minimal
/// set of features.
/// This is why this class is defined in the same header file, but it may
/// have to move to a separate header file when we understand what is
/// necessary for this class for actual operation.
/// Likewise, it will have more features. For example, it will maintain
///
/// The idea is to provide a specific derived zone class for each data
/// source, beginning with in memory one. At that point the derived classes
/// will have more specific features. For example, they will maintain
/// information about the location of a zone file, whether it's loaded in
/// memory, etc.
class Zone {
class AbstractZone {
public:
/// Result codes of the \c find() method.
///
/// Note: the codes are tentative. We may need more, or we may find
/// some of them unnecessary as we implement more details.
enum Result {
SUCCESS, ///< An exact match is found.
DELEGATION, ///< The search encounters a zone cut.
NXDOMAIN, ///< There is no domain name that matches the search name
NXRRSET, ///< There is a matching name but no RRset of the search type
CNAME, ///< The search encounters and returns a CNAME RR
DNAME ///< The search encounters and returns a DNAME RR
};
/// A helper structure to represent the search result of \c find().
///
/// This is a straightforward tuple of the result code and a pointer
/// to the found RRset to represent the result of \c find()
/// (there will be more members in the future - see the class
/// description).
/// We use this in order to avoid overloading the return value for both
/// the result code ("success" or "not found") and the found object,
/// i.e., avoid using \c NULL to mean "not found", etc.
///
/// This is a simple value class with no internal state, so for
/// convenience we allow the applications to refer to the members
/// directly.
///
/// Note: we should eventually include a notion of "zone node", which
/// corresponds to a particular domain name of the zone, so that we can
/// find RRsets of a different RR type for that name (e.g. for type ANY
/// query or to include DS RRs with delegation).
///
/// Note: we may also want to include the closest enclosure "node" to
/// optimize including the NSEC for no-wildcard proof (FWIW NSD does that).
struct FindResult {
FindResult(Result param_code,
const isc::dns::ConstRRsetPtr param_rrset) :
code(param_code), rrset(param_rrset)
{}
const Result code;
const isc::dns::ConstRRsetPtr rrset;
};
///
/// \name Constructors and Destructor.
///
//@{
protected:
/// The default constructor.
///
/// This is intentionally defined as \c protected as this base class should
/// never be instantiated (except as part of a derived class).
AbstractZone() {}
public:
/// The destructor.
virtual ~AbstractZone() {}
//@}
///
/// \name Getter Methods
///
/// These methods should never throw an exception.
//@{
/// Return the origin name of the zone.
virtual const isc::dns::Name& getOrigin() const = 0;
/// Return the RR class of the zone.
virtual const isc::dns::RRClass& getClass() const = 0;
//@}
///
/// \name Search Method
///
//@{
/// Search the zone for a given pair of domain name and RR type.
///
/// Each derived version of this method searches the underlying backend
/// for the data that best matches the given name and type.
/// This method is expected to be "intelligent", and identifies the
/// best possible answer for the search key. Specifically,
/// - If the search name belongs under a zone cut, it returns the code
/// of \c DELEGATION and the NS RRset at the zone cut.
/// - If there is no matching name, it returns the code of \c NXDOMAIN,
/// and, if DNSSEC is requested, the NSEC RRset that proves the
/// non-existence.
/// - If there is a matching name but no RRset of the search type, it
/// returns the code of \c NXRRSET, and, if DNSSEC is required,
/// the NSEC RRset for that name.
/// - If there is a matching name with CNAME, it returns the code of
/// \c CNAME and that CNAME RR.
/// - If the search name matches a delegation point of DNAME, it returns
/// the code of \c DNAME and that DNAME RR.
///
/// A derived version of this method may involve internal resource
/// allocation, especially for constructing the resulting RRset, and may
/// throw an exception if it fails.
/// It should not throw other types of exceptions.
///
/// Note: It's quite likely that we'll need to specify search options.
/// For example, we should be able to specify whether to allow returning
/// glue records at or under a zone cut. We leave this interface open
/// at this moment.
///
/// \param name The domain name to be searched for.
/// \param type The RR type to be searched for.
/// \return A \c FindResult object enclosing the search result (see above).
virtual FindResult find(const isc::dns::Name& name,
const isc::dns::RRType& type) const = 0;
//@}
};
/// \brief A pointer-like type pointing to a \c AbstractZone object.
typedef boost::shared_ptr<AbstractZone> ZonePtr;
/// \brief A pointer-like type pointing to a \c AbstractZone object.
typedef boost::shared_ptr<const AbstractZone> ConstZonePtr;
/// A derived zone class intended to be used with the memory data source.
///
/// Currently this is almost empty and is only used for testing the
/// \c ZoneTable class. It will be substantially expanded, and will probably
/// moved to a separate header file.
class Zone : public AbstractZone {
///
/// \name Constructors and Destructor.
///
......@@ -60,32 +191,19 @@ public:
Zone(const isc::dns::RRClass& rrclass, const isc::dns::Name& origin);
/// The destructor.
~Zone();
virtual ~Zone();
//@}
///
/// \name Getter Methods
///
/// These methods never throw an exception.
//@{
/// \brief Return the origin name of the zone.
const isc::dns::Name& getOrigin() const;
/// \brief Return the RR class of the zone.
const isc::dns::RRClass& getClass() const;
//@}
virtual const isc::dns::Name& getOrigin() const;
virtual const isc::dns::RRClass& getClass() const;
virtual FindResult find(const isc::dns::Name& name,
const isc::dns::RRType& type) const;
private:
struct ZoneImpl;
ZoneImpl* impl_;
};
/// \brief A pointer-like type pointing to a \c Zone object.
typedef boost::shared_ptr<Zone> ZonePtr;
/// \brief A pointer-like type pointing to a \c Zone object.
typedef boost::shared_ptr<const Zone> ConstZonePtr;
/// \brief A set of authoritative zones.
///
/// The \c ZoneTable class represents a set of zones of the same RR class
......@@ -156,11 +274,11 @@ public:
/// See the description of \c find() for the semantics of the member
/// variables.
struct FindResult {
FindResult(Result param_code, const Zone* param_zone) :
FindResult(Result param_code, const AbstractZone* param_zone) :
code(param_code), zone(param_zone)
{}
const Result code;
const Zone* const zone;
const AbstractZone* const zone;
};
///
......
Supports Markdown
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