[svn] commit: r3749 - in /trunk: ./ src/bin/auth/tests/query_unittest.cc src/bin/bind10/bind10.py.in src/lib/datasrc/tests/zonetable_unittest.cc src/lib/datasrc/zonetable.cc src/lib/datasrc/zonetable.h src/lib/python/isc/utils/
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Dec 7 12:40:09 UTC 2010
Author: jinmei
Date: Tue Dec 7 12:40:09 2010
New Revision: 3749
Log:
merged trac #418: a second (or 1.5th) step of the query logic for in memory data source.
Modified:
trunk/ (props changed)
trunk/src/bin/auth/tests/query_unittest.cc
trunk/src/bin/bind10/bind10.py.in (props changed)
trunk/src/lib/datasrc/tests/zonetable_unittest.cc
trunk/src/lib/datasrc/zonetable.cc
trunk/src/lib/datasrc/zonetable.h
trunk/src/lib/python/isc/utils/ (props changed)
Modified: trunk/src/bin/auth/tests/query_unittest.cc
==============================================================================
--- trunk/src/bin/auth/tests/query_unittest.cc (original)
+++ trunk/src/bin/auth/tests/query_unittest.cc Tue Dec 7 12:40:09 2010
@@ -55,7 +55,7 @@
TEST_F(QueryTest, matchZone) {
// add a matching zone. since the zone is empty right now, the response
// should have NXDOMAIN.
- zone_table.add(ZonePtr(new Zone(qclass, Name("example.com"))));
+ zone_table.add(ZonePtr(new MemoryZone(qclass, Name("example.com"))));
query.process();
EXPECT_EQ(Rcode::NXDOMAIN(), response.getRcode());
}
@@ -63,7 +63,7 @@
TEST_F(QueryTest, noMatchZone) {
// there's a zone in the table but it doesn't match the qname. should
// result in SERVFAIL.
- zone_table.add(ZonePtr(new Zone(qclass, Name("example.org"))));
+ zone_table.add(ZonePtr(new MemoryZone(qclass, Name("example.org"))));
query.process();
EXPECT_EQ(Rcode::SERVFAIL(), response.getRcode());
}
Modified: trunk/src/lib/datasrc/tests/zonetable_unittest.cc
==============================================================================
--- trunk/src/lib/datasrc/tests/zonetable_unittest.cc (original)
+++ trunk/src/lib/datasrc/tests/zonetable_unittest.cc Tue Dec 7 12:40:09 2010
@@ -26,20 +26,28 @@
namespace {
TEST(ZoneTest, init) {
- Zone zone(RRClass::IN(), Name("example.com"));
+ MemoryZone zone(RRClass::IN(), Name("example.com"));
EXPECT_EQ(Name("example.com"), zone.getOrigin());
EXPECT_EQ(RRClass::IN(), zone.getClass());
- Zone ch_zone(RRClass::CH(), Name("example"));
+ MemoryZone ch_zone(RRClass::CH(), Name("example"));
EXPECT_EQ(Name("example"), ch_zone.getOrigin());
EXPECT_EQ(RRClass::CH(), ch_zone.getClass());
}
+TEST(ZoneTest, find) {
+ MemoryZone zone(RRClass::IN(), Name("example.com"));
+ EXPECT_EQ(Zone::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"))),
- zone2(new Zone(RRClass::IN(), Name("example.net"))),
- zone3(new Zone(RRClass::IN(), Name("example")))
+ ZoneTableTest() : zone1(new MemoryZone(RRClass::IN(),
+ Name("example.com"))),
+ zone2(new MemoryZone(RRClass::IN(),
+ Name("example.net"))),
+ zone3(new MemoryZone(RRClass::IN(), Name("example")))
{}
ZoneTable zone_table;
ZonePtr zone1, zone2, zone3;
@@ -50,7 +58,7 @@
EXPECT_EQ(ZoneTable::EXIST, zone_table.add(zone1));
// names are compared in a case insensitive manner.
EXPECT_EQ(ZoneTable::EXIST, zone_table.add(
- ZonePtr(new Zone(RRClass::IN(), Name("EXAMPLE.COM")))));
+ ZonePtr(new MemoryZone(RRClass::IN(), Name("EXAMPLE.COM")))));
EXPECT_EQ(ZoneTable::SUCCESS, zone_table.add(zone2));
EXPECT_EQ(ZoneTable::SUCCESS, zone_table.add(zone3));
@@ -58,7 +66,8 @@
// Zone table is indexed only by name. Duplicate origin name with
// different zone class isn't allowed.
EXPECT_EQ(ZoneTable::EXIST, zone_table.add(
- ZonePtr(new Zone(RRClass::CH(), Name("example.com")))));
+ ZonePtr(new MemoryZone(RRClass::CH(),
+ Name("example.com")))));
/// Bogus zone (NULL)
EXPECT_THROW(zone_table.add(ZonePtr()), isc::InvalidParameter);
@@ -96,7 +105,7 @@
// make sure the partial match is indeed the longest match by adding
// a zone with a shorter origin and query again.
- ZonePtr zone_com(new Zone(RRClass::IN(), Name("com")));
+ ZonePtr zone_com(new MemoryZone(RRClass::IN(), Name("com")));
EXPECT_EQ(ZoneTable::SUCCESS, zone_table.add(zone_com));
EXPECT_EQ(Name("example.com"),
zone_table.find(Name("www.example.com")).zone->getOrigin());
Modified: trunk/src/lib/datasrc/zonetable.cc
==============================================================================
--- trunk/src/lib/datasrc/zonetable.cc (original)
+++ trunk/src/lib/datasrc/zonetable.cc Tue Dec 7 12:40:09 2010
@@ -28,30 +28,37 @@
namespace isc {
namespace datasrc {
-struct Zone::ZoneImpl {
- ZoneImpl(const RRClass& zone_class, const Name& origin) :
+struct MemoryZone::MemoryZoneImpl {
+ MemoryZoneImpl(const RRClass& zone_class, const Name& origin) :
zone_class_(zone_class), origin_(origin)
{}
RRClass zone_class_;
Name origin_;
};
-Zone::Zone(const RRClass& zone_class, const Name& origin) : impl_(NULL) {
- impl_ = new ZoneImpl(zone_class, origin);
+MemoryZone::MemoryZone(const RRClass& zone_class, const Name& origin) :
+ impl_(new MemoryZoneImpl(zone_class, origin))
+{
}
-Zone::~Zone() {
+MemoryZone::~MemoryZone() {
delete impl_;
}
const Name&
-Zone::getOrigin() const {
+MemoryZone::getOrigin() const {
return (impl_->origin_);
}
const RRClass&
-Zone::getClass() const {
+MemoryZone::getClass() const {
return (impl_->zone_class_);
+}
+
+Zone::FindResult
+MemoryZone::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
Modified: trunk/src/lib/datasrc/zonetable.h
==============================================================================
--- trunk/src/lib/datasrc/zonetable.h (original)
+++ trunk/src/lib/datasrc/zonetable.h Tue Dec 7 12:40:09 2010
@@ -17,6 +17,8 @@
#include <boost/shared_ptr.hpp>
+#include <dns/rrset.h>
+
namespace isc {
namespace dns {
class Name;
@@ -25,19 +27,165 @@
namespace datasrc {
-/// \brief A single authoritative zone
-///
-/// The \c Zone class represents a DNS zone as part of %data source.
+/// \brief The base class for a single authoritative zone
+///
+/// The \c Zone 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.
+///
+/// It's not yet clear how the derived zone classes work with various other
+/// data sources when we integrate these components, but one possibility is
+/// something like this:
+/// - If the underlying database such as some variant of SQL doesn't have an
+/// explicit representation of zones (as part of public interface), we can
+/// probably use a "default" zone class that simply encapsulates the
+/// corresponding data source and calls a common "find" like method.
+/// - Some data source may want to specialize it by inheritance as an
+/// optimization. For example, in the current schema design of the sqlite3
+/// data source, its (derived) zone class would contain the information of
+/// the "zone ID".
+///
+/// <b>Note:</b> Unlike some other abstract base classes we don't name the
+/// class beginning with "Abstract". This is because we want to have
+/// commonly used definitions such as \c Result and \c ZonePtr, and we want
+/// to make them look more intuitive.
class Zone {
+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 whose internal state never changes,
+ /// 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).
+ Zone() {}
+public:
+ /// The destructor.
+ virtual ~Zone() {}
+ //@}
+
+ ///
+ /// \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 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;
+
+/// 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 MemoryZone : public Zone {
///
/// \name Constructors and Destructor.
///
@@ -46,8 +194,8 @@
/// defined as private, making this class non copyable.
//@{
private:
- Zone(const Zone& source);
- Zone& operator=(const Zone& source);
+ MemoryZone(const MemoryZone& source);
+ MemoryZone& operator=(const MemoryZone& source);
public:
/// \brief Constructor from zone parameters.
///
@@ -57,34 +205,21 @@
///
/// \param rrclass The RR class of the zone.
/// \param origin The origin name of the zone.
- Zone(const isc::dns::RRClass& rrclass, const isc::dns::Name& origin);
+ MemoryZone(const isc::dns::RRClass& rrclass, const isc::dns::Name& origin);
/// The destructor.
- ~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 ~MemoryZone();
+ //@}
+
+ 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_;
+ struct MemoryZoneImpl;
+ MemoryZoneImpl* 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.
///
More information about the bind10-changes
mailing list