BIND 10 master, updated. 2015d7fc14dee3abea892ea3bed3d6af6899fb38 [master] Update changelog for merge of #1986
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Jul 20 09:03:28 UTC 2012
The branch, master has been updated
via 2015d7fc14dee3abea892ea3bed3d6af6899fb38 (commit)
via bd6b0a5ed3481f78fb4e5cb0b18c7b6e5920f9f8 (commit)
via a25bfbc47ae1d1d138c38edbe75820c758cde4ec (commit)
via 09d8f46c29ee329529bf251473691611e86d1f9a (commit)
via b6838349c382c9b4452dfaccf158c110594c162b (commit)
via 22c45facd92929d66723796127b3a51e77c6c9f1 (commit)
via 3eb46f5f9ed333e791ead5d759810546aefef4a9 (commit)
via ea44fe72161fa65fef97d128b28f1223a8762d99 (commit)
via 96f4382db5fdd9df1a63d658e9baae1b48502537 (commit)
via 64d089fdc9afb69b581892764e8cccd47d958013 (commit)
via 0d9247297af2866ac4a39dfdc9cd497d12d10470 (commit)
via a60ad302be00a9106686beb8fec1f26f22847141 (commit)
via 1f6f0248eb6614574c321a2ca2b9c68f73bc6614 (commit)
via b2c8aa2a94d55f9071a834bef0b041b9629f4738 (commit)
via b6fb7dee3b59c356ef374c486e1a8047f3fbef5d (commit)
from 0044c1905b24873969148d22ca95e3b63aa6e3c2 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 2015d7fc14dee3abea892ea3bed3d6af6899fb38
Author: Jelte Jansen <jelte at isc.org>
Date: Fri Jul 20 11:03:12 2012 +0200
[master] Update changelog for merge of #1986
commit bd6b0a5ed3481f78fb4e5cb0b18c7b6e5920f9f8
Merge: 0044c19 a25bfbc
Author: Jelte Jansen <jelte at isc.org>
Date: Fri Jul 20 09:58:33 2012 +0200
[master] Merge branch 'trac1986'
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 97 +++++++++++++++-------------
src/bin/auth/auth.spec.pre.in | 10 +++
src/bin/auth/auth_messages.mes | 22 ++++++-
src/bin/auth/auth_srv.cc | 46 ++++++++++---
src/bin/auth/auth_srv.h | 29 +++++++--
src/bin/auth/command.cc | 18 ++++++
src/bin/auth/common.cc | 1 +
src/bin/auth/common.h | 5 ++
src/bin/auth/main.cc | 6 ++
src/bin/auth/tests/auth_srv_unittest.cc | 85 ++++++++++++++++++++++++
src/bin/ddns/ddns.py.in | 34 ++++++++++
src/bin/ddns/ddns_messages.mes | 37 +++++++++++
src/bin/ddns/tests/ddns_test.py | 63 ++++++++++++++++++
tests/lettuce/features/ddns_system.feature | 24 ++++---
14 files changed, 403 insertions(+), 74 deletions(-)
-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index fa85446..776f14e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+453. [bug] jelte
+ b10-auth no longer tries to send DDNS UPDATE messages to b10-ddns if
+ b10-ddns is not running. Sending an UPDATE to BIND 10 that is not
+ configured to run DDNS will now result in a response with rcode
+ NOTIMP instead of SERVFAIL.
+ (Trac #1986, git bd6b0a5ed3481f78fb4e5cb0b18c7b6e5920f9f8)
+
452. [func]* muks
b10-showtech: An initial implementation of the b10-showtech tool
is now available. It gathers and outputs system information which
@@ -291,8 +298,8 @@ bind10-devel-20120329 released on March 29, 2012
407. [build] haikuo
Remove "--enable-boost-threads" switch in configure command. This
- thread lock mechanism is useless for bind10 and causes performance
- hits.
+ thread lock mechanism is useless for bind10 and causes performance
+ hits.
(Trac #1680, git 9c4d0cadf4adc802cc41a2610dc2c30b25aad728)
406. [bug] muks
@@ -788,26 +795,26 @@ bind10-devel-20120119 released on January 19, 2012
(Trac #1350, git cc20ff993da1ddb1c6e8a98370438b45a2be9e0a)
336. [func] jelte
- libdns++ (and its python wrapper) now includes a class Serial, for
- SOA SERIAL comparison and addition. Operations on instances of this
- class follow the specification from RFC 1982.
- Rdata::SOA::getSerial() now returns values of this type (and not
+ libdns++ (and its python wrapper) now includes a class Serial, for
+ SOA SERIAL comparison and addition. Operations on instances of this
+ class follow the specification from RFC 1982.
+ Rdata::SOA::getSerial() now returns values of this type (and not
uint32_t).
(Trac #1278, git 2ae72d76c74f61a67590722c73ebbf631388acbd)
335. [bug]* jelte
- The DataSourceClientContainer class that dynamically loads
- datasource backend libraries no longer provides just a .so file name
- to its call to dlopen(), but passes it an absolute path. This means
- that it is no longer an system implementation detail that depends on
- [DY]LD_LIBRARY_PATH which file is chosen, should there be multiple
- options (for instance, when test-running a new build while a
+ The DataSourceClientContainer class that dynamically loads
+ datasource backend libraries no longer provides just a .so file name
+ to its call to dlopen(), but passes it an absolute path. This means
+ that it is no longer an system implementation detail that depends on
+ [DY]LD_LIBRARY_PATH which file is chosen, should there be multiple
+ options (for instance, when test-running a new build while a
different version is installed).
- These loadable libraries are also no longer installed in the default
- library path, but in a subdirectory of the libexec directory of the
+ These loadable libraries are also no longer installed in the default
+ library path, but in a subdirectory of the libexec directory of the
target ($prefix/libexec/[version]/backends).
- This also removes the need to handle b10-xfin and b10-xfrout as
- 'special' hardcoded components, and they are now started as regular
+ This also removes the need to handle b10-xfin and b10-xfrout as
+ 'special' hardcoded components, and they are now started as regular
components as dictated by the configuration of the boss process.
(Trac #1292, git 83ce13c2d85068a1bec015361e4ef8c35590a5d0)
@@ -952,12 +959,12 @@ bind10-devel-20111128 released on November 28, 2011
(Trac #1228, git 31d5a4f66b18cca838ca1182b9f13034066427a7)
314. [bug] jelte
- b10-xfrin would previously initiate incoming transfers upon
- receiving NOTIFY messages from any address (if the zone was
- known to b10-xfrin, and using the configured address). It now
- only starts a transfer if the source address from the NOTIFY
- packet matches the configured master address and port. This was
- really already fixed in release bind10-devel-20111014, but there
+ b10-xfrin would previously initiate incoming transfers upon
+ receiving NOTIFY messages from any address (if the zone was
+ known to b10-xfrin, and using the configured address). It now
+ only starts a transfer if the source address from the NOTIFY
+ packet matches the configured master address and port. This was
+ really already fixed in release bind10-devel-20111014, but there
were some deferred cleanups to add.
(Trac #1298, git 1177bfe30e17a76bea6b6447e14ae9be9e1ca8c2)
@@ -971,7 +978,7 @@ bind10-devel-20111128 released on November 28, 2011
(Trac #1329, git 1aa233fab1d74dc776899df61181806679d14013)
312. [func] jelte
- Added an initial framework for doing system tests using the
+ Added an initial framework for doing system tests using the
cucumber-based BDD tool Lettuce. A number of general steps are
included, for instance running bind10 with specific
configurations, sending queries, and inspecting query answers. A
@@ -1349,7 +1356,7 @@ bind10-devel-20110705 released on July 05, 2011
(Trac #710, git dae1d2e24f993e1eef9ab429326652f40a006dfb)
257. [bug] y-aharen
- Fixed a bug an instance of IntervalTimerImpl may be destructed
+ Fixed a bug an instance of IntervalTimerImpl may be destructed
while deadline_timer is holding the handler. This fix addresses
occasional failure of IntervalTimerTest.destructIntervalTimer.
(Trac #957, git e59c215e14b5718f62699ec32514453b983ff603)
@@ -2019,7 +2026,7 @@ bind10-devel-20110120 released on January 20, 2011
(Trac #513, git 285c5ee3d5582ed6df02d1aa00387f92a74e3695)
151. [bug] smann
- lib/log/dummylog.h:
+ 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
@@ -2327,11 +2334,11 @@ bind10-devel-20101201 released on December 01, 2010
104. [bug] jerry
bin/zonemgr: zonemgr should be attempting to refresh expired zones.
(Trac #336, r3139)
-
+
103. [bug] jerry
lib/python/isc/log: Fixed an issue with python logging,
python log shouldn't die with OSError. (Trac #267, r3137)
-
+
102. [build] jinmei
Disable threads in ASIO to minimize build time dependency.
(Trac #345, r3100)
@@ -2366,7 +2373,7 @@ bind10-devel-20101201 released on December 01, 2010
it can be customized; Make sure --disable-static works.
(Trac #325, r2976)
-bind10-devel-20100917 released on September 17, 2010
+bind10-devel-20100917 released on September 17, 2010
95. [doc] jreed
Add b10-zonemgr manual page. Update other docs to introduce
@@ -2419,14 +2426,14 @@ bind10-devel-20100917 released on September 17, 2010
reason. (Trac #296, r2761)
87. [func] zhanglikun
- lib/python/isc/notifyout: Add the feature of notify-out, when
+ lib/python/isc/notifyout: Add the feature of notify-out, when
zone axfr/ixfr finishing, the server will notify its slaves.
(Trac #289, svn r2737)
86. [func] jerry
- bin/zonemgr: Added zone manager module. The zone manager is one
- of the co-operating processes of BIND10, which keeps track of
- timers and other information necessary for BIND10 to act as a
+ bin/zonemgr: Added zone manager module. The zone manager is one
+ of the co-operating processes of BIND10, which keeps track of
+ timers and other information necessary for BIND10 to act as a
slave. (Trac #215, svn r2737)
85. [build]* jinmei
@@ -2439,7 +2446,7 @@ bind10-devel-20100917 released on September 17, 2010
bind10-devel-20100812 released on August 12, 2010
84. [bug] jinmei, jerry
- This is a quick fix patch for the issue: AXFR fails half the
+ This is a quick fix patch for the issue: AXFR fails half the
time because of connection problems. xfrout client will make
a new connection every time. (Trac #299, svn r2697)
@@ -2489,7 +2496,7 @@ bind10-devel-20100812 released on August 12, 2010
(Trac #256, r2549)
77. [func] zhanglikun
- Make error message be more friendly when running cmdctl and it's
+ Make error message be more friendly when running cmdctl and it's
already running (listening on same port)(Trac #277, r2540)
76. [bug] jelte
@@ -2545,8 +2552,8 @@ bind10-devel-20100701 released on July 1, 2010
68. [func] zhanglikun
Add options -c (--certificate-chain) to bindctl. Override class
HTTPSConnection to support server certificate validation.
- Add support to cmdctl.spec file, now there are three configurable
- items for cmdctl: 'key_file', 'cert_file' and 'accounts_file',
+ Add support to cmdctl.spec file, now there are three configurable
+ items for cmdctl: 'key_file', 'cert_file' and 'accounts_file',
all of them can be changed in runtime.
(Trac #127, svn r2357)
@@ -2566,7 +2573,7 @@ bind10-devel-20100701 released on July 1, 2010
section; this, among other things, will prevent multiple copies
of the same CNAME from showing up when there's a loop. (Trac #69,
svn r2350)
-
+
65. [func] shentingting
Various loadzone improvements: allow optional comment for
$TTL, allow optional origin and comment for $INCLUDE, allow
@@ -2587,7 +2594,7 @@ bind10-devel-20100701 released on July 1, 2010
63. [func] shane
Added initial support for setuid(), using the "-u" flag. This will
- be replaced in the future, but for now provides a reasonable
+ be replaced in the future, but for now provides a reasonable
starting point.
(Trac #180, svn r2330)
@@ -2636,17 +2643,17 @@ bind10-devel-20100701 released on July 1, 2010
(Trac #224, svn r2103)
53. [bug] zhanglikun
- bin/bindctl: Generate a unique session ID by using
- socket.gethostname() instead of socket.gethostbyname(),
- since the latter one could make bindctl stall if its own
+ bin/bindctl: Generate a unique session ID by using
+ socket.gethostname() instead of socket.gethostbyname(),
+ since the latter one could make bindctl stall if its own
host name can't be resolved.
(Trac #228, svn r2096)
52. [func] zhanglikun
bin/xfrout: When xfrout is launched, check whether the
- socket file is being used by one running xfrout process,
- if it is, exit from python. If the file isn't a socket file
- or nobody is listening, it will be removed. If it can't
+ socket file is being used by one running xfrout process,
+ if it is, exit from python. If the file isn't a socket file
+ or nobody is listening, it will be removed. If it can't
be removed, exit from python.
(Trac #151, svn r2091)
@@ -2659,7 +2666,7 @@ bind10-devel-20100602 released on June 2, 2010
(Trac #223)
50. [bug] zhanglikun
- bin/xfrin: a regression in xfrin: it can't communicate with
+ bin/xfrin: a regression in xfrin: it can't communicate with
a remote server. (Trac #218, svn r2038)
49. [func]* jelte
diff --git a/src/bin/auth/auth.spec.pre.in b/src/bin/auth/auth.spec.pre.in
index 3eeb35e..7606be4 100644
--- a/src/bin/auth/auth.spec.pre.in
+++ b/src/bin/auth/auth.spec.pre.in
@@ -131,6 +131,16 @@
"item_optional": true, "item_default": "memory"
}
]
+ },
+ {
+ "command_name": "start_ddns_forwarder",
+ "command_description": "(Re)start internal forwarding of DDNS Update messages. This is automatically called if b10-ddns is started, and is not expected to be called by administrators; it will be removed as a public command in the future.",
+ "command_args": []
+ },
+ {
+ "command_name": "stop_ddns_forwarder",
+ "command_description": "Stop internal forwarding of DDNS Update messages. This is automatically called if b10-ddns is stopped, and is not expected to be called by administrators; it will be removed as a public command in the future.",
+ "command_args": []
}
],
"statistics": [
diff --git a/src/bin/auth/auth_messages.mes b/src/bin/auth/auth_messages.mes
index 61de3ee..e964b05 100644
--- a/src/bin/auth/auth_messages.mes
+++ b/src/bin/auth/auth_messages.mes
@@ -110,9 +110,6 @@ look into the cause and address the issue. The log message includes
the client's address (and port), and the error message sent from the
lower layer that detects the failure.
-% AUTH_RECEIVED_NOTIFY received incoming NOTIFY for zone name %1, zone class %2
-This is a debug message reporting that an incoming NOTIFY was received.
-
% AUTH_NOTIFY_QUESTIONS invalid number of questions (%1) in incoming NOTIFY
This debug message is logged by the authoritative server when it receives
a NOTIFY packet that contains zero or more than one question. (A valid
@@ -169,6 +166,9 @@ bug ticket for this issue.
This is a debug message issued when the authoritative server has received
a command on the command channel.
+% AUTH_RECEIVED_NOTIFY received incoming NOTIFY for zone name %1, zone class %2
+This is a debug message reporting that an incoming NOTIFY was received.
+
% AUTH_RECEIVED_SENDSTATS command 'sendstats' received
This is a debug message issued when the authoritative server has received
a command from the statistics module to send it data. The 'sendstats'
@@ -235,6 +235,13 @@ This is a debug message indicating that the authoritative server has
found that the data source it is loading is an SQLite3 data source,
so no further validation is needed.
+% AUTH_START_DDNS_FORWARDER DDNS UPDATE handling started
+This is a debug message indicating that b10-auth has received a message
+that it should internally forward UPDATE message to b10-ddns. When b10-ddns
+is not running, b10-auth will respond to UPDATE requests with rcode NOTIMP.
+When b10-ddns is running, b10-ddns will handle and respond to the UPDATE
+message.
+
% AUTH_STATS_CHANNEL_CREATED STATS session channel created
This is a debug message indicating that the authoritative server has
created a channel to the statistics process. It is issued during server
@@ -266,6 +273,15 @@ This is a debug message indicating that the statistics timer has been
enabled and that the authoritative server will produce statistics data
at the specified interval.
+% AUTH_STOP_DDNS_FORWARDER DDNS UPDATE handling stopped
+This is a debug message indicating that b10-auth has received a message
+that it should stop internally forwarding UPDATE message to b10-ddns.
+b10-auth will no longer forward UPDATE messages to b10-ddns, but will
+respond itself with error code NOTIMP.
+This message is also logged when the forwarding is restarted (for instance
+if b10-ddns is restarted and the internal connection needs to be created
+again), in which case it should be followed by AUTH_START_DDNS_FORWARDER.
+
% AUTH_UNSUPPORTED_OPCODE unsupported opcode: %1
This is a debug message, produced when a received DNS packet being
processed by the authoritative server has been found to contain an
diff --git a/src/bin/auth/auth_srv.cc b/src/bin/auth/auth_srv.cc
index 7b8e963..e8176c3 100644
--- a/src/bin/auth/auth_srv.cc
+++ b/src/bin/auth/auth_srv.cc
@@ -58,6 +58,7 @@
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
+#include <boost/scoped_ptr.hpp>
#include <algorithm>
#include <cassert>
@@ -270,6 +271,14 @@ public:
/// isc:config::ModuleSpec::validateStatistics.
void registerStatisticsValidator();
+ /// Socket session forwarder for dynamic update requests
+ BaseSocketSessionForwarder& ddns_base_forwarder_;
+
+ /// Holder for the DDNS Forwarder, which is used to send
+ /// DDNS messages to b10-ddns, but can be set to empty if
+ /// b10-ddns is not running
+ boost::scoped_ptr<SocketSessionForwarderHolder> ddns_forwarder_;
+
/// \brief Resume the server
///
/// This is a wrapper call for DNSServer::resume(done), if 'done' is true,
@@ -285,6 +294,7 @@ public:
void resumeServer(isc::asiodns::DNSServer* server,
isc::dns::Message& message,
bool done);
+
private:
std::string db_file_;
@@ -297,9 +307,6 @@ private:
bool xfrout_connected_;
AbstractXfroutClient& xfrout_client_;
- // Socket session forwarder for dynamic update requests
- SocketSessionForwarderHolder ddns_forwarder_;
-
/// Increment query counter
void incCounter(const int protocol);
@@ -318,9 +325,10 @@ AuthSrvImpl::AuthSrvImpl(const bool use_cache,
statistics_timer_(io_service_),
counters_(),
keyring_(NULL),
+ ddns_base_forwarder_(ddns_forwarder),
+ ddns_forwarder_(NULL),
xfrout_connected_(false),
- xfrout_client_(xfrout_client),
- ddns_forwarder_("update", ddns_forwarder)
+ xfrout_client_(xfrout_client)
{
// cur_datasrc_ is automatically initialized by the default constructor,
// effectively being an empty (sqlite) data source. once ccsession is up
@@ -456,7 +464,7 @@ makeErrorMessage(MessageRenderer& renderer, Message& message,
for_each(questions.begin(), questions.end(), QuestionInserter(message));
message.setRcode(rcode);
-
+
RendererHolder holder(renderer, &buffer);
if (tsig_context.get() != NULL) {
message.toWire(renderer, *tsig_context);
@@ -653,7 +661,12 @@ AuthSrv::processMessage(const IOMessage& io_message, Message& message,
send_answer = impl_->processNotify(io_message, message, buffer,
tsig_context);
} else if (opcode == Opcode::UPDATE()) {
- send_answer = impl_->processUpdate(io_message);
+ if (impl_->ddns_forwarder_) {
+ send_answer = impl_->processUpdate(io_message);
+ } else {
+ makeErrorMessage(impl_->renderer_, message, buffer,
+ Rcode::NOTIMP(), tsig_context);
+ }
} else if (opcode != Opcode::QUERY()) {
LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_UNSUPPORTED_OPCODE)
.arg(message.getOpcode().toText());
@@ -880,7 +893,7 @@ AuthSrvImpl::processUpdate(const IOMessage& io_message) {
// Push the update request to a separate process via the forwarder.
// On successful push, the request shouldn't be responded from b10-auth,
// so we return false.
- ddns_forwarder_.push(io_message);
+ ddns_forwarder_->push(io_message);
return (false);
}
@@ -1027,3 +1040,20 @@ void
AuthSrv::setTSIGKeyRing(const boost::shared_ptr<TSIGKeyRing>* keyring) {
impl_->keyring_ = keyring;
}
+
+void
+AuthSrv::createDDNSForwarder() {
+ LOG_DEBUG(auth_logger, DBG_AUTH_OPS, AUTH_START_DDNS_FORWARDER);
+ impl_->ddns_forwarder_.reset(
+ new SocketSessionForwarderHolder("update", impl_->ddns_base_forwarder_));
+}
+
+void
+AuthSrv::destroyDDNSForwarder() {
+ if (impl_->ddns_forwarder_) {
+ LOG_DEBUG(auth_logger, DBG_AUTH_OPS, AUTH_STOP_DDNS_FORWARDER);
+ impl_->ddns_forwarder_.reset();
+ }
+}
+
+
diff --git a/src/bin/auth/auth_srv.h b/src/bin/auth/auth_srv.h
index 18d7503..d40a490 100644
--- a/src/bin/auth/auth_srv.h
+++ b/src/bin/auth/auth_srv.h
@@ -111,7 +111,7 @@ public:
/// This method should never throw an exception.
void stop();
- /// \brief Process an incoming DNS message, then signal 'server' to resume
+ /// \brief Process an incoming DNS message, then signal 'server' to resume
///
/// A DNS query (or other message) has been received by a \c DNSServer
/// object. Find an answer, then post the \c DNSServer object on the
@@ -355,13 +355,13 @@ public:
bool submitStatistics() const;
/// \brief Get the value of counter in the AuthCounters.
- ///
+ ///
/// This function calls AuthCounters::getCounter() and
/// returns its return value.
///
/// This function never throws an exception as far as
/// AuthCounters::getCounter() doesn't throw.
- ///
+ ///
/// Note: Currently this function is for testing purpose only.
///
/// \param type Type of a counter to get the value of
@@ -418,6 +418,25 @@ public:
void setTSIGKeyRing(const boost::shared_ptr<isc::dns::TSIGKeyRing>*
keyring);
+ /// \brief Create the internal forwarder for DDNS update messages
+ ///
+ /// Until this method is called (it is called when the
+ /// start_ddns_forwarder command is sent to b10-auth), b10-auth will
+ /// respond to UPDATE messages with a NOTIMP rcode.
+ /// If the internal forwarder was already created, it is destroyed and
+ /// created again. This is useful for instance when b10-ddns is shut
+ /// down and restarted.
+ void createDDNSForwarder();
+
+ /// \brief Destroy the internal forwarder for DDNS update messages
+ ///
+ /// After this method has been called (it is called when the
+ /// stop_ddns_forwarder command is sent to b10-auth), DDNS Update
+ /// messages are no longer forwarded internally, but b10-auth will
+ /// immediately respond with a NOTIMP rcode.
+ /// If there was no forwarder yet, this method does nothing.
+ void destroyDDNSForwarder();
+
private:
AuthSrvImpl* impl_;
isc::asiolink::SimpleCallback* checkin_;
@@ -428,6 +447,6 @@ private:
#endif // __AUTH_SRV_H
-// Local Variables:
+// Local Variables:
// mode: c++
-// End:
+// End:
diff --git a/src/bin/auth/command.cc b/src/bin/auth/command.cc
index 750ea28..aaaa5b6 100644
--- a/src/bin/auth/command.cc
+++ b/src/bin/auth/command.cc
@@ -141,6 +141,20 @@ public:
}
};
+class StartDDNSForwarderCommand : public AuthCommand {
+public:
+ virtual void exec(AuthSrv& server, isc::data::ConstElementPtr) {
+ server.createDDNSForwarder();
+ }
+};
+
+class StopDDNSForwarderCommand : public AuthCommand {
+public:
+ virtual void exec(AuthSrv& server, isc::data::ConstElementPtr) {
+ server.destroyDDNSForwarder();
+ }
+};
+
// Handle the "loadzone" command.
class LoadZoneCommand : public AuthCommand {
public:
@@ -309,6 +323,10 @@ createAuthCommand(const string& command_id) {
return (new SendStatsCommand());
} else if (command_id == "loadzone") {
return (new LoadZoneCommand());
+ } else if (command_id == "start_ddns_forwarder") {
+ return (new StartDDNSForwarderCommand());
+ } else if (command_id == "stop_ddns_forwarder") {
+ return (new StopDDNSForwarderCommand());
} else if (false && command_id == "_throw_exception") {
// This is for testing purpose only and should not appear in the
// actual configuration syntax.
diff --git a/src/bin/auth/common.cc b/src/bin/auth/common.cc
index 2c21895..26466da 100644
--- a/src/bin/auth/common.cc
+++ b/src/bin/auth/common.cc
@@ -57,3 +57,4 @@ getDDNSSocketPath() {
}
const char* const AUTH_NAME = "b10-auth";
+const char* const AUTH_STARTED_NOTIFICATION = "auth_started";
diff --git a/src/bin/auth/common.h b/src/bin/auth/common.h
index 9a1942c..0964217 100644
--- a/src/bin/auth/common.h
+++ b/src/bin/auth/common.h
@@ -57,6 +57,11 @@ std::string getDDNSSocketPath();
/// This is currently b10-auth, but it can be changed easily in one place.
extern const char* const AUTH_NAME;
+/// \brief Notification string that is used to inform auth is starting
+///
+/// This is sent to interested modules (currently only b10-ddns)
+extern const char* const AUTH_STARTED_NOTIFICATION;
+
#endif // __COMMON_H
// Local Variables:
diff --git a/src/bin/auth/main.cc b/src/bin/auth/main.cc
index cf4f52e..fc3b6b6 100644
--- a/src/bin/auth/main.cc
+++ b/src/bin/auth/main.cc
@@ -210,6 +210,12 @@ main(int argc, char* argv[]) {
// Successfully initialized.
LOG_INFO(auth_logger, AUTH_SERVER_STARTED);
+
+ // Ping any interested module that (a new) auth is up
+ // Currently, only the DDNS module is notified, but we could consider
+ // make an announcement channel for these (one-way) messages
+ cc_session->group_sendmsg(
+ isc::config::createCommand(AUTH_STARTED_NOTIFICATION), "DDNS");
io_service.run();
} catch (const std::exception& ex) {
diff --git a/src/bin/auth/tests/auth_srv_unittest.cc b/src/bin/auth/tests/auth_srv_unittest.cc
index 0a41f5d..0a9efe1 100644
--- a/src/bin/auth/tests/auth_srv_unittest.cc
+++ b/src/bin/auth/tests/auth_srv_unittest.cc
@@ -31,6 +31,7 @@
#include <datasrc/memory_datasrc.h>
#include <auth/auth_srv.h>
+#include <auth/command.h>
#include <auth/common.h>
#include <auth/statistics.h>
@@ -99,6 +100,7 @@ protected:
server.setDNSService(dnss_);
server.setXfrinSession(¬ify_session);
server.setStatisticsSession(&statistics_session);
+ server.createDDNSForwarder();
}
~AuthSrvTest() {
@@ -106,6 +108,7 @@ protected:
// type information may be lost if the message is cleared
// automatically later, so as a precaution we do it now.
parse_message->clear(Message::PARSE);
+ server.destroyDDNSForwarder();
}
virtual void processMessage() {
@@ -1625,6 +1628,7 @@ TEST_F(AuthSrvTest, DDNSForwardPushFail) {
TEST_F(AuthSrvTest, DDNSForwardClose) {
scoped_ptr<AuthSrv> tmp_server(new AuthSrv(true, xfrout, ddns_forwarder));
+ tmp_server->createDDNSForwarder();
UnitTestUtil::createRequestMessage(request_message, Opcode::UPDATE(),
default_qid, Name("example.com"),
RRClass::IN(), RRType::SOA());
@@ -1639,4 +1643,85 @@ TEST_F(AuthSrvTest, DDNSForwardClose) {
EXPECT_FALSE(ddns_forwarder.isConnected());
}
+namespace {
+ // Send a basic command without arguments, and check the response has
+ // result code 0
+ void sendSimpleCommand(AuthSrv& server, const std::string& command) {
+ ConstElementPtr response = execAuthServerCommand(server, command,
+ ConstElementPtr());
+ int command_result = -1;
+ isc::config::parseAnswer(command_result, response);
+ EXPECT_EQ(0, command_result);
+ }
+} // end anonymous namespace
+
+TEST_F(AuthSrvTest, DDNSForwardCreateDestroy) {
+ // Test that AuthSrv returns NOTIMP before ddns forwarder is created,
+ // that the ddns_forwarder is connected when the 'start_ddns_forwarder'
+ // command has been sent, and that it is no longer connected and auth
+ // returns NOTIMP after the stop_ddns_forwarding command is sent.
+ scoped_ptr<AuthSrv> tmp_server(new AuthSrv(true, xfrout, ddns_forwarder));
+
+ // Prepare update message to send
+ UnitTestUtil::createRequestMessage(request_message, Opcode::UPDATE(),
+ default_qid, Name("example.com"),
+ RRClass::IN(), RRType::SOA());
+ createRequestPacket(request_message, IPPROTO_UDP);
+
+ // before creating forwarder. isConnected() should be false and
+ // rcode to UPDATE should be NOTIMP
+ parse_message->clear(Message::PARSE);
+ tmp_server->processMessage(*io_message, *parse_message, *response_obuffer,
+ &dnsserv);
+ EXPECT_FALSE(ddns_forwarder.isConnected());
+ EXPECT_TRUE(dnsserv.hasAnswer());
+ headerCheck(*parse_message, default_qid, Rcode::NOTIMP(),
+ Opcode::UPDATE().getCode(), QR_FLAG, 0, 0, 0, 0);
+
+ // now create forwarder
+ sendSimpleCommand(*tmp_server, "start_ddns_forwarder");
+
+ // our mock does not respond, and since auth is supposed to send it on,
+ // there should now be no result when an UPDATE is sent
+ parse_message->clear(Message::PARSE);
+ tmp_server->processMessage(*io_message, *parse_message, *response_obuffer,
+ &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
+ EXPECT_TRUE(ddns_forwarder.isConnected());
+
+ // If we send a start again, the connection should be recreated,
+ // visible because isConnected() reports false until an actual message
+ // has been forwarded
+ sendSimpleCommand(*tmp_server, "start_ddns_forwarder");
+
+ EXPECT_FALSE(ddns_forwarder.isConnected());
+ parse_message->clear(Message::PARSE);
+ tmp_server->processMessage(*io_message, *parse_message, *response_obuffer,
+ &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
+ EXPECT_TRUE(ddns_forwarder.isConnected());
+
+ // Now tell it to stop forwarder, should respond with NOTIMP again
+ sendSimpleCommand(*tmp_server, "stop_ddns_forwarder");
+
+ parse_message->clear(Message::PARSE);
+ tmp_server->processMessage(*io_message, *parse_message, *response_obuffer,
+ &dnsserv);
+ EXPECT_FALSE(ddns_forwarder.isConnected());
+ EXPECT_TRUE(dnsserv.hasAnswer());
+ headerCheck(*parse_message, default_qid, Rcode::NOTIMP(),
+ Opcode::UPDATE().getCode(), QR_FLAG, 0, 0, 0, 0);
+
+ // Sending stop again should make no difference
+ sendSimpleCommand(*tmp_server, "stop_ddns_forwarder");
+
+ parse_message->clear(Message::PARSE);
+ tmp_server->processMessage(*io_message, *parse_message, *response_obuffer,
+ &dnsserv);
+ EXPECT_FALSE(ddns_forwarder.isConnected());
+ EXPECT_TRUE(dnsserv.hasAnswer());
+ headerCheck(*parse_message, default_qid, Rcode::NOTIMP(),
+ Opcode::UPDATE().getCode(), QR_FLAG, 0, 0, 0, 0);
+}
+
}
diff --git a/src/bin/ddns/ddns.py.in b/src/bin/ddns/ddns.py.in
index 70acf72..eaeb06c 100755
--- a/src/bin/ddns/ddns.py.in
+++ b/src/bin/ddns/ddns.py.in
@@ -228,6 +228,9 @@ class DDNSServer:
# Outstanding TCP context: fileno=>(context_obj, dst)
self._tcp_ctxs = {}
+ # Notify Auth server that DDNS update messages can now be forwarded
+ self.__notify_start_forwarder()
+
class InternalError(Exception):
'''Exception for internal errors in an update session.
@@ -274,6 +277,9 @@ class DDNSServer:
logger.info(DDNS_RECEIVED_SHUTDOWN_COMMAND)
self.trigger_shutdown()
answer = create_answer(0)
+ elif cmd == "auth_started":
+ self.__notify_start_forwarder()
+ answer = None
else:
answer = create_answer(1, "Unknown command: " + str(cmd))
return answer
@@ -378,6 +384,8 @@ class DDNSServer:
Do NOT call this to initialize shutdown, use trigger_shutdown().
'''
+ # tell Auth not to forward UPDATE messages anymore
+ self.__notify_stop_forwarder()
# tell the ModuleCCSession to send a message that this module is
# stopping.
self._cc.send_stopping()
@@ -533,6 +541,32 @@ class DDNSServer:
return True
+ def __notify_start_forwarder(self):
+ '''Notify auth that DDNS Update messages can now be forwarded'''
+ try:
+ seq = self._cc._session.group_sendmsg(create_command(
+ "start_ddns_forwarder"), AUTH_MODULE_NAME)
+ answer, _ = self._cc._session.group_recvmsg(False, seq)
+ rcode, error_msg = parse_answer(answer)
+ if rcode != 0:
+ logger.error(DDNS_START_FORWARDER_ERROR, error_msg)
+ except (SessionTimeout, SessionError, ProtocolError) as ex:
+ logger.error(DDNS_START_FORWARDER_FAIL, ex)
+
+ def __notify_stop_forwarder(self):
+ '''Notify auth that DDNS Update messages should no longer be forwarded.
+
+ '''
+ try:
+ seq = self._cc._session.group_sendmsg(create_command(
+ "stop_ddns_forwarder"), AUTH_MODULE_NAME)
+ answer, _ = self._cc._session.group_recvmsg(False, seq)
+ rcode, error_msg = parse_answer(answer)
+ if rcode != 0:
+ logger.error(DDNS_STOP_FORWARDER_ERROR, error_msg)
+ except (SessionTimeout, SessionError, ProtocolError) as ex:
+ logger.error(DDNS_STOP_FORWARDER_FAIL, ex)
+
def __notify_auth(self, zname, zclass):
'''Notify auth of the update, if necessary.'''
msg = auth_loadzone_command(self._cc, zname, zclass)
diff --git a/src/bin/ddns/ddns_messages.mes b/src/bin/ddns/ddns_messages.mes
index 92099fd..d128361 100644
--- a/src/bin/ddns/ddns_messages.mes
+++ b/src/bin/ddns/ddns_messages.mes
@@ -192,6 +192,25 @@ be completed, after which the process will exit.
The ddns process has successfully started and is now ready to receive commands
and updates.
+% DDNS_START_FORWARDER_ERROR Error from b10-auth when requesting DDNS UPDATE forwarding: %1
+There was an error response from b10-auth to the command to start
+forwarding DDNS UPDATE messages to b10-ddns.
+It is almost certain that DDNS UPDATE messages are not handled now, and that
+they will be responded to with a NOTIMP error code, even though b10-ddns is
+running.
+The error message is printed, and additional information may be found in
+the b10-auth log output. Since this is an error that is sent by the
+b10-auth module, it should have more information as to what the actual
+problem was.
+
+% DDNS_START_FORWARDER_FAIL Error sending request for DDNS UPDATE forwarding to b10-auth: %1
+There was an error when attempting to send b10-auth the request to forward
+DDNS UPDATE messages to the b10-ddns module. This points to an internal
+problem using the inter-module messaging system.
+This needs to be inspected, as it is almost certain that DDNS UPDATE messages
+are not handled now.
+The specific error is printed in the log message.
+
% DDNS_STOPPED ddns server has stopped
The ddns process has successfully stopped and is no longer listening for or
handling commands or updates, and will now exit.
@@ -200,6 +219,24 @@ handling commands or updates, and will now exit.
There was a keyboard interrupt signal to stop the ddns process. The
process will now shut down.
+% DDNS_STOP_FORWARDER_ERROR Error from b10-auth when requesting to stop DDNS UPDATE forwarding: %1
+There was an error response from b10-auth to the command to stop
+forwarding DDNS UPDATE messages to b10-ddns.
+This specific error may not be fatal; instead of returning NOTIMP for future
+DDNS UPDATE messages, it will return SERVFAIL. However, this does point to
+an underlying problem in the messaging system, and should be inspected.
+The error message is printed, and additional information may be found in
+the b10-auth log output.
+
+% DDNS_STOP_FORWARDER_FAIL Error sending request to stop DDNS UPDATE forwarding to b10-auth: %1
+There was an error when attempting to send b10-auth the request to stop
+forwarding DDNS UPDATE messages to the b10-ddns module. This points to an
+internal problem using the inter-module messaging system.
+This specific error may not be fatal; instead of returning NOTIMP for future
+DDNS UPDATE messages, it will return SERVFAIL. However, this does point to
+an underlying problem in the messaging system, and should be inspected.
+The specific error is printed in the log message.
+
% DDNS_UNCAUGHT_EXCEPTION uncaught exception of type %1: %2
The b10-ddns process encountered an uncaught exception and will now shut
down. This is indicative of a programming error and should not happen under
diff --git a/src/bin/ddns/tests/ddns_test.py b/src/bin/ddns/tests/ddns_test.py
index 3343031..b634415 100755
--- a/src/bin/ddns/tests/ddns_test.py
+++ b/src/bin/ddns/tests/ddns_test.py
@@ -918,6 +918,10 @@ class TestDDNSSession(unittest.TestCase):
self.orig_tsig_keyring = isc.server_common.tsig_keyring
isc.server_common.tsig_keyring = FakeKeyringModule()
self.server = ddns.DDNSServer(self.__cc_session)
+ # Check that start_ddns_forwarder has been called upon
+ # initialization (before we do anything else that might
+ # cause messages to be sent)
+ self.check_session_start_forwarder_called()
self.server._UpdateSessionClass = self.__fake_session_creator
self.__faked_result = UPDATE_SUCCESS # will be returned by fake session
self.__sock = FakeSocket(-1)
@@ -1179,8 +1183,33 @@ class TestDDNSSession(unittest.TestCase):
self.assertEqual([], self.__cc_session._sent_msg)
self.assertEqual(0, self.__cc_session._recvmsg_called)
+ def check_session_start_forwarder_called(self):
+ '''Check that the command 'start_ddns_forwarder' has been called
+ This test removes said message from the sent message queue.
+ '''
+ sent_msg, sent_group = self.__cc_session._sent_msg.pop(0)
+ sent_cmd = sent_msg['command']
+ self.assertEqual('Auth', sent_group)
+ self.assertEqual('start_ddns_forwarder', sent_cmd[0])
+ self.assertEqual(1, len(sent_cmd))
+ self.assertEqual(1, self.__cc_session._recvmsg_called)
+ # reset it for other tests
+ self.__cc_session._recvmsg_called = 0
+
+ def check_session_stop_forwarder_called(self):
+ '''Check that the command 'stop_ddns_forwarder' has been called
+ This test removes said message from the sent message queue.
+ '''
+ # check the last message sent
+ sent_msg, sent_group = self.__cc_session._sent_msg.pop()
+ sent_cmd = sent_msg['command']
+ self.assertEqual('Auth', sent_group)
+ self.assertEqual('stop_ddns_forwarder', sent_cmd[0])
+ self.assertEqual(1, len(sent_cmd))
+
def test_session_msg(self):
'''Test post update communication with other modules.'''
+
# Normal cases, confirming communication takes place iff update
# succeeds
for r in [UPDATE_SUCCESS, UPDATE_ERROR, UPDATE_DROP]:
@@ -1224,8 +1253,14 @@ class TestDDNSSession(unittest.TestCase):
self.__cc_session._sendmsg_exception = RuntimeError('unexpected')
self.assertRaises(RuntimeError, self.check_session)
+ def test_session_shutdown_cleanup(self):
+ '''Test that the stop forwarding message is sent'''
+ self.server.shutdown_cleanup()
+ self.check_session_stop_forwarder_called()
+
def test_session_msg_for_auth(self):
'''Test post update communication with other modules including Auth.'''
+
# Let the CC session return in-memory config with sqlite3 backend.
# (The default case was covered by other tests.)
self.__cc_session.auth_datasources = \
@@ -1270,6 +1305,34 @@ class TestDDNSSession(unittest.TestCase):
# check the result
self.check_session(UPDATE_DROP)
+ def test_session_start_stop_forwarder_failures(self):
+ '''Check that we don't crash if the server reports an error
+ setting up or closing down the DDNS UPDATE message forwarder,
+ or if there is an exception from the message queue.'''
+ self.__cc_session._answer_code = 1
+ self.server._DDNSServer__notify_start_forwarder()
+ self.server._DDNSServer__notify_stop_forwarder()
+
+ for exc in [ SessionError("sessionerror"),
+ SessionTimeout("sessiontimeout"),
+ ProtocolError("protocolerror") ]:
+ self.__cc_session._recvmsg_exception = exc
+ self.server._DDNSServer__notify_start_forwarder()
+ self.server._DDNSServer__notify_stop_forwarder()
+ self.__cc_session._recvmsg_exception = None
+
+ self.__cc_session._sendmsg_exception = exc
+ self.server._DDNSServer__notify_start_forwarder()
+ self.server._DDNSServer__notify_stop_forwarder()
+ self.__cc_session._recvmsg_exception = None
+
+ def test_session_auth_started(self):
+ '''Check that 'start_ddns_forwarder' is sent (again) when the
+ notification 'auth_started' is received'''
+ # auth_started message should trigger it again
+ answer = self.server.command_handler('auth_started', None)
+ self.check_session_start_forwarder_called()
+
class TestMain(unittest.TestCase):
def setUp(self):
self._server = MyDDNSServer()
diff --git a/tests/lettuce/features/ddns_system.feature b/tests/lettuce/features/ddns_system.feature
index 327ef96..ee3187c 100644
--- a/tests/lettuce/features/ddns_system.feature
+++ b/tests/lettuce/features/ddns_system.feature
@@ -13,9 +13,8 @@ Feature: DDNS System
# Test 1
When I use DDNS to set the SOA serial to 1235
- # Note: test spec says refused here, system returns SERVFAIL
- #The DDNS response should be REFUSED
- The DDNS response should be SERVFAIL
+ # Note: test spec says refused here, system returns NOTIMP
+ The DDNS response should be NOTIMP
And the SOA serial for example.org should be 1234
# Test 2
@@ -53,15 +52,14 @@ Feature: DDNS System
And wait for new bind10 stderr message DDNS_STARTED
# Test 8
- # Known issue: after shutdown, first new attempt results in SERVFAIL
When I use DDNS to set the SOA serial to 1238
- The DDNS response should be SERVFAIL
- And the SOA serial for example.org should be 1237
+ The DDNS response should be SUCCESS
+ And the SOA serial for example.org should be 1238
- When I use DDNS to set the SOA serial to 1238
+ When I use DDNS to set the SOA serial to 1239
And wait for new bind10 stderr message AUTH_LOAD_ZONE
The DDNS response should be SUCCESS
- And the SOA serial for example.org should be 1238
+ And the SOA serial for example.org should be 1239
# Test 9
When I send bind10 the command Auth shutdown
@@ -70,10 +68,10 @@ Feature: DDNS System
And wait for new bind10 stderr message AUTH_SERVER_STARTED
# Test 10
- When I use DDNS to set the SOA serial to 1239
+ When I use DDNS to set the SOA serial to 1240
And wait for new bind10 stderr message AUTH_LOAD_ZONE
The DDNS response should be SUCCESS
- And the SOA serial for example.org should be 1239
+ And the SOA serial for example.org should be 1240
# Test 11
When I configure BIND10 to stop running DDNS
@@ -82,10 +80,10 @@ Feature: DDNS System
bind10 module DDNS should not be running
# Test 12
- When I use DDNS to set the SOA serial to 1240
+ When I use DDNS to set the SOA serial to 1241
# should this be REFUSED again?
- The DDNS response should be SERVFAIL
- And the SOA serial for example.org should be 1239
+ The DDNS response should be NOTIMP
+ And the SOA serial for example.org should be 1240
Scenario: ACL
Given I have bind10 running with configuration ddns/ddns.config
More information about the bind10-changes
mailing list