Commit db105a36 authored by zhanglikun's avatar zhanglikun
Browse files

Merge branch 'master' into trac384

parents 0061de28 53033d94
153. [bug] jelte
b10-cfgmgr: Fixed a bug where configuration updates sometimes
lost previous settings in the configuration manager.
(Trac #427, git 2df894155657754151e0860e2ca9cdbed7317c70)
152. [func]* jinmei
b10-auth: Added new configuration variable "statistics-interval"
to allow the user to change the timer interval for periodic
statistics updates. The update can also be disabled by setting
the value to 0. Disabling statistics updates will also work as
a temporary workaround of a known issue that b10-auth can block in
sending statistics and stop responding to queries as a result.
(Trac #513, git 285c5ee)
151. [bug] smann
lib/log/dummylog.h:
lib/log/dummylog.cc: Modify dlog so that it takes an optional 2nd
argument of type bool (true or false). This flag, if set, will cause
the message to be printed whether or not -v is chosen.
(trac #432, git 880220478c3e8702d56d761b1e0b21b77d08ee5a)
150. [bug] jelte
b10-cfgmgr: No longer save the configuration on exit. Configuration
is already saved if it is changed successfully, so writing it on
exit (and hence, when nothing has changed too) is unnecessary and
may even cause problems.
(Trac #435, git fd7baa38c08d54d5b5f84930c1684c436d2776dc)
149. [bug] jelte
bindctl: Check if the user session has disappeared (either by a
timeout or by a server restart), and reauthenticate if so. This
fixes the 'cmdctl not running' problem.
(trac #431, git b929be82fec5f92e115d8985552f84b4fdd385b9)
148. [func] jelte
bindctl: Command results are now pretty-printed (i.e. printed in
a more readable form). Empty results are no longer printed at all
(used to print '{}'), and the message
'send the command to cmd-ctrl' has also been removed.
(git 3954c628c13ec90722a2d8816f52a380e0065bae)
147. [bug] jinmei
python/isc/config: Fixed a bug that importing custom configuration
(in b10-config.db) of a remote module didn't work.
(Trac #478, git ea4a481)
146. [func] jelte
Command arguments were not validated internally against their
specifications. This change fixes that (on the C++ side, Python
side depends on an as yet planned addition). Note: this is only
an added internal check, the cli already checks format.
(Trac #473, git 5474eba181cb2fdd80e2b2200e072cd0a13a4e52)
145. [func]* jinmei
b10-auth: added a new command 'loadzone' for (re)loading a
specific zone. The command syntax is generic but it is currently
only feasible for class IN in memory data source. To reload a
zone "example.com" via bindctl, execute the command as follows:
> Auth loadzone origin = example.com
(Trac #467)
144. [build] jinmei
Introduced a workaround for clang++ build on FreeBSD (and probably
some other OSes). If building BIND 10 fails with clang++ due to
a link error about "__dso_handle", try again from the configure
script with CXX_LIBTOOL_LDFLAGS=-L/usr/lib (the path actually
doesn't matter; the important part is the -L flag). This
workaround is not automatically enabled as it's difficult to
detect the need for it dynamically, and must be enabled via the
variable by hand. (Trac #474, git cfde436)
143. [build] jinmei
Fixed build problems with clang++ in unit tests due to recent
changes. No behavior change. (Trac #448, svn r4133)
......@@ -62,21 +133,21 @@
(Trac #202, svn r3967)
135. [func] each
Add b10-recurse. This is an example recursive server that
Add b10-resolver. This is an example recursive server that
currently does forwarding only and no caching.
(Trac #327, svn r3903)
134. [func] vorner
b10-recurse supports timeouts and retries in forwarder mode.
b10-resolver supports timeouts and retries in forwarder mode.
(Trac #401, svn r3660)
133. [func] vorner
New temporary logging function available in isc::log. It is used by
b10-recurse.
b10-resolver.
(Trac #393, r3602)
132. [func] vorner
The b10-recurse is configured through config manager.
The b10-resolver is configured through config manager.
It has "listen_on" and "forward_addresses" options.
(Trac #389, r3448)
......@@ -139,7 +210,7 @@ bind10-devel-20101201 released on December 01, 2010
122. [func] stephen
src/bin/bind10: Added configuration options to Boss to determine
whether to start the authoritative server, recursive server (or
both). A dummy recursor has been provided for test purposes.
both). A dummy program has been provided for test purposes.
(Trac #412, svn r3676)
121. [func] jinmei
......@@ -200,7 +271,7 @@ bind10-devel-20101201 released on December 01, 2010
112. [func] zhang likun
Add one mixin class to override the naive serve_forever() provided
in python library socketserver. Instead of polling for shutdwon
in python library socketserver. Instead of polling for shutdown
every poll_interval seconds, one socketpair is used to wake up
the waiting server. (Trac #352, svn r3366)
......@@ -781,8 +852,12 @@ bind10-devel-20100421 released on April 21, 2010
bind10-devel-20100319 released on March 19, 2010
For complete code revision history, see http://bind10.isc.org/browser
Specific subversion changesets can be accessed at:
http://bind10.isc.org/changeset/rrrr
Specific git changesets can be accessed at:
http://bind10.isc.org/changeset/?reponame=&old=rrrr^&new=rrrr
or after cloning the original git repository by executing:
% git diff rrrr^ rrrr
Subversion changesets are not accessible any more. The subversion
revision numbers will be replaced with corresponding git revisions.
Trac tickets can be accessed at: https://bind10.isc.org/ticket/nnn
LEGEND
......
......@@ -15,7 +15,7 @@ five year plan are described here:
This release includes the bind10 master process, b10-msgq message
bus, b10-auth authoritative DNS server (with SQLite3 backend),
b10-recurse forwarding DNS server, b10-cmdctl remote control daemon,
b10-resolver forwarding DNS server, b10-cmdctl remote control daemon,
b10-cfgmgr configuration manager, b10-xfrin AXFR inbound service,
b10-xfrout outgoing AXFR service, b10-zonemgr secondary manager,
b10-stats statistics collection and reporting daemon, and a new
......@@ -193,6 +193,7 @@ config revert: Revert all changes that have not been committed
config commit: Commit all changes
config diff: Show the changes that have not been committed yet
EXAMPLE SESSION
~> bindctl
......
......@@ -9,7 +9,23 @@ AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CXX
# Libtool configuration
#
# On FreeBSD (and probably some others), clang++ does not meet an autoconf
# assumption in identifying libtool configuration regarding shared library:
# the configure script will execute "$CC -shared $CFLAGS -v -o" and expect
# the output contains -Lxxx or -Ryyy. This is the case for g++, but not for
# clang++, and, as a result, it will cause various errors in linking programs
# or running them with a shared object (such as some of our python scripts).
# To work around this problem we define a temporary variable
# "CXX_LIBTOOL_LDFLAGS". It's expected to be defined as, e.g, "-L/usr/lib"
# to temporarily fake the output so that it will be compatible with that of
# g++.
CFLAGS_SAVED=$CFLAGS
CFLAGS="$CFLAGS $CXX_LIBTOOL_LDFLAGS"
AC_PROG_LIBTOOL
CFLAGS=$CFLAGS_SAVED
# Use C++ language
AC_LANG([C++])
......@@ -67,7 +83,7 @@ case "$host" in
CPPFLAGS="$CPPFLAGS -D_XPG4_2 -D__EXTENSIONS__"
;;
*-apple-darwin*)
# libtool doesn't work pefectly with Darwin: libtool embeds the
# libtool doesn't work perfectly with Darwin: libtool embeds the
# final install path in dynamic libraries and our loadable python
# modules always refer to that path even if it's loaded within the
# source tree. This prevents pre-install tests from working.
......@@ -186,7 +202,7 @@ fi
# Compiler dependent settings: define some mandatory CXXFLAGS here.
# We also use a separate variable B10_CXXFLAGS. This will (and should) be
# used as the default value for each specifc AM_CXXFLAGS:
# used as the default value for each specific AM_CXXFLAGS:
# AM_CXXFLAGS = $(B10_CXXFLAGS)
# AM_CXXFLAGS += ... # add module specific flags
# We need this so that we can disable some specific compiler warnings per
......@@ -539,7 +555,7 @@ fi
# So, for the moment, we simply disable the use of /dev/poll. Unless we
# implement recursive DNS server with randomized ports, we don't need the
# scalability that /dev/poll can provide, so this decision wouldn't affect
# run time performance. Hpefully we can find a better solution or the ASIO
# run time performance. Hopefully we can find a better solution or the ASIO
# code will be updated by the time we really need it.
AC_CHECK_HEADERS(sys/devpoll.h, ac_cv_have_devpoll=yes, ac_cv_have_devpoll=no)
if test "X$ac_cv_have_devpoll" = "Xyes" -a "X$GXX" = "Xyes"; then
......@@ -577,8 +593,8 @@ AC_CONFIG_FILES([Makefile
src/bin/auth/Makefile
src/bin/auth/tests/Makefile
src/bin/auth/benchmarks/Makefile
src/bin/recurse/Makefile
src/bin/recurse/tests/Makefile
src/bin/resolver/Makefile
src/bin/resolver/tests/Makefile
src/bin/xfrin/Makefile
src/bin/xfrin/tests/Makefile
src/bin/xfrout/Makefile
......@@ -652,8 +668,8 @@ AC_OUTPUT([src/bin/cfgmgr/b10-cfgmgr.py
src/bin/xfrout/xfrout.spec.pre
src/bin/xfrout/tests/xfrout_test
src/bin/xfrout/run_b10-xfrout.sh
src/bin/recurse/recurse.spec.pre
src/bin/recurse/spec_config.h.pre
src/bin/resolver/resolver.spec.pre
src/bin/resolver/spec_config.h.pre
src/bin/zonemgr/zonemgr.py
src/bin/zonemgr/zonemgr.spec.pre
src/bin/zonemgr/tests/zonemgr_test
......@@ -696,7 +712,7 @@ AC_OUTPUT([src/bin/cfgmgr/b10-cfgmgr.py
chmod +x src/bin/cmdctl/run_b10-cmdctl.sh
chmod +x src/bin/xfrin/run_b10-xfrin.sh
chmod +x src/bin/xfrout/run_b10-xfrout.sh
chmod +x src/bin/recurse/run_b10-recurse.sh
chmod +x src/bin/resolver/run_b10-resolver.sh
chmod +x src/bin/zonemgr/run_b10-zonemgr.sh
chmod +x src/bin/stats/tests/stats_test
chmod +x src/bin/stats/run_b10-stats.sh
......
SUBDIRS = bind10 bindctl cfgmgr loadzone msgq host cmdctl auth xfrin xfrout \
usermgr zonemgr stats tests recurse
usermgr zonemgr stats tests resolver
check-recursive: all-recursive
......@@ -40,6 +40,7 @@ b10_auth_SOURCES = query.cc query.h
b10_auth_SOURCES += auth_srv.cc auth_srv.h
b10_auth_SOURCES += change_user.cc change_user.h
b10_auth_SOURCES += config.cc config.h
b10_auth_SOURCES += command.cc command.h
b10_auth_SOURCES += common.h
b10_auth_SOURCES += statistics.cc statistics.h
b10_auth_SOURCES += main.cc
......
......@@ -51,6 +51,11 @@
}
}]
}
},
{ "item_name": "statistics-interval",
"item_type": "integer",
"item_optional": true,
"item_default": 60
}
],
"commands": [
......@@ -63,8 +68,25 @@
"command_name": "sendstats",
"command_description": "Send data to a statistics module at once",
"command_args": []
},
{
"command_name": "loadzone",
"command_description": "(Re)load a specified zone",
"command_args": [
{
"item_name": "class", "item_type": "string",
"item_optional": true, "item_default": "IN"
},
{
"item_name": "origin", "item_type": "string",
"item_optional": false, "item_default": ""
},
{
"item_name": "datasrc", "item_type": "string",
"item_optional": true, "item_default": "memory"
}
]
}
]
}
}
......@@ -23,6 +23,8 @@
#include <iostream>
#include <vector>
#include <boost/bind.hpp>
#include <asiolink/asiolink.h>
#include <config/ccsession.h>
......@@ -87,6 +89,8 @@ public:
bool processNotify(const IOMessage& io_message, MessagePtr message,
OutputBufferPtr buffer);
IOService io_service_;
/// Currently non-configurable, but will be.
static const uint16_t DEFAULT_LOCAL_UDPSIZE = 4096;
......@@ -102,6 +106,9 @@ public:
/// Hot spot cache
isc::datasrc::HotCache cache_;
/// Interval timer for periodic submission of statistics counters.
IntervalTimer statistics_timer_;
/// Query counters for statistics
AuthCounters counters_;
private:
......@@ -125,6 +132,7 @@ AuthSrvImpl::AuthSrvImpl(const bool use_cache,
config_session_(NULL), verbose_mode_(false),
xfrin_session_(NULL),
memory_datasrc_class_(RRClass::IN()),
statistics_timer_(io_service_),
counters_(verbose_mode_),
xfrout_connected_(false),
xfrout_client_(xfrout_client)
......@@ -200,6 +208,11 @@ AuthSrv::AuthSrv(const bool use_cache, AbstractXfroutClient& xfrout_client) :
dns_answer_(new MessageAnswer(this))
{}
void
AuthSrv::stop() {
impl_->io_service_.stop();
}
AuthSrv::~AuthSrv() {
delete impl_;
delete checkin_;
......@@ -269,6 +282,11 @@ AuthSrv::getVerbose() const {
return (impl_->verbose_mode_);
}
IOService&
AuthSrv::getIOService() {
return (impl_->io_service_);
}
void
AuthSrv::setCacheSlots(const size_t slots) {
impl_->cache_.setSlots(slots);
......@@ -299,8 +317,8 @@ AuthSrv::getConfigSession() const {
return (impl_->config_session_);
}
AuthSrv::ConstMemoryDataSrcPtr
AuthSrv::getMemoryDataSrc(const RRClass& rrclass) const {
AuthSrv::MemoryDataSrcPtr
AuthSrv::getMemoryDataSrc(const RRClass& rrclass) {
// XXX: for simplicity, we only support the IN class right now.
if (rrclass != impl_->memory_datasrc_class_) {
isc_throw(InvalidParameter,
......@@ -332,6 +350,32 @@ AuthSrv::setMemoryDataSrc(const isc::dns::RRClass& rrclass,
impl_->memory_datasrc_ = memory_datasrc;
}
uint32_t
AuthSrv::getStatisticsTimerInterval() const {
return (impl_->statistics_timer_.getInterval());
}
void
AuthSrv::setStatisticsTimerInterval(uint32_t interval) {
if (interval == impl_->statistics_timer_.getInterval()) {
return;
}
if (interval == 0) {
impl_->statistics_timer_.cancel();
} else {
impl_->statistics_timer_.setupTimer(
boost::bind(&AuthSrv::submitStatistics, this), interval);
}
if (impl_->verbose_mode_) {
if (interval == 0) {
cerr << "[b10-auth] Disabled statistics timer" << endl;
} else {
cerr << "[b10-auth] Set statistics timer to " << interval
<< " seconds" << endl;
}
}
}
void
AuthSrv::processMessage(const IOMessage& io_message, MessagePtr message,
OutputBufferPtr buffer, DNSServer* server)
......
......@@ -87,6 +87,14 @@ public:
~AuthSrv();
//@}
/// Stop the server.
///
/// It stops the internal event loop of the server and subsequently
/// returns the control to the top level context.
///
/// This method should never throw an exception.
void stop();
/// \brief Process an incoming DNS message, then signal 'server' to resume
///
/// A DNS query (or other message) has been received by a \c DNSServer
......@@ -185,11 +193,8 @@ public:
/// control commands and configuration updates.
void setConfigSession(isc::config::ModuleCCSession* config_session);
/// \brief Assign an ASIO IO Service queue to this Recursor object
void setIOService(asiolink::IOService& ios) { io_service_ = &ios; }
/// \brief Return this object's ASIO IO Service queue
asiolink::IOService& getIOService() const { return (*io_service_); }
asiolink::IOService& getIOService();
/// \brief Return pointer to the DNS Lookup callback function
asiolink::DNSLookup* getDNSLookupProvider() const { return (dns_lookup_); }
......@@ -265,8 +270,7 @@ public:
/// \param rrclass The RR class of the requested in-memory data source.
/// \return A pointer to the in-memory data source, if configured;
/// otherwise NULL.
ConstMemoryDataSrcPtr
getMemoryDataSrc(const isc::dns::RRClass& rrclass) const;
MemoryDataSrcPtr getMemoryDataSrc(const isc::dns::RRClass& rrclass);
/// Sets or replaces the in-memory data source of the specified RR class.
///
......@@ -304,6 +308,28 @@ public:
/// is shutdown.
void setStatisticsSession(isc::cc::AbstractSession* statistics_session);
/// Return the interval of periodic submission of statistics in seconds.
///
/// If the statistics submission is disabled, it returns 0.
///
/// This method never throws an exception.
uint32_t getStatisticsTimerInterval() const;
/// Set the interval of periodic submission of statistics.
///
/// If the specified value is non 0, the \c AuthSrv object will submit
/// its statistics to the statistics module every \c interval seconds.
/// If it's 0, and \c AuthSrv currently submits statistics, the submission
/// will be disabled.
///
/// This method should normally not throw an exception; however, its
/// underlying library routines may involve resource allocation, and
/// when it fails it would result in a corresponding standard exception.
///
/// \param interval The submission interval in seconds if non 0;
/// or a value of 0 to disable the submission.
void setStatisticsTimerInterval(uint32_t interval);
/// \brief Submit statistics counters to statistics module.
///
/// This function can throw an exception from
......@@ -330,7 +356,6 @@ public:
private:
AuthSrvImpl* impl_;
asiolink::IOService* io_service_;
asiolink::SimpleCallback* checkin_;
asiolink::DNSLookup* dns_lookup_;
asiolink::DNSAnswer* dns_answer_;
......
// 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 <string>
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <exceptions/exceptions.h>
#include <dns/rrclass.h>
#include <cc/data.h>
#include <datasrc/memory_datasrc.h>
#include <config/ccsession.h>
#include <auth/auth_srv.h>
#include <auth/command.h>
using namespace std;
using boost::shared_ptr;
using boost::scoped_ptr;
using namespace isc::dns;
using namespace isc::data;
using namespace isc::datasrc;
using namespace isc::config;
namespace {
/// An exception that is thrown if an error occurs while handling a command
/// on an \c AuthSrv object.
///
/// Currently it's only used internally, since \c execAuthServerCommand()
/// (which is the only interface to this module) catches all \c isc::
/// exceptions and converts them.
class AuthCommandError : public isc::Exception {
public:
AuthCommandError(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) {}
};
/// An abstract base class that represents a single command identifier
/// for an \c AuthSrv object.
///
/// Each of derived classes of \c AuthCommand, which are hidden inside the
/// implementation, corresponds to a command executed on \c AuthSrv, such as
/// "shutdown". The derived class is responsible to execute the corresponding
/// command with the given command arguments (if any) in its \c exec()
/// method.
///
/// In the initial implementation the existence of the command classes is
/// hidden inside the implementation since the only public interface is
/// \c execAuthServerCommand(), which does not expose this class.
/// In future, we may want to make this framework more dynamic, i.e.,
/// registering specific derived classes run time outside of this
/// implementation. If and when that happens the definition of the abstract
/// class will be published.
class AuthCommand {
///
/// \name Constructors and Destructor
///
/// Note: The copy constructor and the assignment operator are
/// intentionally defined as private to make it explicit that this is a
/// pure base class.
//@{
private:
AuthCommand(const AuthCommand& source);
AuthCommand& operator=(const AuthCommand& source);
protected:
/// \brief 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).
AuthCommand() {}
public:
/// The destructor.
virtual ~AuthCommand() {}
//@}
/// Execute a single control command.
///
/// Specific derived methods can throw exceptions. When called via
/// \c execAuthServerCommand(), all BIND 10 exceptions are caught
/// and converted into an error code.
/// The derived method may also throw an exception of class
/// \c AuthCommandError when it encounters an internal error, such as
/// semantics error on the command arguments.
///
/// \param server The \c AuthSrv object on which the command is executed.
/// \param args Command specific argument.
virtual void exec(AuthSrv& server, isc::data::ConstElementPtr args) = 0;
};
// Handle the "shutdown" command. No argument is assumed.
class ShutdownCommand : public AuthCommand {
public:
virtual void exec(AuthSrv& server, isc::data::ConstElementPtr) {
server.stop();
}
};
// Handle the "sendstats" command. No argument is assumed.
class SendStatsCommand : public AuthCommand {
public:
virtual void exec(AuthSrv& server, isc::data::ConstElementPtr) {
if (server.getVerbose()) {
cerr << "[b10-auth] command 'sendstats' received" << endl;
}
server.submitStatistics();
}
};
// Handle the "loadzone" command.
class LoadZoneCommand : public AuthCommand {
public:
virtual void exec(AuthSrv& server, isc::data::ConstElementPtr args) {
// parse and validate the args.
if (!validate(server, args)) {
return;
}
// Load a new zone and replace the current zone with the new one.
// TODO: eventually this should be incremental or done in some way
// that doesn't block other server operations.
// TODO: we may (should?) want to check the "last load time" and
// the timestamp of the file and skip loading if the file isn't newer.
shared_ptr<MemoryZone> newzone(new MemoryZone(oldzone->getClass(),
oldzone->getOrigin()));
newzone->load(oldzone->getFileName());
oldzone->swap(*newzone);
if (server.getVerbose()) {
cerr << "[b10-auth] Loaded zone '" << newzone->getOrigin()
<< "'/" << newzone->getClass() << endl;
}
}
private:
shared_ptr<MemoryZone> oldzone; // zone to be updated with the new file.
// A helper private method to parse and validate command parameters.
// On success, it sets 'oldzone' to the zone to be updated.
// It returns true if everything is okay; and false if the command is
// valid but there's no need for further process.
bool validate(AuthSrv& server, isc::data::ConstElementPtr args) {
if (args == NULL) {
isc_throw(AuthCommandError, "Null argument");
}
// In this initial implementation, we assume memory data source
// for class IN by default.
ConstElementPtr datasrc_elem = args->get("datasrc");
if (datasrc_elem) {
if (datasrc_elem->stringValue() == "sqlite3") {
if (server.getVerbose()) {
cerr << "[b10-auth] Nothing to do for loading sqlite3"
<< endl;
}
return (false);
} else if (datasrc_elem->stringValue() != "memory") {
// (note: at this point it's guaranteed that datasrc_elem
// is of string type)
isc_throw(AuthCommandError,
"Data source type " << datasrc_elem->stringValue()
<< " is not supported");
}
}
ConstElementPtr class_elem = args->get("class");
const RRClass zone_class = class_elem ?
RRClass(class_elem->stringValue()) : RRClass::IN();
AuthSrv::MemoryDataSrcPtr datasrc(server.getMemoryDataSrc(zone_class));
if