Commit dc5ef2b0 authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

sync with trunk


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac410@3593 e5f2f494-b856-4b98-b285-d166d9295462
parents 397245df 0233ab56
117. [func] jinmei
src/lib/datasrc: added new zone and zone table classes for the
support of in memory data source. This is an intermediate step to
the bigger feature, and is not yet actually usable in practice.
(Trac #399, svn r3590)
116. [bug] jerry
src/bin/xfrout: Xfrout and Auth will communicate by long tcp
connection, Auth needs to make a new connection only on the first
......
......@@ -132,7 +132,7 @@ public:
/// This constructor never throws an exception.
///
/// \param asio_address The ASIO \c ip::address to be converted.
IOAddress(const asio::ip::address& asio_adress);
IOAddress(const asio::ip::address& asio_address);
//@}
/// \brief Convert the address to a string.
......
......@@ -84,7 +84,7 @@ public:
isc::xfr::AbstractXfroutClient& xfrout_client);
~AuthSrv();
//@}
/// \return \c true if the \message contains a response to be returned;
/// \return \c true if the \a message contains a response to be returned;
/// otherwise \c false.
bool processMessage(const asio_link::IOMessage& io_message,
isc::dns::Message& message,
......@@ -138,7 +138,7 @@ public:
/// containing the result of the update operation.
isc::data::ConstElementPtr updateConfig(isc::data::ConstElementPtr config);
/// \param Returns the command and configuration session for the
/// \brief Returns the command and configuration session for the
/// \c AuthSrv.
///
/// This method never throws an exception.
......
......@@ -200,7 +200,7 @@ private:
BenchMark(const BenchMark& source);
BenchMark& operator=(const BenchMark& source);
public:
/// \bench Constructor for immediate run.
/// \brief Constructor for immediate run.
///
/// This is the constructor that is expected to be used normally.
/// It runs the benchmark within the constructor and prints the result,
......@@ -217,7 +217,7 @@ public:
initialize(true);
}
/// \bench Constructor for finer-grained control.
/// \brief Constructor for finer-grained control.
///
/// This constructor takes the third parameter, \c immediate, to control
/// whether to run the benchmark within the constructor.
......
......@@ -15,3 +15,4 @@ libdatasrc_la_SOURCES += static_datasrc.h static_datasrc.cc
libdatasrc_la_SOURCES += sqlite3_datasrc.h sqlite3_datasrc.cc
libdatasrc_la_SOURCES += query.h query.cc
libdatasrc_la_SOURCES += cache.h cache.cc
libdatasrc_la_SOURCES += zonetable.h zonetable.cc
......@@ -170,9 +170,9 @@ public:
/// then promoted to the head of the LRU queue. (NOTE: Because
/// of this, "retrieve" cannot be implemented as a const method.)
///
/// \param name The query name
/// \param rrclass The query class
/// \param rrtype The query type
/// \param qname The query name
/// \param qclass The query class
/// \param qtype The query type
/// \param rrset Returns the RRset found, if any, to the caller
/// \param flags Returns the flags, if any, to the caller
///
......
......@@ -24,6 +24,7 @@ run_unittests_SOURCES += static_unittest.cc
run_unittests_SOURCES += query_unittest.cc
run_unittests_SOURCES += cache_unittest.cc
run_unittests_SOURCES += test_datasrc.h test_datasrc.cc
run_unittests_SOURCES += zonetable_unittest.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
run_unittests_LDADD = $(GTEST_LDADD)
......
// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <exceptions/exceptions.h>
#include <dns/name.h>
#include <dns/rrclass.h>
#include <datasrc/zonetable.h>
#include <gtest/gtest.h>
using namespace isc::dns;
using namespace isc::datasrc;
namespace {
TEST(ZoneTest, init) {
Zone 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"));
EXPECT_EQ(Name("example"), ch_zone.getOrigin());
EXPECT_EQ(RRClass::CH(), ch_zone.getClass());
}
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")))
{}
ZoneTable zone_table;
ZonePtr zone1, zone2, zone3;
};
TEST_F(ZoneTableTest, add) {
EXPECT_EQ(ZoneTable::SUCCESS, zone_table.add(zone1));
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")))));
EXPECT_EQ(ZoneTable::SUCCESS, zone_table.add(zone2));
EXPECT_EQ(ZoneTable::SUCCESS, zone_table.add(zone3));
// 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")))));
/// Bogus zone (NULL)
EXPECT_THROW(zone_table.add(ZonePtr()), isc::InvalidParameter);
}
TEST_F(ZoneTableTest, remove) {
EXPECT_EQ(ZoneTable::SUCCESS, zone_table.add(zone1));
EXPECT_EQ(ZoneTable::SUCCESS, zone_table.add(zone2));
EXPECT_EQ(ZoneTable::SUCCESS, zone_table.add(zone3));
EXPECT_EQ(ZoneTable::SUCCESS, zone_table.remove(Name("example.net")));
EXPECT_EQ(ZoneTable::NOTFOUND, zone_table.remove(Name("example.net")));
}
TEST_F(ZoneTableTest, find) {
EXPECT_EQ(ZoneTable::SUCCESS, zone_table.add(zone1));
EXPECT_EQ(ZoneTable::SUCCESS, zone_table.add(zone2));
EXPECT_EQ(ZoneTable::SUCCESS, zone_table.add(zone3));
EXPECT_EQ(ZoneTable::SUCCESS, zone_table.find(Name("example.com")).code);
EXPECT_EQ(Name("example.com"),
zone_table.find(Name("example.com")).zone->getOrigin());
EXPECT_EQ(ZoneTable::NOTFOUND,
zone_table.find(Name("example.org")).code);
EXPECT_EQ(static_cast<const Zone*>(NULL),
zone_table.find(Name("example.org")).zone);
// there's no exact match. the result should be the longest match,
// and the code should be PARTIALMATCH.
EXPECT_EQ(ZoneTable::PARTIALMATCH,
zone_table.find(Name("www.example.com")).code);
EXPECT_EQ(Name("example.com"),
zone_table.find(Name("www.example.com")).zone->getOrigin());
// 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")));
EXPECT_EQ(ZoneTable::SUCCESS, zone_table.add(zone_com));
EXPECT_EQ(Name("example.com"),
zone_table.find(Name("www.example.com")).zone->getOrigin());
}
}
// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// Note: map and utility (for 'pair') are for temporary workaround.
// we'll soon replace them with built-in intelligent backend structure.
#include <map>
#include <utility>
#include <dns/name.h>
#include <dns/rrclass.h>
#include <datasrc/zonetable.h>
using namespace std;
using namespace isc::dns;
namespace isc {
namespace datasrc {
struct Zone::ZoneImpl {
ZoneImpl(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);
}
Zone::~Zone() {
delete impl_;
}
const Name&
Zone::getOrigin() const {
return (impl_->origin_);
}
const RRClass&
Zone::getClass() const {
return (impl_->zone_class_);
}
// This is a temporary, inefficient implementation using std::map and handmade
// iteration to realize longest match.
struct ZoneTable::ZoneTableImpl {
typedef map<Name, ZonePtr> ZoneMap;
typedef pair<Name, ZonePtr> NameAndZone;
ZoneMap zones;
};
ZoneTable::ZoneTable() : impl_(new ZoneTableImpl)
{}
ZoneTable::~ZoneTable() {
delete impl_;
}
ZoneTable::Result
ZoneTable::add(ZonePtr zone) {
if (!zone) {
isc_throw(InvalidParameter,
"Null pointer is passed to ZoneTable::add()");
}
if (impl_->zones.insert(
ZoneTableImpl::NameAndZone(zone->getOrigin(), zone)).second
== true) {
return (SUCCESS);
} else {
return (EXIST);
}
}
ZoneTable::Result
ZoneTable::remove(const Name& origin) {
return (impl_->zones.erase(origin) == 1 ? SUCCESS : NOTFOUND);
}
ZoneTable::FindResult
ZoneTable::find(const Name& name) const {
// Inefficient internal loop to find a longest match.
// This will be replaced with a single call to more intelligent backend.
for (int i = 0; i < name.getLabelCount(); ++i) {
Name matchname(name.split(i));
ZoneTableImpl::ZoneMap::const_iterator found =
impl_->zones.find(matchname);
if (found != impl_->zones.end()) {
return (FindResult(i == 0 ? SUCCESS : PARTIALMATCH,
(*found).second.get()));
}
}
return (FindResult(NOTFOUND, NULL));
}
} // end of namespace datasrc
} // end of namespace isc
// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef __ZONETABLE_H
#define __ZONETABLE_H 1
#include <boost/shared_ptr.hpp>
namespace isc {
namespace dns {
class Name;
class RRClass;
};
namespace datasrc {
/// \brief A single authoritative zone
///
/// The \c Zone class represents 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.
/// 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
/// information about the location of a zone file, whether it's loaded in
/// memory, etc.
class Zone {
///
/// \name Constructors and Destructor.
///
/// \b Note:
/// The copy constructor and the assignment operator are intentionally
/// defined as private, making this class non copyable.
//@{
private:
Zone(const Zone& source);
Zone& operator=(const Zone& source);
public:
/// \brief Constructor from zone parameters.
///
/// This constructor internally involves resource allocation, and if
/// it fails, a corresponding standard exception will be thrown.
/// It never throws an exception otherwise.
///
/// \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);
/// 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;
//@}
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
/// and provides a basic interface to help DNS lookup processing.
/// For a given domain name, its \c find() method searches the set for a zone
/// that gives a longest match against that name.
///
/// The set of zones are assumed to be of the same RR class, but the
/// \c ZoneTable class does not enforce the assumption through its interface.
/// For example, the \c add() method does not check if the new zone
/// is of the same RR class as that of the others already in the table.
/// It is caller's responsibility to ensure this assumption.
///
/// <b>Notes to developer:</b>
///
/// The add() method takes a (Boost) shared pointer because it would be
/// inconvenient to require the caller to maintain the ownership of zones,
/// while it wouldn't be safe to delete unnecessary zones inside the zone
/// table.
///
/// On the other hand, the find() method returns a bare pointer, rather than
/// the shared pointer, in order to minimize the dependency on Boost
/// definitions in our public interfaces. This means the caller can only
/// refer to the returned object (via the pointer) for a short period.
/// It should be okay for simple lookup purposes, but if we see the need
/// for keeping a \c Zone object for a longer period of context, we may
/// have to revisit this decision.
///
/// Currently, \c FindResult::zone is immutable for safety.
/// In future versions we may want to make it changeable. For example,
/// we may want to allow configuration update on an existing zone.
///
/// In BIND 9's "zt" module, the equivalent of \c find() has an "option"
/// parameter. The only defined option is the one to specify the "no exact"
/// mode, and the only purpose of that mode is to prefer a second longest match
/// even if there is an exact match in order to deal with type DS query.
/// This trick may help enhance performance, but it also seems to make the
/// implementation complicated for a very limited, minor case. So, for now,
/// we don't introduce the special mode, and, since it was the only reason to
/// have search options in BIND 9, our initial implementation doesn't provide
/// a switch for options.
class ZoneTable {
public:
/// Result codes of various public methods of \c ZoneTable.
///
/// The detailed semantics may differ in different methods.
/// See the description of specific methods for more details.
enum Result {
SUCCESS, ///< The operation is successful.
EXIST, ///< A zone is already stored in \c ZoneTable.
NOTFOUND, ///< The specified zone is not found in \c ZoneTable.
PARTIALMATCH ///< \c Only a partial match is found in \c find().
};
/// \brief A helper structure to represent the search result of
/// <code>ZoneTable::find()</code>.
///
/// This is a straightforward pair of the result code and a pointer
/// to the found zone to represent the result of \c find().
/// 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.
///
/// See the description of \c find() for the semantics of the member
/// variables.
struct FindResult {
FindResult(Result param_code, const Zone* param_zone) :
code(param_code), zone(param_zone)
{}
const Result code;
const Zone* const zone;
};
///
/// \name Constructors and Destructor.
///
/// \b Note:
/// The copy constructor and the assignment operator are intentionally
/// defined as private, making this class non copyable.
//@{
private:
ZoneTable(const ZoneTable& source);
ZoneTable& operator=(const ZoneTable& source);
public:
/// Default constructor.
///
/// This constructor internally involves resource allocation, and if
/// it fails, a corresponding standard exception will be thrown.
/// It never throws an exception otherwise.
ZoneTable();
/// The destructor.
~ZoneTable();
//@}
/// Add a \c Zone to the \c ZoneTable.
///
/// \c zone must not be associated with a NULL pointer; otherwise
/// an exception of class \c InvalidParameter will be thrown.
/// If internal resource allocation fails, a corresponding standard
/// exception will be thrown.
/// This method never throws an exception otherwise.
///
/// \param zone A \c Zone object to be added.
/// \return \c SUCCESS If the zone is successfully added to the zone table.
/// \return \c EXIST The zone table already stores a zone that has the
/// same origin.
Result add(ZonePtr zone);
/// Remove a \c Zone of the given origin name from the \c ZoneTable.
///
/// This method never throws an exception.
///
/// \param origin The origin name of the zone to be removed.
/// \return \c SUCCESS If the zone is successfully removed from the
/// zone table.
/// \return \c NOTFOUND The zone table does not store the zone that matches
/// \c origin.
Result remove(const isc::dns::Name& origin);
/// Find a \c Zone that best matches the given name in the \c ZoneTable.
///
/// It searches the internal storage for a \c Zone that gives the
/// longest match against \c name, and returns the result in the
/// form of a \c FindResult object as follows:
/// - \c code: The result code of the operation.
/// - \c SUCCESS: A zone that gives an exact match is found
/// - \c PARTIALMATCH: A zone whose origin is a super domain of
/// \c name is found (but there is no exact match)
/// - \c NOTFOUND: For all other cases.
/// - \c zone: A pointer to the found \c Zone object if one is found;
/// otherwise \c NULL.
///
/// The pointer returned in the \c FindResult object is only valid until
/// the corresponding zone is removed from the zone table.
/// The caller must ensure that the zone is held in the zone table while
/// it needs to refer to it.
///
/// This method never throws an exception.
///
/// \param name A domain name for which the search is performed.
/// \return A \c FindResult object enclosing the search result (see above).
FindResult find(const isc::dns::Name& name) const;
private:
struct ZoneTableImpl;
ZoneTableImpl* impl_;
};
}
}
#endif // __ZONETABLE_H
// Local Variables:
// mode: c++
// End:
......@@ -40,7 +40,7 @@ public:
/// file line number.
///
/// @param file the file name where the exception was thrown.
/// @param line the line in @ref file where the exception was thrown.
/// @param line the line in \a file where the exception was thrown.
/// @param what a description (type) of the exception.
Exception(const char* file, size_t line, const char* what) :
file_(file), line_(line), what_(what) {}
......@@ -49,7 +49,7 @@ public:
/// file line number.
///
/// @param file the file name where the exception was thrown.
/// @param line the line in @ref file where the exception was thrown.
/// @param line the line in \a file where the exception was thrown.
/// @param what a description (type) of the exception.
Exception(const char* file, size_t line, const std::string& what) :
file_(file), line_(line), what_(what) {}
......
......@@ -367,6 +367,7 @@ class NotifyOut:
zone_id = self._waiting_zones.pop(0)
self._notify_infos[zone_id].prepare_notify_out()
self.notify_num += 1
self._notifying_zones.append(zone_id)
def _send_notify_message_udp(self, zone_notify_info, addrinfo):
msg, qid = self._create_notify_message(zone_notify_info.zone_name,
......
......@@ -156,7 +156,7 @@ class TestNotifyOut(unittest.TestCase):
com_info = self._notify._notify_infos[('com.', 'IN')]
self._notify._notify_next_target(com_info)
self.assertEqual(2, self._notify.notify_num)
self.assertEqual(0, len(self._notify._notifying_zones))
self.assertEqual(2, len(self._notify._notifying_zones))
def test_handle_notify_reply(self):
self.assertEqual(notify_out._BAD_REPLY_PACKET, self._notify._handle_notify_reply(None, b'badmsg'))
......
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