[svn] commit: r3216 - in /branches/trac191-rebased: ./ src/bin/ src/bin/auth/ src/bin/auth/tests/ src/bin/auth/tests/testdata/ src/bin/bind10/ src/bin/bind10/tests/ src/bin/bindctl/ src/bin/cfgmgr/ src/bin/cmdctl/ src/bin/host/ src/bin/loadzone/ src/bin/msgq/ src/bin/tests/ src/bin/usermgr/ src/bin/xfrin/ src/bin/xfrout/ src/bin/zonemgr/ src/bin/zonemgr/tests/ src/lib/bench/ src/lib/bench/tests/ src/lib/cc/tests/ src/lib/config/ src/lib/config/testdata/ src/lib/config/tests/ src/lib/config/tests/testdata/ src/lib/datasrc/ src/lib/datasrc/tests/ src/lib/dns/ src/lib/dns/python/ src/lib/dns/python/tests/ src/lib/dns/rdata/ src/lib/dns/tests/ src/lib/dns/tests/testdata/ src/lib/python/isc/ src/lib/python/isc/config/ src/lib/python/isc/config/tests/ src/lib/python/isc/log/ src/lib/python/isc/log/tests/ src/lib/python/isc/utils/
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Oct 15 05:19:20 UTC 2010
Author: naokikambe
Date: Fri Oct 15 05:19:19 2010
New Revision: 3216
Log:
- sync with trunk
- fix conflicts of ChangeLog and src/bin/Makefile.am
- change the entry of stats in ChangeLog
Added:
branches/trac191-rebased/src/bin/auth/tests/testdata/Makefile.am
- copied unchanged from r3215, trunk/src/bin/auth/tests/testdata/Makefile.am
branches/trac191-rebased/src/bin/tests/
- copied from r3215, trunk/src/bin/tests/
branches/trac191-rebased/src/bin/xfrin/xfrin.spec
- copied unchanged from r3215, trunk/src/bin/xfrin/xfrin.spec
branches/trac191-rebased/src/lib/config/tests/testdata/
- copied from r3215, trunk/src/lib/config/tests/testdata/
branches/trac191-rebased/src/lib/dns/opcode.cc
- copied unchanged from r3215, trunk/src/lib/dns/opcode.cc
branches/trac191-rebased/src/lib/dns/opcode.h
- copied unchanged from r3215, trunk/src/lib/dns/opcode.h
branches/trac191-rebased/src/lib/dns/python/opcode_python.cc
- copied unchanged from r3215, trunk/src/lib/dns/python/opcode_python.cc
branches/trac191-rebased/src/lib/dns/python/rcode_python.cc
- copied unchanged from r3215, trunk/src/lib/dns/python/rcode_python.cc
branches/trac191-rebased/src/lib/dns/python/tests/opcode_python_test.py
- copied unchanged from r3215, trunk/src/lib/dns/python/tests/opcode_python_test.py
branches/trac191-rebased/src/lib/dns/python/tests/rcode_python_test.py
- copied unchanged from r3215, trunk/src/lib/dns/python/tests/rcode_python_test.py
branches/trac191-rebased/src/lib/dns/rcode.cc
- copied unchanged from r3215, trunk/src/lib/dns/rcode.cc
branches/trac191-rebased/src/lib/dns/rcode.h
- copied unchanged from r3215, trunk/src/lib/dns/rcode.h
branches/trac191-rebased/src/lib/dns/tests/opcode_unittest.cc
- copied unchanged from r3215, trunk/src/lib/dns/tests/opcode_unittest.cc
branches/trac191-rebased/src/lib/dns/tests/rcode_unittest.cc
- copied unchanged from r3215, trunk/src/lib/dns/tests/rcode_unittest.cc
branches/trac191-rebased/src/lib/python/isc/utils/
- copied from r3215, trunk/src/lib/python/isc/utils/
Removed:
branches/trac191-rebased/src/bin/auth/tests/testdata/badExampleQuery_fromWire
branches/trac191-rebased/src/bin/auth/tests/testdata/examplequery_fromWire
branches/trac191-rebased/src/bin/auth/tests/testdata/iqueryresponse_fromWire
branches/trac191-rebased/src/bin/auth/tests/testdata/multiquestion_fromWire
branches/trac191-rebased/src/bin/auth/tests/testdata/queryBadEDNS_fromWire
branches/trac191-rebased/src/bin/auth/tests/testdata/shortanswer_fromWire
branches/trac191-rebased/src/bin/auth/tests/testdata/simplequery_fromWire
branches/trac191-rebased/src/bin/auth/tests/testdata/simpleresponse_fromWire
branches/trac191-rebased/src/bin/xfrin/xfrin.spec.pre.in
branches/trac191-rebased/src/lib/config/testdata/
branches/trac191-rebased/src/lib/dns/tests/testdata/message_fromWire10
branches/trac191-rebased/src/lib/dns/tests/testdata/message_fromWire11
branches/trac191-rebased/src/lib/dns/tests/testdata/name_toWire5
branches/trac191-rebased/src/lib/dns/tests/testdata/name_toWire6
branches/trac191-rebased/src/lib/dns/tests/testdata/rdata_nsec_fromWire10
branches/trac191-rebased/src/lib/dns/tests/testdata/rdata_nsec_fromWire4
branches/trac191-rebased/src/lib/dns/tests/testdata/rdata_nsec_fromWire5
branches/trac191-rebased/src/lib/dns/tests/testdata/rdata_nsec_fromWire6
branches/trac191-rebased/src/lib/dns/tests/testdata/rdata_nsec_fromWire7
branches/trac191-rebased/src/lib/dns/tests/testdata/rdata_nsec_fromWire8
branches/trac191-rebased/src/lib/dns/tests/testdata/rdata_nsec_fromWire9
branches/trac191-rebased/src/lib/dns/tests/testdata/rdata_rrsig_fromWire2
branches/trac191-rebased/src/lib/dns/tests/testdata/rdata_soa_toWireUncompressed
branches/trac191-rebased/src/lib/dns/tests/testdata/rdata_txt_fromWire2
branches/trac191-rebased/src/lib/dns/tests/testdata/rdata_txt_fromWire3
branches/trac191-rebased/src/lib/dns/tests/testdata/rdata_txt_fromWire4
branches/trac191-rebased/src/lib/dns/tests/testdata/rdata_txt_fromWire5
Modified:
branches/trac191-rebased/ (props changed)
branches/trac191-rebased/ChangeLog
branches/trac191-rebased/configure.ac
branches/trac191-rebased/src/bin/Makefile.am
branches/trac191-rebased/src/bin/auth/asio_link.cc
branches/trac191-rebased/src/bin/auth/auth_srv.cc
branches/trac191-rebased/src/bin/auth/auth_srv.h
branches/trac191-rebased/src/bin/auth/tests/Makefile.am
branches/trac191-rebased/src/bin/auth/tests/auth_srv_unittest.cc
branches/trac191-rebased/src/bin/auth/tests/run_unittests.cc
branches/trac191-rebased/src/bin/bind10/bind10.8
branches/trac191-rebased/src/bin/bind10/bind10.py.in
branches/trac191-rebased/src/bin/bind10/bind10.xml
branches/trac191-rebased/src/bin/bind10/tests/args_test.py
branches/trac191-rebased/src/bin/bindctl/bindctl-source.py.in
branches/trac191-rebased/src/bin/cfgmgr/b10-cfgmgr.py.in
branches/trac191-rebased/src/bin/cmdctl/Makefile.am
branches/trac191-rebased/src/bin/cmdctl/cmdctl.py.in
branches/trac191-rebased/src/bin/host/host.cc
branches/trac191-rebased/src/bin/loadzone/b10-loadzone.py.in
branches/trac191-rebased/src/bin/msgq/msgq.py.in
branches/trac191-rebased/src/bin/usermgr/b10-cmdctl-usermgr.py.in
branches/trac191-rebased/src/bin/xfrin/Makefile.am
branches/trac191-rebased/src/bin/xfrin/xfrin.py.in
branches/trac191-rebased/src/bin/xfrout/xfrout.py.in
branches/trac191-rebased/src/bin/zonemgr/tests/zonemgr_test.py
branches/trac191-rebased/src/bin/zonemgr/zonemgr.py.in
branches/trac191-rebased/src/bin/zonemgr/zonemgr.spec.pre.in
branches/trac191-rebased/src/lib/bench/benchmark_util.cc
branches/trac191-rebased/src/lib/bench/tests/loadquery_unittest.cc
branches/trac191-rebased/src/lib/cc/tests/Makefile.am
branches/trac191-rebased/src/lib/config/Makefile.am
branches/trac191-rebased/src/lib/config/tests/Makefile.am
branches/trac191-rebased/src/lib/config/tests/data_def_unittests_config.h.in
branches/trac191-rebased/src/lib/datasrc/data_source.cc
branches/trac191-rebased/src/lib/datasrc/tests/datasrc_unittest.cc
branches/trac191-rebased/src/lib/datasrc/tests/query_unittest.cc
branches/trac191-rebased/src/lib/dns/Makefile.am
branches/trac191-rebased/src/lib/dns/exceptions.cc
branches/trac191-rebased/src/lib/dns/message.cc
branches/trac191-rebased/src/lib/dns/message.h
branches/trac191-rebased/src/lib/dns/python/Makefile.am
branches/trac191-rebased/src/lib/dns/python/message_python.cc
branches/trac191-rebased/src/lib/dns/python/pydnspp.cc
branches/trac191-rebased/src/lib/dns/python/tests/Makefile.am
branches/trac191-rebased/src/lib/dns/python/tests/message_python_test.py
branches/trac191-rebased/src/lib/dns/python/tests/messagerenderer_python_test.py
branches/trac191-rebased/src/lib/dns/rdata/template.cc
branches/trac191-rebased/src/lib/dns/tests/Makefile.am
branches/trac191-rebased/src/lib/dns/tests/edns_unittest.cc
branches/trac191-rebased/src/lib/dns/tests/message_unittest.cc
branches/trac191-rebased/src/lib/dns/tests/messagerenderer_unittest.cc
branches/trac191-rebased/src/lib/dns/tests/rdata_nsec_unittest.cc
branches/trac191-rebased/src/lib/dns/tests/rdata_rrsig_unittest.cc
branches/trac191-rebased/src/lib/dns/tests/rdata_soa_unittest.cc
branches/trac191-rebased/src/lib/dns/tests/rdata_txt_unittest.cc
branches/trac191-rebased/src/lib/dns/tests/testdata/Makefile.am
branches/trac191-rebased/src/lib/dns/tests/testdata/gen-wiredata.py.in
branches/trac191-rebased/src/lib/python/isc/Makefile.am
branches/trac191-rebased/src/lib/python/isc/config/ccsession.py
branches/trac191-rebased/src/lib/python/isc/config/tests/Makefile.am
branches/trac191-rebased/src/lib/python/isc/config/tests/ccsession_test.py
branches/trac191-rebased/src/lib/python/isc/config/tests/cfgmgr_test.py
branches/trac191-rebased/src/lib/python/isc/config/tests/unittest_fakesession.py
branches/trac191-rebased/src/lib/python/isc/log/log.py
branches/trac191-rebased/src/lib/python/isc/log/tests/log_test.py
Modified: branches/trac191-rebased/ChangeLog
==============================================================================
--- branches/trac191-rebased/ChangeLog (original)
+++ branches/trac191-rebased/ChangeLog Fri Oct 15 05:19:19 2010
@@ -1,10 +1,51 @@
- XX. [func] naokikambe
+ XXX. [func] naokikambe
Added the initial version of the stats module for the statistics
feature of BIND 10, which supports the restricted features and
items and reports via bindctl command (Trac #191, rXXXX)
- [doc] kambe
Added the document of the stats module, which is about how stats
- module collects the data (Trac #170)
+ module collects the data (Trac #170, [wiki:StatsModule])
+
+ 108. [func] jerry
+ src/bin/zonemgr: Provide customizable configurations for
+ lowerbound_refresh, lowerbound_retry, max_transfer_timeout and
+ jitter_scope. (Trac #340, r3205)
+
+ 107. [func] zhang likun
+ Remove the parameter 'db_file' for command 'retransfer' of
+ xfrin module. xfrin.spec will not be generated by script.
+ (Trac #329, r3171)
+
+ 106. [bug] zhang likun
+ When xfrin can't connect with one zone's master, it should tell
+ the bad news to zonemgr, so that zonemgr can reset the timer for
+ that zone. (Trac #329, r3170)
+
+ 105. [bug] Michal Vaner
+ Python processes: they no longer take 100% CPU while idle
+ due to a busy loop in reading command session in a nonblocking way.
+ (Trac #349, svn r3153)
+
+ 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)
+
+ 101. [func] jinmei
+ src/lib/dns: Completed Opcode and Rcode implementation with more
+ tests and documentation. API is mostly the same but the
+ validation was a bit tightened. (Trac #351, svn r3056)
+
+ 100. [func] Michal Vaner
+ Python processes: support naming of python processes so
+ they're not all called python3.
+ (Trac #322, svn r3052)
99. [func]* jinmei
Introduced a separate EDNS class to encapsulate EDNS related
@@ -83,8 +124,8 @@
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
+ 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
slave. (Trac #215, svn r2737)
Modified: branches/trac191-rebased/configure.ac
==============================================================================
--- branches/trac191-rebased/configure.ac (original)
+++ branches/trac191-rebased/configure.ac Fri Oct 15 05:19:19 2010
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.59])
-AC_INIT(bind10-devel, 20100701, bind10-dev at isc.org)
+AC_INIT(bind10-devel, 20101013, bind10-dev at isc.org)
AC_CONFIG_SRCDIR(README)
AM_INIT_AUTOMAKE
AC_CONFIG_HEADERS([config.h])
@@ -47,6 +47,12 @@
if test $enable_shared = no; then
AC_MSG_ERROR([BIND 10 requires shared libraries to be built])
fi
+
+# allow configuring without setproctitle.
+AC_ARG_ENABLE(setproctitle-check,
+AC_HELP_STRING([--disable-setproctitle-check],
+ [do not check for python setproctitle module (used to give nice names to python processes)]),
+ setproctitle_check=$enableval, setproctitle_check=yes)
# OS dependent configuration
SET_ENV_LIBRARY_PATH=no
@@ -162,6 +168,18 @@
AC_SUBST(PYTHON_LIB)
LDFLAGS=$LDFLAGS_SAVED
+# Check for the setproctitle module
+if test "$setproctitle_check" = "yes" ; then
+ AC_MSG_CHECKING(for setproctitle module)
+ if "$PYTHON" -c 'import setproctitle' 2>/dev/null ; then
+ AC_MSG_RESULT(ok)
+ else
+ AC_MSG_RESULT(missing)
+ AC_MSG_ERROR([Missing setproctitle module. Either install it or provide --disable-setproctitle-check.
+In that case we will continue, but naming of python processes will not work.])
+ fi
+fi
+
# TODO: check for _sqlite3.py module
# Compiler dependent settings: define some mandatory CXXFLAGS here.
@@ -242,7 +260,6 @@
AC_ARG_WITH(gtest,
[ --with-gtest=PATH specify a path to gtest header files (PATH/include) and library (PATH/lib)],
gtest_path="$withval", gtest_path="no")
-
USE_LCOV="no"
if test "$lcov" != "no"; then
@@ -375,6 +392,9 @@
# Use local ASIO headers from ext
#
CPPFLAGS="$CPPFLAGS -I\$(top_srcdir)/ext/asio"
+#
+# Disable threads: Currently we don't use them.
+CPPFLAGS="$CPPFLAGS -DASIO_DISABLE_THREADS=1"
#
# kqueue portability: ASIO uses kqueue by default if it's available (it's
# generally available in BSD variants). Unfortunately, some public
@@ -414,7 +434,7 @@
fi
AC_ARG_ENABLE(man, [AC_HELP_STRING([--enable-man],
- [regenerate man pages [default=no]])] ,enable_man=yes, enable_man=no)
+ [regenerate man pages [default=no]])], enable_man=yes, enable_man=no)
AM_CONDITIONAL(ENABLE_MAN, test x$enable_man != xno)
@@ -443,6 +463,7 @@
src/bin/msgq/tests/Makefile
src/bin/auth/Makefile
src/bin/auth/tests/Makefile
+ src/bin/auth/tests/testdata/Makefile
src/bin/auth/benchmarks/Makefile
src/bin/xfrin/Makefile
src/bin/xfrin/tests/Makefile
@@ -453,6 +474,7 @@
src/bin/stats/Makefile
src/bin/stats/tests/Makefile
src/bin/usermgr/Makefile
+ src/bin/tests/Makefile
src/lib/Makefile
src/lib/bench/Makefile
src/lib/bench/example/Makefile
@@ -461,6 +483,8 @@
src/lib/cc/tests/Makefile
src/lib/python/Makefile
src/lib/python/isc/Makefile
+ src/lib/python/isc/utils/Makefile
+ src/lib/python/isc/utils/tests/Makefile
src/lib/python/isc/datasrc/Makefile
src/lib/python/isc/cc/Makefile
src/lib/python/isc/cc/tests/Makefile
@@ -472,7 +496,7 @@
src/lib/python/isc/notify/tests/Makefile
src/lib/config/Makefile
src/lib/config/tests/Makefile
- src/lib/config/testdata/Makefile
+ src/lib/config/tests/testdata/Makefile
src/lib/dns/Makefile
src/lib/dns/tests/Makefile
src/lib/dns/tests/testdata/Makefile
@@ -492,7 +516,6 @@
src/bin/cmdctl/cmdctl.spec.pre
src/bin/xfrin/tests/xfrin_test
src/bin/xfrin/xfrin.py
- src/bin/xfrin/xfrin.spec.pre
src/bin/xfrin/run_b10-xfrin.sh
src/bin/xfrout/xfrout.py
src/bin/xfrout/xfrout.spec.pre
@@ -525,6 +548,7 @@
src/bin/msgq/run_msgq.sh
src/bin/auth/auth.spec.pre
src/bin/auth/spec_config.h.pre
+ src/bin/tests/process_rename_test.py
src/lib/config/tests/data_def_unittests_config.h
src/lib/python/isc/config/tests/config_test
src/lib/python/isc/cc/tests/cc_test
Modified: branches/trac191-rebased/src/bin/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/bin/Makefile.am (original)
+++ branches/trac191-rebased/src/bin/Makefile.am Fri Oct 15 05:19:19 2010
@@ -1,1 +1,4 @@
-SUBDIRS = bind10 bindctl cfgmgr loadzone msgq host cmdctl auth xfrin xfrout usermgr zonemgr stats
+SUBDIRS = bind10 bindctl cfgmgr loadzone msgq host cmdctl auth xfrin xfrout \
+ usermgr zonemgr stats tests
+
+check-recursive: all-recursive
Modified: branches/trac191-rebased/src/bin/auth/asio_link.cc
==============================================================================
--- branches/trac191-rebased/src/bin/auth/asio_link.cc (original)
+++ branches/trac191-rebased/src/bin/auth/asio_link.cc Fri Oct 15 05:19:19 2010
@@ -64,24 +64,50 @@
return (asio_address_.to_string());
}
-// Note: this implementation is optimized for the case where this object
-// is created from an ASIO endpoint object in a receiving code path
-// by avoiding to make a copy of the base endpoint. For TCP it may not be
-// a big deal, but when we receive UDP packets at a high rate, the copy
-// overhead might be significant.
+/// \brief The \c TCPEndpoint class is a concrete derived class of
+/// \c IOEndpoint that represents an endpoint of a TCP connection.
+///
+/// In the current implementation, an object of this class is always
+/// instantiated within the wrapper routines. Applications are expected to
+/// get access to the object via the abstract base class, \c IOEndpoint.
+/// This design may be changed when we generalize the wrapper interface.
+///
+/// Note: this implementation is optimized for the case where this object
+/// is created from an ASIO endpoint object in a receiving code path
+/// by avoiding to make a copy of the base endpoint. For TCP it may not be
+/// a big deal, but when we receive UDP packets at a high rate, the copy
+/// overhead might be significant.
class TCPEndpoint : public IOEndpoint {
public:
+ ///
+ /// \name Constructors and Destructor
+ ///
+ //@{
+ /// \brief Constructor from a pair of address and port.
+ ///
+ /// \param address The IP address of the endpoint.
+ /// \param port The TCP port number of the endpoint.
TCPEndpoint(const IOAddress& address, const unsigned short port) :
asio_endpoint_placeholder_(
new tcp::endpoint(ip::address::from_string(address.toText()),
port)),
asio_endpoint_(*asio_endpoint_placeholder_)
{}
+
+ /// \brief Constructor from an ASIO TCP endpoint.
+ ///
+ /// This constructor is designed to be an efficient wrapper for the
+ /// corresponding ASIO class, \c tcp::endpoint.
+ ///
+ /// \param asio_endpoint The ASIO representation of the TCP endpoint.
TCPEndpoint(const tcp::endpoint& asio_endpoint) :
asio_endpoint_placeholder_(NULL), asio_endpoint_(asio_endpoint)
{}
-
+
+ /// \brief The destructor.
~TCPEndpoint() { delete asio_endpoint_placeholder_; }
+ //@}
+
virtual IOAddress getAddress() const {
return (asio_endpoint_.address());
}
@@ -90,18 +116,41 @@
const tcp::endpoint& asio_endpoint_;
};
+/// \brief The \c UDPEndpoint class is a concrete derived class of
+/// \c IOEndpoint that represents an endpoint of a UDP packet.
+///
+/// Other notes about \c TCPEndpoint applies to this class, too.
class UDPEndpoint : public IOEndpoint {
public:
+ ///
+ /// \name Constructors and Destructor.
+ ///
+ //@{
+ /// \brief Constructor from a pair of address and port.
+ ///
+ /// \param address The IP address of the endpoint.
+ /// \param port The UDP port number of the endpoint.
UDPEndpoint(const IOAddress& address, const unsigned short port) :
asio_endpoint_placeholder_(
new udp::endpoint(ip::address::from_string(address.toText()),
port)),
asio_endpoint_(*asio_endpoint_placeholder_)
{}
+
+ /// \brief Constructor from an ASIO UDP endpoint.
+ ///
+ /// This constructor is designed to be an efficient wrapper for the
+ /// corresponding ASIO class, \c udp::endpoint.
+ ///
+ /// \param asio_endpoint The ASIO representation of the UDP endpoint.
UDPEndpoint(const udp::endpoint& asio_endpoint) :
asio_endpoint_placeholder_(NULL), asio_endpoint_(asio_endpoint)
{}
+
+ /// \brief The destructor.
~UDPEndpoint() { delete asio_endpoint_placeholder_; }
+ //@}
+
virtual IOAddress getAddress() const {
return (asio_endpoint_.address());
}
@@ -124,37 +173,74 @@
protocol);
}
+/// \brief The \c TCPSocket class is a concrete derived class of
+/// \c IOSocket that represents a TCP socket.
+///
+/// In the current implementation, an object of this class is always
+/// instantiated within the wrapper routines. Applications are expected to
+/// get access to the object via the abstract base class, \c IOSocket.
+/// This design may be changed when we generalize the wrapper interface.
class TCPSocket : public IOSocket {
private:
TCPSocket(const TCPSocket& source);
TCPSocket& operator=(const TCPSocket& source);
public:
+ /// \brief Constructor from an ASIO TCP socket.
+ ///
+ /// \param socket The ASIO representation of the TCP socket.
TCPSocket(tcp::socket& socket) : socket_(socket) {}
+
virtual int getNative() const { return (socket_.native()); }
virtual int getProtocol() const { return (IPPROTO_TCP); }
private:
tcp::socket& socket_;
};
+/// \brief The \c UDPSocket class is a concrete derived class of
+/// \c IOSocket that represents a UDP socket.
+///
+/// Other notes about \c TCPSocket applies to this class, too.
class UDPSocket : public IOSocket {
private:
UDPSocket(const UDPSocket& source);
UDPSocket& operator=(const UDPSocket& source);
public:
+ /// \brief Constructor from an ASIO UDP socket.
+ ///
+ /// \param socket The ASIO representation of the UDP socket.
UDPSocket(udp::socket& socket) : socket_(socket) {}
+
virtual int getNative() const { return (socket_.native()); }
virtual int getProtocol() const { return (IPPROTO_UDP); }
private:
udp::socket& socket_;
};
+/// \brief The \c DummySocket class is a concrete derived class of
+/// \c IOSocket that is not associated with any real socket.
+///
+/// This main purpose of this class is tests, where it may be desirable to
+/// instantiate an \c IOSocket object without involving system resource
+/// allocation such as real network sockets.
class DummySocket : public IOSocket {
private:
DummySocket(const DummySocket& source);
DummySocket& operator=(const DummySocket& source);
public:
+ /// \brief Constructor from the protocol number.
+ ///
+ /// The protocol must validly identify a standard network protocol.
+ /// For example, to specify TCP \c protocol must be \c IPPROTO_TCP.
+ ///
+ /// \param protocol The network protocol number for the socket.
DummySocket(const int protocol) : protocol_(protocol) {}
+
+ /// \brief A dummy derived method of \c IOSocket::getNative().
+ ///
+ /// This version of method always returns -1 as the object is not
+ /// associated with a real (native) socket.
virtual int getNative() const { return (-1); }
+
virtual int getProtocol() const { return (protocol_); }
private:
const int protocol_;
@@ -197,8 +283,8 @@
void start() {
// Check for queued configuration commands
if (auth_server_ != NULL &&
- auth_server_->configSession()->hasQueuedMsgs()) {
- auth_server_->configSession()->checkCommand();
+ auth_server_->getConfigSession()->hasQueuedMsgs()) {
+ auth_server_->getConfigSession()->checkCommand();
}
async_read(socket_, asio::buffer(data_, TCP_MESSAGE_LENGTHSIZE),
boost::bind(&TCPClient::headerRead, this,
@@ -385,8 +471,8 @@
{
// Check for queued configuration commands
if (auth_server_ != NULL &&
- auth_server_->configSession()->hasQueuedMsgs()) {
- auth_server_->configSession()->checkCommand();
+ auth_server_->getConfigSession()->hasQueuedMsgs()) {
+ auth_server_->getConfigSession()->checkCommand();
}
if (!error && bytes_recvd > 0) {
const UDPEndpoint remote_endpoint(sender_endpoint_);
Modified: branches/trac191-rebased/src/bin/auth/auth_srv.cc
==============================================================================
--- branches/trac191-rebased/src/bin/auth/auth_srv.cc (original)
+++ branches/trac191-rebased/src/bin/auth/auth_srv.cc Fri Oct 15 05:19:19 2010
@@ -29,6 +29,8 @@
#include <dns/messagerenderer.h>
#include <dns/name.h>
#include <dns/question.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <dns/rrset.h>
#include <dns/rrttl.h>
#include <dns/message.h>
@@ -213,7 +215,7 @@
}
ModuleCCSession*
-AuthSrv::configSession() const {
+AuthSrv::getConfigSession() const {
return (impl_->config_session_);
}
Modified: branches/trac191-rebased/src/bin/auth/auth_srv.h
==============================================================================
--- branches/trac191-rebased/src/bin/auth/auth_srv.h (original)
+++ branches/trac191-rebased/src/bin/auth/auth_srv.h Fri Oct 15 05:19:19 2010
@@ -38,8 +38,30 @@
class IOMessage;
}
+/// \brief The implementation class for the \c AuthSrv class using the pimpl
+/// idiom.
class AuthSrvImpl;
+/// \brief The authoritative nameserver class.
+///
+/// \c AuthSrv is a concrete class that implements authoritative DNS server
+/// protocol processing.
+/// An \c AuthSrv object is primarily responsible for handling incoming DNS
+/// requests: It parses the request and dispatches subsequent processing to
+/// the corresponding module (which may be an internal library or a separate
+/// process) depending on the request type. For normal queries, the
+/// \c AuthSrv object searches configured data sources for the answer to the
+/// query, and builds a response containing the answer.
+///
+/// This class uses the "pimpl" idiom, and hides detailed implementation
+/// through the \c impl_ pointer (which points to an instance of the
+/// \c AuthSrvImpl class). An \c AuthSrv object is supposed to exist for quite
+/// a long period, and only a few \c AuthSrv objects will be created (in fact,
+/// in this current implementation there will only be one object), so the
+/// construction overhead of this approach should be acceptable.
+///
+/// The design of this class is still in flux. It's quite likely to change
+/// in future versions.
class AuthSrv {
///
/// \name Constructors, Assignment Operator and Destructor.
@@ -67,10 +89,77 @@
bool processMessage(const asio_link::IOMessage& io_message,
isc::dns::Message& message,
isc::dns::MessageRenderer& response_renderer);
- void setVerbose(bool on);
+
+ /// \brief Enable or disable verbose logging.
+ ///
+ /// This method never throws an exception.
+ ///
+ /// \param on \c true to enable verbose logging; \c false to disable
+ /// verbose logging.
+ void setVerbose(const bool on);
+
+ /// \brief Returns the logging verbosity of the \c AuthSrv object.
+ ///
+ /// This method never throws an exception.
+ ///
+ /// \return \c true if verbose logging is enabled; otherwise \c false.
bool getVerbose() const;
+
+ /// \brief Updates the data source for the \c AuthSrv object.
+ ///
+ /// This method installs or replaces the data source that the \c AuthSrv
+ /// object refers to for query processing.
+ /// Although the method name is generic, the only thing it does is to
+ /// update the data source information.
+ /// If there is a data source installed, it will be replaced with the
+ /// new one.
+ ///
+ /// In the current implementation, the SQLite data source is assumed.
+ /// The \c config parameter will simply be passed to the initialization
+ /// routine of the \c Sqlite3DataSrc class.
+ ///
+ /// On success this method returns a data \c Element (in the form of a
+ /// pointer like object) indicating the successful result,
+ /// i.e., {"result": [0]}.
+ /// Otherwise, it returns a data \c Element explaining the error:
+ /// {"result": [1, <error-description>]}.
+ ///
+ /// This method is mostly exception free (error conditions are represented
+ /// via the return value). But it may still throw a standard exception
+ /// if memory allocation fails inside the method.
+ /// When a standard exception is thrown or an implementation specific
+ /// exception is triggered and caught internally, this function provides
+ /// the strong exception guarantee: Unless everything succeeds, currently
+ /// installed data source (if any) won't be replaced.
+ ///
+ /// \param config An immutable pointer-like object to a data \c Element,
+ /// possibly containing the data source information to be used.
+ /// \return An immutable pointer-like object to a data \c Element
+ /// containing the result of the update operation.
isc::data::ConstElementPtr updateConfig(isc::data::ConstElementPtr config);
- isc::config::ModuleCCSession* configSession() const;
+
+ /// \param Returns the command and configuration session for the
+ /// \c AuthSrv.
+ ///
+ /// This method never throws an exception.
+ ///
+ /// \return A pointer to \c ModuleCCSession object stored in the
+ /// \c AuthSrv object. In this implementation it could be NULL.
+ isc::config::ModuleCCSession* getConfigSession() const;
+
+ /// \brief Set the command and configuration session for the \c AuthSrv.
+ ///
+ /// Note: this interface is tentative. We'll revisit the ASIO and session
+ /// frameworks, at which point the session will probably be passed on
+ /// construction of the server.
+ /// In the current implementation, this method is expected to be called
+ /// exactly once as part of initialization. If this method is called
+ /// multiple times, previously specified session is silently overridden.
+ ///
+ /// This method never throws an exception.
+ ///
+ /// \param config_session A pointer to \c ModuleCCSession object to receive
+ /// control commands and configuration updates.
void setConfigSession(isc::config::ModuleCCSession* config_session);
/// \brief Set or update the size (number of slots) of hot spot cache.
@@ -93,6 +182,8 @@
/// \return The current number of cache slots.
size_t getCacheSlots() const;
+ /// \brief Set the communication session with a separate process for
+ /// outgoing zone transfers.
///
/// Note: this interface is tentative. We'll revisit the ASIO and session
/// frameworks, at which point the session will probably be passed on
@@ -105,6 +196,7 @@
/// Ownership isn't transferred: the caller is responsible for keeping
/// this object to be valid while the server object is working and for
/// disconnecting the session and destroying the object when the server
+ /// is shutdown.
///
void setXfrinSession(isc::cc::AbstractSession* xfrin_session);
private:
Modified: branches/trac191-rebased/src/bin/auth/tests/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/bin/auth/tests/Makefile.am (original)
+++ branches/trac191-rebased/src/bin/auth/tests/Makefile.am Fri Oct 15 05:19:19 2010
@@ -1,7 +1,10 @@
+SUBDIRS = testdata .
+
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_builddir)/src/lib/dns -I$(top_srcdir)/src/bin
AM_CPPFLAGS += -I$(top_builddir)/src/lib/cc
AM_CPPFLAGS += -DTEST_DATA_DIR=\"$(srcdir)/testdata\"
+AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/bin/auth/tests/testdata\"
AM_CXXFLAGS = $(B10_CXXFLAGS)
@@ -36,25 +39,3 @@
endif
noinst_PROGRAMS = $(TESTS)
-
-EXTRA_DIST = testdata/badExampleQuery_fromWire
-EXTRA_DIST += testdata/badExampleQuery_fromWire.spec
-EXTRA_DIST += testdata/example.com
-EXTRA_DIST += testdata/examplequery_fromWire
-EXTRA_DIST += testdata/examplequery_fromWire.spec
-EXTRA_DIST += testdata/example.sqlite3
-EXTRA_DIST += testdata/iqueryresponse_fromWire
-EXTRA_DIST += testdata/iqueryresponse_fromWire.spec
-EXTRA_DIST += testdata/multiquestion_fromWire
-EXTRA_DIST += testdata/multiquestion_fromWire.spec
-EXTRA_DIST += testdata/queryBadEDNS_fromWire
-EXTRA_DIST += testdata/queryBadEDNS_fromWire.spec
-EXTRA_DIST += testdata/shortanswer_fromWire
-EXTRA_DIST += testdata/shortanswer_fromWire.spec
-EXTRA_DIST += testdata/shortmessage_fromWire
-EXTRA_DIST += testdata/shortquestion_fromWire
-EXTRA_DIST += testdata/shortresponse_fromWire
-EXTRA_DIST += testdata/simplequery_fromWire
-EXTRA_DIST += testdata/simplequery_fromWire.spec
-EXTRA_DIST += testdata/simpleresponse_fromWire
-EXTRA_DIST += testdata/simpleresponse_fromWire.spec
Modified: branches/trac191-rebased/src/bin/auth/tests/auth_srv_unittest.cc
==============================================================================
--- branches/trac191-rebased/src/bin/auth/tests/auth_srv_unittest.cc (original)
+++ branches/trac191-rebased/src/bin/auth/tests/auth_srv_unittest.cc Fri Oct 15 05:19:19 2010
@@ -22,6 +22,8 @@
#include <dns/name.h>
#include <dns/message.h>
#include <dns/messagerenderer.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <dns/rrclass.h>
#include <dns/rrtype.h>
@@ -114,7 +116,7 @@
AuthSrvTest() : server(true, xfrout),
request_message(Message::RENDER),
parse_message(Message::PARSE), default_qid(0x1035),
- opcode(Opcode(Opcode::QUERY())), qname("www.example.com"),
+ opcode(Opcode::QUERY()), qname("www.example.com"),
qclass(RRClass::IN()), qtype(RRType::A()),
io_message(NULL), endpoint(NULL), request_obuffer(0),
request_renderer(request_obuffer),
@@ -280,6 +282,7 @@
{
request_message.clear(Message::RENDER);
request_message.setOpcode(opcode);
+ request_message.setRcode(Rcode::NOERROR());
request_message.setQid(default_qid);
request_message.addQuestion(Question(request_name, rrclass, rrtype));
}
@@ -341,7 +344,7 @@
i == Opcode::NOTIFY().getCode()) {
continue;
}
- createDataFromFile("simplequery_fromWire");
+ createDataFromFile("simplequery_fromWire.wire");
data[2] = ((i << 3) & 0xff);
parse_message.clear(Message::PARSE);
@@ -363,7 +366,7 @@
// Multiple questions. Should result in FORMERR.
TEST_F(AuthSrvTest, multiQuestion) {
- createDataFromFile("multiquestion_fromWire");
+ createDataFromFile("multiquestion_fromWire.wire");
EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
response_renderer));
headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
@@ -393,7 +396,7 @@
// or malformed or could otherwise cause a protocol error.
TEST_F(AuthSrvTest, response) {
// A valid (although unusual) response
- createDataFromFile("simpleresponse_fromWire");
+ createDataFromFile("simpleresponse_fromWire.wire");
EXPECT_EQ(false, server.processMessage(*io_message, parse_message,
response_renderer));
@@ -404,7 +407,7 @@
response_renderer));
// A response to iquery. must be dropped rather than returning NOTIMP.
- createDataFromFile("iqueryresponse_fromWire");
+ createDataFromFile("iqueryresponse_fromWire.wire");
EXPECT_EQ(false, server.processMessage(*io_message, parse_message,
response_renderer));
}
@@ -422,7 +425,7 @@
// Query with a broken answer section
TEST_F(AuthSrvTest, shortAnswer) {
- createDataFromFile("shortanswer_fromWire");
+ createDataFromFile("shortanswer_fromWire.wire");
EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
response_renderer));
@@ -441,7 +444,7 @@
// Query with unsupported version of EDNS.
TEST_F(AuthSrvTest, ednsBadVers) {
- createDataFromFile("queryBadEDNS_fromWire");
+ createDataFromFile("queryBadEDNS_fromWire.wire");
EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
response_renderer));
@@ -584,6 +587,7 @@
TEST_F(AuthSrvTest, notifyEmptyQuestion) {
request_message.clear(Message::RENDER);
request_message.setOpcode(Opcode::NOTIFY());
+ request_message.setRcode(Rcode::NOERROR());
request_message.setHeaderFlag(MessageFlag::AA());
request_message.setQid(default_qid);
request_message.toWire(request_renderer);
@@ -722,7 +726,7 @@
// query for existent data in the installed data source. The resulting
// response should have the AA flag on, and have an RR in each answer
// and authority section.
- createDataFromFile("examplequery_fromWire");
+ createDataFromFile("examplequery_fromWire.wire");
EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
response_renderer));
headerCheck(parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
@@ -736,7 +740,7 @@
// tool and the data source itself naively accept it). This will result
// in a SERVFAIL response, and the answer and authority sections should
// be empty.
- createDataFromFile("badExampleQuery_fromWire");
+ createDataFromFile("badExampleQuery_fromWire.wire");
EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
response_renderer));
headerCheck(parse_message, default_qid, Rcode::SERVFAIL(),
@@ -751,7 +755,7 @@
updateConfig(&server, BADCONFIG_TESTDB, false);
// The original data source should still exist.
- createDataFromFile("examplequery_fromWire");
+ createDataFromFile("examplequery_fromWire.wire");
EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
response_renderer));
headerCheck(parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
Modified: branches/trac191-rebased/src/bin/auth/tests/run_unittests.cc
==============================================================================
--- branches/trac191-rebased/src/bin/auth/tests/run_unittests.cc (original)
+++ branches/trac191-rebased/src/bin/auth/tests/run_unittests.cc Fri Oct 15 05:19:19 2010
@@ -23,6 +23,7 @@
{
::testing::InitGoogleTest(&argc, argv);
isc::UnitTestUtil::addDataPath(TEST_DATA_DIR);
+ isc::UnitTestUtil::addDataPath(TEST_DATA_BUILDDIR);
return (RUN_ALL_TESTS());
}
Modified: branches/trac191-rebased/src/bin/bind10/bind10.8
==============================================================================
--- branches/trac191-rebased/src/bin/bind10/bind10.8 (original)
+++ branches/trac191-rebased/src/bin/bind10/bind10.8 Fri Oct 15 05:19:19 2010
@@ -1,13 +1,22 @@
'\" t
.\" Title: bind10
.\" Author: [see the "AUTHORS" section]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\" Generator: DocBook XSL Stylesheets v1.76.0 <http://docbook.sf.net/>
.\" Date: July 29, 2010
.\" Manual: BIND10
.\" Source: BIND10
.\" Language: English
.\"
.TH "BIND10" "8" "July 29, 2010" "BIND10" "BIND10"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -22,7 +31,7 @@
bind10 \- BIND 10 boss process
.SH "SYNOPSIS"
.HP \w'\fBbind10\fR\ 'u
-\fBbind10\fR [\fB\-a\ \fR\fB\fIaddress\fR\fR] [\fB\-m\ \fR\fB\fIfile\fR\fR] [\fB\-n\fR] [\fB\-p\ \fR\fB\fInumber\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-\-address\ \fR\fB\fIaddress\fR\fR] [\fB\-\-msgq\-socket\-file\ \fR\fB\fIfile\fR\fR] [\fB\-\-no\-cache\fR] [\fB\-\-port\ \fR\fB\fInumber\fR\fR] [\fB\-\-user\ \fR\fB\fIuser\fR\fR] [\fB\-\-verbose\fR]
+\fBbind10\fR [\fB\-a\ \fR\fB\fIaddress\fR\fR] [\fB\-m\ \fR\fB\fIfile\fR\fR] [\fB\-n\fR] [\fB\-p\ \fR\fB\fInumber\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-\-address\ \fR\fB\fIaddress\fR\fR] [\fB\-\-msgq\-socket\-file\ \fR\fB\fIfile\fR\fR] [\fB\-\-no\-cache\fR] [\fB\-\-port\ \fR\fB\fInumber\fR\fR] [\fB\-\-user\ \fR\fB\fIuser\fR\fR] [\fB\-\-pretty\-name\ \fR\fB\fIname\fR\fR] [\fB\-\-verbose\fR]
.SH "DESCRIPTION"
.PP
The
@@ -86,6 +95,15 @@
must be initially ran as the root user to use this option\&. The default is to run as the current user\&.
.RE
.PP
+\fB\-\-pretty\-name \fR\fB\fIname\fR\fR
+.RS 4
+The name this process should have in tools like
+\fBps\fR
+or
+\fBtop\fR\&. This is handy if you have multiple versions/installations of
+\fBbind10\fR\&.
+.RE
+.PP
\fB\-v\fR, \fB\-\-verbose\fR
.RS 4
Display more about what is going on for
Modified: branches/trac191-rebased/src/bin/bind10/bind10.py.in
==============================================================================
--- branches/trac191-rebased/src/bin/bind10/bind10.py.in (original)
+++ branches/trac191-rebased/src/bin/bind10/bind10.py.in Fri Oct 15 05:19:19 2010
@@ -63,6 +63,10 @@
import posix
import isc.cc
+import isc.utils.process
+
+# Assign this process some longer name
+isc.utils.process.rename(sys.argv[0])
# This is the version that gets displayed to the user.
# The VERSION string consists of the module name, the module version
@@ -646,7 +650,11 @@
parser.values.address = value
else:
raise OptionValueError("Unknown option " + opt_str)
-
+
+def process_rename(option, opt_str, value, parser):
+ """Function that renames the process if it is requested by a option."""
+ isc.utils.process.rename(value)
+
def main():
global options
global boss_of_bind
@@ -672,6 +680,9 @@
help="Change user after startup (must run as root)")
parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
help="display more about what is going on")
+ parser.add_option("--pretty-name", type="string", action="callback",
+ callback=process_rename,
+ help="Set the process name (displayed in ps, top, ...)")
(options, args) = parser.parse_args()
if args:
parser.print_help()
@@ -724,6 +735,9 @@
signal.siginterrupt(signal.SIGCHLD, False)
signal.signal(signal.SIGINT, fatal_signal)
signal.signal(signal.SIGTERM, fatal_signal)
+
+ # Block SIGPIPE, as we don't want it to end this process
+ signal.signal(signal.SIGPIPE, signal.SIG_IGN)
# Go bob!
boss_of_bind = BoB(options.msgq_socket_file, int(options.auth_port),
Modified: branches/trac191-rebased/src/bin/bind10/bind10.xml
==============================================================================
--- branches/trac191-rebased/src/bin/bind10/bind10.xml (original)
+++ branches/trac191-rebased/src/bin/bind10/bind10.xml Fri Oct 15 05:19:19 2010
@@ -56,6 +56,7 @@
<arg><option>--no-cache</option></arg>
<arg><option>--port <replaceable>number</replaceable></option></arg>
<arg><option>--user <replaceable>user</replaceable></option></arg>
+ <arg><option>--pretty-name <replaceable>name</replaceable></option></arg>
<arg><option>--verbose</option></arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -149,6 +150,17 @@
</varlistentry>
<varlistentry>
+ <term><option>--pretty-name <replaceable>name</replaceable></option></term>
+
+ <listitem>
+ <para>The name this process should have in tools like
+ <command>ps</command> or <command>top</command>. This
+ is handy if you have multiple versions/installations
+ of <command>bind10</command>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>-v</option>, <option>--verbose</option></term>
<listitem>
<para>Display more about what is going on for
Modified: branches/trac191-rebased/src/bin/bind10/tests/args_test.py
==============================================================================
--- branches/trac191-rebased/src/bin/bind10/tests/args_test.py (original)
+++ branches/trac191-rebased/src/bin/bind10/tests/args_test.py Fri Oct 15 05:19:19 2010
@@ -130,5 +130,28 @@
x = bob.wait()
self.assertTrue(bob.wait() == 0)
+ def testPrettyName(self):
+ """Try the --pretty-name option."""
+ CMD_PRETTY_NAME = b'bob-name-test'
+ bob = subprocess.Popen(args=(BIND10_EXE, '--pretty-name',
+ CMD_PRETTY_NAME), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ started_ok = self._waitForString(bob, '[bind10] BIND 10 started')
+ self.assertTrue(started_ok)
+ ps = subprocess.Popen(args=("ps", "axo", "pid,comm"),
+ stdout=subprocess.PIPE)
+ s = ps.stdout.readline()
+ command = None
+ while True:
+ s = ps.stdout.readline()
+ if s == '': break
+ (pid,comm) = s.split(None, 1)
+ if int(pid) == bob.pid:
+ command = comm
+ break
+ self.assertEqual(command, CMD_PRETTY_NAME + b'\n')
+ time.sleep(0.1)
+ bob.terminate()
+ bob.wait()
+
if __name__ == '__main__':
unittest.main()
Modified: branches/trac191-rebased/src/bin/bindctl/bindctl-source.py.in
==============================================================================
--- branches/trac191-rebased/src/bin/bindctl/bindctl-source.py.in (original)
+++ branches/trac191-rebased/src/bin/bindctl/bindctl-source.py.in Fri Oct 15 05:19:19 2010
@@ -24,6 +24,9 @@
from bindctl.bindcmd import *
import pprint
from optparse import OptionParser, OptionValueError
+import isc.utils.process
+
+isc.utils.process.rename()
__version__ = 'Bindctl'
Modified: branches/trac191-rebased/src/bin/cfgmgr/b10-cfgmgr.py.in
==============================================================================
--- branches/trac191-rebased/src/bin/cfgmgr/b10-cfgmgr.py.in (original)
+++ branches/trac191-rebased/src/bin/cfgmgr/b10-cfgmgr.py.in Fri Oct 15 05:19:19 2010
@@ -21,8 +21,11 @@
from isc.config.cfgmgr import ConfigManager, ConfigManagerDataReadError
from isc.cc import SessionError
+import isc.utils.process
import signal
import os
+
+isc.utils.process.rename()
# If B10_FROM_SOURCE is set in the environment, we use data files
# from a directory relative to that, otherwise we use the ones
Modified: branches/trac191-rebased/src/bin/cmdctl/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/bin/cmdctl/Makefile.am (original)
+++ branches/trac191-rebased/src/bin/cmdctl/Makefile.am Fri Oct 15 05:19:19 2010
@@ -15,7 +15,7 @@
b10_cmdctl_DATA = $(CMDCTL_CONFIGURATIONS)
b10_cmdctl_DATA += cmdctl.spec
-
+
EXTRA_DIST = $(CMDCTL_CONFIGURATIONS)
CLEANFILES= b10-cmdctl cmdctl.pyc cmdctl.spec
Modified: branches/trac191-rebased/src/bin/cmdctl/cmdctl.py.in
==============================================================================
--- branches/trac191-rebased/src/bin/cmdctl/cmdctl.py.in (original)
+++ branches/trac191-rebased/src/bin/cmdctl/cmdctl.py.in Fri Oct 15 05:19:19 2010
@@ -1,6 +1,7 @@
#!@PYTHON@
# Copyright (C) 2010 Internet Systems Consortium.
+# Copyright (C) 2010 CZ NIC
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -42,12 +43,15 @@
import time
import signal
from isc.config import ccsession
+import isc.utils.process
from optparse import OptionParser, OptionValueError
from hashlib import sha1
try:
import threading
except ImportError:
import dummy_threading as threading
+
+isc.utils.process.rename()
__version__ = 'BIND10'
URL_PATTERN = re.compile('/([\w]+)(?:/([\w]+))?/?')
@@ -320,8 +324,8 @@
def _handle_msg_from_msgq(self):
'''Process all the received commands with module session. '''
while self._serving:
- self._module_cc.check_command()
-
+ self._module_cc.check_command(False)
+
def _parse_command_result(self, rcode, reply):
'''Ignore the error reason when command rcode isn't 0, '''
if rcode != 0:
Modified: branches/trac191-rebased/src/bin/host/host.cc
==============================================================================
--- branches/trac191-rebased/src/bin/host/host.cc (original)
+++ branches/trac191-rebased/src/bin/host/host.cc Fri Oct 15 05:19:19 2010
@@ -28,6 +28,8 @@
#include <dns/name.h>
#include <dns/message.h>
#include <dns/messagerenderer.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <dns/rrclass.h>
#include <dns/rrtype.h>
#include <dns/rrset.h>
Modified: branches/trac191-rebased/src/bin/loadzone/b10-loadzone.py.in
==============================================================================
--- branches/trac191-rebased/src/bin/loadzone/b10-loadzone.py.in (original)
+++ branches/trac191-rebased/src/bin/loadzone/b10-loadzone.py.in Fri Oct 15 05:19:19 2010
@@ -18,9 +18,13 @@
import sys; sys.path.append ('@@PYTHONPATH@@')
import re, getopt
import isc.datasrc
+import isc.utils.process
from isc.datasrc.master import MasterFile
import time
import os
+
+isc.utils.process.rename()
+
#########################################################################
# usage: print usage note and exit
#########################################################################
Modified: branches/trac191-rebased/src/bin/msgq/msgq.py.in
==============================================================================
--- branches/trac191-rebased/src/bin/msgq/msgq.py.in (original)
+++ branches/trac191-rebased/src/bin/msgq/msgq.py.in Fri Oct 15 05:19:19 2010
@@ -31,8 +31,11 @@
import pprint
import random
from optparse import OptionParser, OptionValueError
+import isc.utils.process
import isc.cc
+
+isc.utils.process.rename()
# This is the version that gets displayed to the user.
__version__ = "v20091030 (Paving the DNS Parking Lot)"
@@ -139,6 +142,10 @@
def setup_listener(self):
"""Set up the listener socket. Internal function."""
+ if self.verbose:
+ sys.stdout.write("[b10-msgq] Setting up socket at %s\n" %
+ self.socket_file)
+
self.listen_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
if os.path.exists(self.socket_file):
Modified: branches/trac191-rebased/src/bin/usermgr/b10-cmdctl-usermgr.py.in
==============================================================================
--- branches/trac191-rebased/src/bin/usermgr/b10-cmdctl-usermgr.py.in (original)
+++ branches/trac191-rebased/src/bin/usermgr/b10-cmdctl-usermgr.py.in Fri Oct 15 05:19:19 2010
@@ -25,6 +25,9 @@
import getpass
import getopt
import sys
+import isc.utils.process
+
+isc.utils.process.rename()
VERSION_NUMBER = 'bind10'
DEFAULT_FILE = 'cmdctl-accounts.csv'
Modified: branches/trac191-rebased/src/bin/xfrin/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/bin/xfrin/Makefile.am (original)
+++ branches/trac191-rebased/src/bin/xfrin/Makefile.am Fri Oct 15 05:19:19 2010
@@ -7,10 +7,11 @@
b10_xfrindir = $(DESTDIR)$(pkgdatadir)
b10_xfrin_DATA = xfrin.spec
-CLEANFILES = b10-xfrin xfrin.pyc xfrin.spec
+CLEANFILES = b10-xfrin xfrin.pyc
man_MANS = b10-xfrin.8
EXTRA_DIST = $(man_MANS) b10-xfrin.xml
+EXTRA_DIST += xfrin.spec
if ENABLE_MAN
@@ -19,9 +20,6 @@
endif
-xfrin.spec: xfrin.spec.pre
- $(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" xfrin.spec.pre >$@
-
# TODO: does this need $$(DESTDIR) also?
# this is done here since configure.ac AC_OUTPUT doesn't expand exec_prefix
b10-xfrin: xfrin.py
Modified: branches/trac191-rebased/src/bin/xfrin/xfrin.py.in
==============================================================================
--- branches/trac191-rebased/src/bin/xfrin/xfrin.py.in (original)
+++ branches/trac191-rebased/src/bin/xfrin/xfrin.py.in Fri Oct 15 05:19:19 2010
@@ -1,6 +1,7 @@
#!@PYTHON@
# Copyright (C) 2010 Internet Systems Consortium.
+# Copyright (C) 2010 CZ NIC
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -29,12 +30,15 @@
from optparse import OptionParser, OptionValueError
from isc.config.ccsession import *
from isc.notify import notify_out
+import isc.utils.process
try:
from pydnspp import *
except ImportError as e:
# C++ loadable module may not be installed; even so the xfrin process
# must keep running, so we warn about it and move forward.
sys.stderr.write('[b10-xfrin] failed to import DNS module: %s\n' % str(e))
+
+isc.utils.process.rename()
# If B10_FROM_BUILD is set in the environment, we use data files
# from a directory relative to that, otherwise we use the ones
@@ -326,10 +330,14 @@
sock_map = {}
conn = XfrinConnection(sock_map, zone_name, rrclass, db_file,
shutdown_event, master_addrinfo, verbose)
+ ret = XFRIN_FAIL
if conn.connect_to_master():
ret = conn.do_xfrin(check_soa)
- server.publish_xfrin_news(zone_name, rrclass, ret)
-
+
+ # Publish the zone transfer result news, so zonemgr can reset the
+ # zone timer, and xfrout can notify the zone's slaves if the result
+ # is success.
+ server.publish_xfrin_news(zone_name, rrclass, ret)
xfrin_recorder.decrement(zone_name)
@@ -393,7 +401,7 @@
'''This is a straightforward wrapper for cc.check_command,
but provided as a separate method for the convenience
of unit tests.'''
- self._module_cc.check_command()
+ self._module_cc.check_command(False)
def config_handler(self, new_config):
self._max_transfers_in = new_config.get("transfers_in") or self._max_transfers_in
Modified: branches/trac191-rebased/src/bin/xfrout/xfrout.py.in
==============================================================================
--- branches/trac191-rebased/src/bin/xfrout/xfrout.py.in (original)
+++ branches/trac191-rebased/src/bin/xfrout/xfrout.py.in Fri Oct 15 05:19:19 2010
@@ -1,6 +1,7 @@
#!@PYTHON@
# Copyright (C) 2010 Internet Systems Consortium.
+# Copyright (C) 2010 CZ NIC
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -29,6 +30,7 @@
from isc.log.log import *
from isc.cc import SessionError, SessionTimeout
from isc.notify import notify_out
+import isc.utils.process
import socket
import select
import errno
@@ -40,6 +42,8 @@
# C++ loadable module may not be installed; even so the xfrout process
# must keep running, so we warn about it and move forward.
sys.stderr.write('[b10-xfrout] failed to import DNS or XFR module: %s\n' % str(e))
+
+isc.utils.process.rename()
if "B10_FROM_BUILD" in os.environ:
SPECFILE_PATH = os.environ["B10_FROM_BUILD"] + "/src/bin/xfrout"
@@ -491,7 +495,7 @@
def run(self):
'''Get and process all commands sent from cfgmgr or other modules. '''
while not self._shutdown_event.is_set():
- self._cc.check_command()
+ self._cc.check_command(False)
xfrout_server = None
Modified: branches/trac191-rebased/src/bin/zonemgr/tests/zonemgr_test.py
==============================================================================
--- branches/trac191-rebased/src/bin/zonemgr/tests/zonemgr_test.py (original)
+++ branches/trac191-rebased/src/bin/zonemgr/tests/zonemgr_test.py Fri Oct 15 05:19:19 2010
@@ -27,6 +27,11 @@
ZONE_NAME_CLASS1_CH = ("sd.cn.", "CH")
ZONE_NAME_CLASS2_IN = ("tw.cn", "IN")
+MAX_TRANSFER_TIMEOUT = 14400
+LOWERBOUND_REFRESH = 10
+LOWERBOUND_RETRY = 5
+JITTER_SCOPE = 0.10
+
class ZonemgrTestException(Exception):
pass
@@ -42,15 +47,20 @@
def __init__(self):
self._cc = MySession()
self._db_file = "initdb.file"
+ current_time = time.time()
+ self._max_transfer_timeout = MAX_TRANSFER_TIMEOUT
+ self._lowerbound_refresh = LOWERBOUND_REFRESH
+ self._lowerbound_retry = LOWERBOUND_RETRY
+ self._jitter_scope = JITTER_SCOPE
self._zonemgr_refresh_info = {
('sd.cn.', 'IN'): {
- 'last_refresh_time': 1280474398.822142,
- 'next_refresh_time': 1280481598.822153,
+ 'last_refresh_time': current_time,
+ 'next_refresh_time': current_time + 6500,
'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600',
'zone_state': 0},
('tw.cn', 'CH'): {
- 'last_refresh_time': 1280474399.116421,
- 'next_refresh_time': 1280481599.116433,
+ 'last_refresh_time': current_time,
+ 'next_refresh_time': current_time + 6900,
'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073112 7200 3600 2419200 21600',
'zone_state': 0}
}
@@ -311,6 +321,11 @@
self.assertTrue((time1 + 3 * 3600 / 4) <= next_refresh_time)
self.assertTrue(next_refresh_time <= time2 + 3600)
self.assertEqual(ZONE_OK, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"])
+
+ self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["last_refresh_time"] = time1 - 2419200
+ self.zone_refresh.zone_refresh_fail(ZONE_NAME_CLASS1_IN)
+ self.assertEqual(ZONE_EXPIRED, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"])
+
self.assertRaises(ZonemgrException, self.zone_refresh.zone_refresh_fail, ("org.cn.", "CH"))
self.assertRaises(ZonemgrException, self.zone_refresh.zone_refresh_fail, ZONE_NAME_CLASS3_IN)
@@ -332,17 +347,6 @@
zone_need_refresh = self.zone_refresh._find_need_do_refresh_zone()
self.assertEqual(ZONE_NAME_CLASS1_IN, zone_need_refresh)
- self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["last_refresh_time"] = time1 - 2419200
- self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"] = ZONE_EXPIRED
- zone_need_refresh = self.zone_refresh._find_need_do_refresh_zone()
- self.assertEqual(None, zone_need_refresh)
-
- self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"] = ZONE_REFRESHING
- self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["notify_master"] = "192.168.0.1"
- zone_need_refresh = self.zone_refresh._find_need_do_refresh_zone()
- self.assertEqual(ZONE_NAME_CLASS1_IN, zone_need_refresh)
- self.assertEqual(ZONE_EXPIRED, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"])
-
self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS2_CH]["refresh_timeout"] = time1
zone_need_refresh = self.zone_refresh._find_need_do_refresh_zone()
self.assertEqual(ZONE_NAME_CLASS2_CH, zone_need_refresh)
@@ -402,6 +406,19 @@
self.assertTrue("refresh_timeout" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
self.assertTrue(zone_state == ZONE_REFRESHING)
+ def test_update_config_data(self):
+ config_data = {
+ "lowerbound_refresh" : 60,
+ "lowerbound_retry" : 30,
+ "max_transfer_timeout" : 19800,
+ "jitter_scope" : 0.25
+ }
+ self.zone_refresh.update_config_data(config_data)
+ self.assertEqual(60, self.zone_refresh._lowerbound_refresh)
+ self.assertEqual(30, self.zone_refresh._lowerbound_retry)
+ self.assertEqual(19800, self.zone_refresh._max_transfer_timeout)
+ self.assertEqual(0.25, self.zone_refresh._jitter_scope)
+
def tearDown(self):
sys.stdout = self.stdout_backup
@@ -422,10 +439,16 @@
def __init__(self):
self._db_file = "initdb.file"
+ self._zone_refresh = None
self._shutdown_event = threading.Event()
self._cc = MySession()
self._module_cc = MyCCSession()
- self._config_data = {"zone_name" : "org.cn", "zone_class" : "CH", "master" : "127.0.0.1"}
+ self._config_data = {
+ "lowerbound_refresh" : 10,
+ "lowerbound_retry" : 5,
+ "max_transfer_timeout" : 14400,
+ "jitter_scope" : 0.1
+ }
def _start_zone_refresh_timer(self):
pass
@@ -436,12 +459,21 @@
self.zonemgr = MyZonemgr()
def test_config_handler(self):
- config_data1 = {"zone_name" : "sd.cn.", "zone_class" : "CH", "master" : "192.168.1.1"}
+ config_data1 = {
+ "lowerbound_refresh" : 60,
+ "lowerbound_retry" : 30,
+ "max_transfer_timeout" : 14400,
+ "jitter_scope" : 0.1
+ }
self.zonemgr.config_handler(config_data1)
self.assertEqual(config_data1, self.zonemgr._config_data)
config_data2 = {"zone_name" : "sd.cn.", "port" : "53", "master" : "192.168.1.1"}
self.zonemgr.config_handler(config_data2)
self.assertEqual(config_data1, self.zonemgr._config_data)
+ # jitter should not be bigger than half of the original value
+ config_data3 = {"jitter_scope" : 0.7}
+ self.zonemgr.config_handler(config_data3)
+ self.assertEqual(0.5, self.zonemgr._config_data.get("jitter_scope"))
def test_get_db_file(self):
self.assertEqual("initdb.file", self.zonemgr.get_db_file())
Modified: branches/trac191-rebased/src/bin/zonemgr/zonemgr.py.in
==============================================================================
--- branches/trac191-rebased/src/bin/zonemgr/zonemgr.py.in (original)
+++ branches/trac191-rebased/src/bin/zonemgr/zonemgr.py.in Fri Oct 15 05:19:19 2010
@@ -1,6 +1,7 @@
#!@PYTHON@
# Copyright (C) 2010 Internet Systems Consortium.
+# Copyright (C) 2010 CZ NIC
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -36,6 +37,9 @@
from isc.datasrc import sqlite3_ds
from optparse import OptionParser, OptionValueError
from isc.config.ccsession import *
+import isc.utils.process
+
+isc.utils.process.rename()
# If B10_FROM_BUILD is set in the environment, we use data files
# from a directory relative to that, otherwise we use the ones
@@ -69,13 +73,6 @@
ZONE_REFRESHING = 1
ZONE_EXPIRED = 2
-# smallest refresh timeout
-LOWERBOUND_REFRESH = 10
-# smallest retry timeout
-LOWERBOUND_RETRY = 5
-# max zone transfer timeout
-MAX_TRANSFER_TIMEOUT = 14400
-
# offsets of fields in the SOA RDATA
REFRESH_OFFSET = 3
RETRY_OFFSET = 4
@@ -97,10 +94,11 @@
do zone refresh.
"""
- def __init__(self, cc, db_file, slave_socket):
+ def __init__(self, cc, db_file, slave_socket, config_data):
self._cc = cc
self._socket = slave_socket
self._db_file = db_file
+ self.update_config_data(config_data)
self._zonemgr_refresh_info = {}
self._build_zonemgr_refresh_info()
@@ -118,25 +116,26 @@
return time.time()
def _set_zone_timer(self, zone_name_class, max, jitter):
- """Set zone next refresh time."""
+ """Set zone next refresh time.
+ jitter should not be bigger than half the original value."""
self._set_zone_next_refresh_time(zone_name_class, self._get_current_time() + \
self._random_jitter(max, jitter))
def _set_zone_refresh_timer(self, zone_name_class):
"""Set zone next refresh time after zone refresh success.
- now + refresh*3/4 <= next_refresh_time <= now + refresh
+ now + refresh - jitter <= next_refresh_time <= now + refresh
"""
zone_refresh_time = float(self._get_zone_soa_rdata(zone_name_class).split(" ")[REFRESH_OFFSET])
- zone_refresh_time = max(LOWERBOUND_REFRESH, zone_refresh_time)
- self._set_zone_timer(zone_name_class, zone_refresh_time, (1 * zone_refresh_time) / 4)
+ zone_refresh_time = max(self._lowerbound_refresh, zone_refresh_time)
+ self._set_zone_timer(zone_name_class, zone_refresh_time, self._jitter_scope * zone_refresh_time)
def _set_zone_retry_timer(self, zone_name_class):
"""Set zone next refresh time after zone refresh fail.
- now + retry*3/4 <= next_refresh_time <= now + retry
+ now + retry - jitter <= next_refresh_time <= now + retry
"""
zone_retry_time = float(self._get_zone_soa_rdata(zone_name_class).split(" ")[RETRY_OFFSET])
- zone_retry_time = max(LOWERBOUND_RETRY, zone_retry_time)
- self._set_zone_timer(zone_name_class, zone_retry_time, (1 * zone_retry_time) / 4)
+ zone_retry_time = max(self._lowerbound_retry, zone_retry_time)
+ self._set_zone_timer(zone_name_class, zone_retry_time, self._jitter_scope * zone_retry_time)
def _set_zone_notify_timer(self, zone_name_class):
"""Set zone next refresh time after receiving notify
@@ -167,7 +166,11 @@
raise ZonemgrException("[b10-zonemgr] Zone (%s, %s) doesn't "
"belong to zonemgr" % zone_name_class)
return
- self._set_zone_state(zone_name_class, ZONE_OK)
+ # Is zone expired?
+ if (self._zone_is_expired(zone_name_class)):
+ self._set_zone_state(zone_name_class, ZONE_EXPIRED)
+ else:
+ self._set_zone_state(zone_name_class, ZONE_OK)
self._set_zone_retry_timer(zone_name_class)
def zone_handle_notify(self, zone_name_class, master):
@@ -269,25 +272,14 @@
"""
zone_need_refresh = None
for zone_name_class in self._zonemgr_refresh_info.keys():
- # Does the zone expired?
- if (ZONE_EXPIRED != self._get_zone_state(zone_name_class) and
- self._zone_is_expired(zone_name_class)):
- log_msg("Zone (%s, %s) is expired." % zone_name_class)
- self._set_zone_state(zone_name_class, ZONE_EXPIRED)
-
zone_state = self._get_zone_state(zone_name_class)
- # If zone is expired and doesn't receive notify, skip the zone
- if (ZONE_EXPIRED == zone_state and
- (not self._get_zone_notifier_master(zone_name_class))):
- continue
-
# If hasn't received refresh response but are within refresh timeout, skip the zone
if (ZONE_REFRESHING == zone_state and
(self._get_zone_refresh_timeout(zone_name_class) > self._get_current_time())):
continue
# Get the zone with minimum next_refresh_time
- if ((None == zone_need_refresh) or
+ if ((zone_need_refresh is None) or
(self._get_zone_next_refresh_time(zone_name_class) <
self._get_zone_next_refresh_time(zone_need_refresh))):
zone_need_refresh = zone_name_class
@@ -303,7 +295,7 @@
"""Do zone refresh."""
log_msg("Do refresh for zone (%s, %s)." % zone_name_class)
self._set_zone_state(zone_name_class, ZONE_REFRESHING)
- self._set_zone_refresh_timeout(zone_name_class, self._get_current_time() + MAX_TRANSFER_TIMEOUT)
+ self._set_zone_refresh_timeout(zone_name_class, self._get_current_time() + self._max_transfer_timeout)
notify_master = self._get_zone_notifier_master(zone_name_class)
# If the zone has notify master, send notify command to xfrin module
if notify_master:
@@ -332,13 +324,13 @@
while True:
# Zonemgr has no zone.
if self._zone_mgr_is_empty():
- time.sleep(LOWERBOUND_RETRY) # A better time?
+ time.sleep(self._lowerbound_retry) # A better time?
continue
zone_need_refresh = self._find_need_do_refresh_zone()
- # If don't get zone with minimum next refresh time, set timer timeout = LOWERBOUND_REFRESH
+ # If don't get zone with minimum next refresh time, set timer timeout = lowerbound_retry
if not zone_need_refresh:
- timeout = LOWERBOUND_RETRY
+ timeout = self._lowerbound_retry
else:
timeout = self._get_zone_next_refresh_time(zone_need_refresh) - self._get_current_time()
if (timeout < 0):
@@ -361,15 +353,23 @@
raise ZonemgrException("[b10-zonemgr] Error with select(): %s\n" % e)
break
+ def update_config_data(self, new_config):
+ """ update ZonemgrRefresh config """
+ self._lowerbound_refresh = new_config.get('lowerbound_refresh')
+ self._lowerbound_retry = new_config.get('lowerbound_retry')
+ self._max_transfer_timeout = new_config.get('max_transfer_timeout')
+ self._jitter_scope = new_config.get('jitter_scope')
+
class Zonemgr:
"""Zone manager class."""
def __init__(self):
+ self._zone_refresh = None
self._setup_session()
self._db_file = self.get_db_file()
# Create socket pair for communicating between main thread and zonemgr timer thread
self._master_socket, self._slave_socket = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM)
- self._zone_refresh= ZonemgrRefresh(self._cc, self._db_file, self._slave_socket)
+ self._zone_refresh = ZonemgrRefresh(self._cc, self._db_file, self._slave_socket, self._config_data)
self._start_zone_refresh_timer()
self._lock = threading.Lock()
@@ -391,6 +391,10 @@
self.command_handler)
self._module_cc.add_remote_config(AUTH_SPECFILE_LOCATION)
self._config_data = self._module_cc.get_full_config()
+ # jitter should not be bigger than half of the original value
+ if self._config_data.get('jitter_scope') > 0.5:
+ self._config_data['jitter_scope'] = 0.5
+ log_msg("[b10-zonemgr] jitter_scope should not be bigger than 0.5.")
self._module_cc.start()
def get_db_file(self):
@@ -417,13 +421,22 @@
th.join()
def config_handler(self, new_config):
- """Update config data."""
+ """ Update config data. """
answer = create_answer(0)
for key in new_config:
if key not in self._config_data:
answer = create_answer(1, "Unknown config data: " + str(key))
continue
+ # jitter should not be bigger than half of the original value
+ if key == 'jitter_scope':
+ if new_config.get(key) > 0.5:
+ new_config[key] = 0.5
+ log_msg("[b10-zonemgr] jitter_scope should not be bigger than 0.5.")
self._config_data[key] = new_config[key]
+
+ if (self._zone_refresh):
+ self._zone_refresh.update_config_data(self._config_data)
+
return answer
def _parse_cmd_params(self, args, command):
@@ -485,7 +498,7 @@
def run(self):
while not self._shutdown_event.is_set():
- self._module_cc.check_command()
+ self._module_cc.check_command(False)
zonemgrd = None
Modified: branches/trac191-rebased/src/bin/zonemgr/zonemgr.spec.pre.in
==============================================================================
--- branches/trac191-rebased/src/bin/zonemgr/zonemgr.spec.pre.in (original)
+++ branches/trac191-rebased/src/bin/zonemgr/zonemgr.spec.pre.in Fri Oct 15 05:19:19 2010
@@ -2,6 +2,30 @@
"module_spec": {
"module_name": "Zonemgr",
"config_data":[
+ {
+ "item_name": "lowerbound_refresh",
+ "item_type": "integer",
+ "item_optional": false,
+ "item_default": 10
+ },
+ {
+ "item_name": "lowerbound_retry",
+ "item_type": "integer",
+ "item_optional": false,
+ "item_default": 5
+ },
+ {
+ "item_name": "max_transfer_timeout",
+ "item_type": "integer",
+ "item_optional": false,
+ "item_default": 14400
+ },
+ {
+ "item_name": "jitter_scope",
+ "item_type": "real",
+ "item_optional": false,
+ "item_default": 0.25
+ }
],
"commands": [
{
Modified: branches/trac191-rebased/src/lib/bench/benchmark_util.cc
==============================================================================
--- branches/trac191-rebased/src/lib/bench/benchmark_util.cc (original)
+++ branches/trac191-rebased/src/lib/bench/benchmark_util.cc Fri Oct 15 05:19:19 2010
@@ -26,6 +26,8 @@
#include <dns/name.h>
#include <dns/message.h>
#include <dns/messagerenderer.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <dns/rrtype.h>
#include <dns/rrclass.h>
#include <dns/question.h>
Modified: branches/trac191-rebased/src/lib/bench/tests/loadquery_unittest.cc
==============================================================================
--- branches/trac191-rebased/src/lib/bench/tests/loadquery_unittest.cc (original)
+++ branches/trac191-rebased/src/lib/bench/tests/loadquery_unittest.cc Fri Oct 15 05:19:19 2010
@@ -22,6 +22,8 @@
#include <dns/buffer.h>
#include <dns/message.h>
#include <dns/name.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <dns/rrclass.h>
#include <dns/rrtype.h>
@@ -79,7 +81,6 @@
// Check if the header part indicates an expected standard query.
EXPECT_EQ(0, message.getQid());
EXPECT_EQ(Opcode::QUERY(), message.getOpcode());
- EXPECT_EQ(Rcode::NOERROR(), message.getRcode());
EXPECT_EQ(Rcode::NOERROR(), message.getRcode());
EXPECT_FALSE(message.getHeaderFlag(MessageFlag::QR()));
EXPECT_FALSE(message.getHeaderFlag(MessageFlag::AA()));
Modified: branches/trac191-rebased/src/lib/cc/tests/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/lib/cc/tests/Makefile.am (original)
+++ branches/trac191-rebased/src/lib/cc/tests/Makefile.am Fri Oct 15 05:19:19 2010
@@ -18,8 +18,7 @@
# (TODO: these need to be completed and moved to tests/)
run_unittests_SOURCES = data_unittests.cc session_unittests.cc run_unittests.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
-# TODO: remove PTHREAD_LDFLAGS (and from configure too)
-run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) $(PTHREAD_LDFLAGS)
+run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
run_unittests_LDADD = $(GTEST_LDADD)
run_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.la
Modified: branches/trac191-rebased/src/lib/config/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/lib/config/Makefile.am (original)
+++ branches/trac191-rebased/src/lib/config/Makefile.am Fri Oct 15 05:19:19 2010
@@ -1,4 +1,4 @@
-SUBDIRS = . testdata tests
+SUBDIRS = . tests
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_builddir)/src/lib/cc
@@ -8,45 +8,3 @@
libcfgclient_la_SOURCES = config_data.h config_data.cc module_spec.h module_spec.cc ccsession.cc ccsession.h
CLEANFILES = *.gcno *.gcda
-
-EXTRA_DIST = testdata/b10-config-bad1.db
-EXTRA_DIST += testdata/b10-config-bad2.db
-EXTRA_DIST += testdata/b10-config-bad3.db
-EXTRA_DIST += testdata/b10-config-bad4.db
-EXTRA_DIST += testdata/b10-config.db.master #.db will be auto-generated
-EXTRA_DIST += testdata/data22_1.data
-EXTRA_DIST += testdata/data22_2.data
-EXTRA_DIST += testdata/data22_3.data
-EXTRA_DIST += testdata/data22_4.data
-EXTRA_DIST += testdata/data22_5.data
-EXTRA_DIST += testdata/data22_6.data
-EXTRA_DIST += testdata/data22_7.data
-EXTRA_DIST += testdata/data22_8.data
-EXTRA_DIST += testdata/spec1.spec
-EXTRA_DIST += testdata/spec2.spec
-EXTRA_DIST += testdata/spec3.spec
-EXTRA_DIST += testdata/spec4.spec
-EXTRA_DIST += testdata/spec5.spec
-EXTRA_DIST += testdata/spec6.spec
-EXTRA_DIST += testdata/spec7.spec
-EXTRA_DIST += testdata/spec8.spec
-EXTRA_DIST += testdata/spec9.spec
-EXTRA_DIST += testdata/spec10.spec
-EXTRA_DIST += testdata/spec11.spec
-EXTRA_DIST += testdata/spec12.spec
-EXTRA_DIST += testdata/spec13.spec
-EXTRA_DIST += testdata/spec14.spec
-EXTRA_DIST += testdata/spec15.spec
-EXTRA_DIST += testdata/spec16.spec
-EXTRA_DIST += testdata/spec17.spec
-EXTRA_DIST += testdata/spec18.spec
-EXTRA_DIST += testdata/spec19.spec
-EXTRA_DIST += testdata/spec20.spec
-EXTRA_DIST += testdata/spec21.spec
-EXTRA_DIST += testdata/spec22.spec
-EXTRA_DIST += testdata/spec23.spec
-EXTRA_DIST += testdata/spec24.spec
-EXTRA_DIST += testdata/spec25.spec
-EXTRA_DIST += testdata/spec26.spec
-EXTRA_DIST += testdata/spec27.spec
-EXTRA_DIST += testdata/spec28.spec
Modified: branches/trac191-rebased/src/lib/config/tests/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/lib/config/tests/Makefile.am (original)
+++ branches/trac191-rebased/src/lib/config/tests/Makefile.am Fri Oct 15 05:19:19 2010
@@ -1,3 +1,5 @@
+SUBDIRS = testdata .
+
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
AM_CXXFLAGS = $(B10_CXXFLAGS)
@@ -21,8 +23,7 @@
run_unittests_SOURCES = ccsession_unittests.cc module_spec_unittests.cc config_data_unittests.cc run_unittests.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
-# TODO: remove PTHREAD_LDFLAGS (and from configure too)
-run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) $(PTHREAD_LDFLAGS)
+run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
run_unittests_LDADD = $(GTEST_LDADD)
run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
run_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.la
Modified: branches/trac191-rebased/src/lib/config/tests/data_def_unittests_config.h.in
==============================================================================
--- branches/trac191-rebased/src/lib/config/tests/data_def_unittests_config.h.in (original)
+++ branches/trac191-rebased/src/lib/config/tests/data_def_unittests_config.h.in Fri Oct 15 05:19:19 2010
@@ -12,4 +12,4 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#define TEST_DATA_PATH "@abs_srcdir@/../testdata"
+#define TEST_DATA_PATH "@abs_srcdir@/testdata"
Modified: branches/trac191-rebased/src/lib/datasrc/data_source.cc
==============================================================================
--- branches/trac191-rebased/src/lib/datasrc/data_source.cc (original)
+++ branches/trac191-rebased/src/lib/datasrc/data_source.cc Fri Oct 15 05:19:19 2010
@@ -32,6 +32,7 @@
#include <dns/buffer.h>
#include <dns/message.h>
#include <dns/name.h>
+#include <dns/rcode.h>
#include <dns/rdataclass.h>
#include <dns/rrset.h>
#include <dns/rrsetlist.h>
Modified: branches/trac191-rebased/src/lib/datasrc/tests/datasrc_unittest.cc
==============================================================================
--- branches/trac191-rebased/src/lib/datasrc/tests/datasrc_unittest.cc (original)
+++ branches/trac191-rebased/src/lib/datasrc/tests/datasrc_unittest.cc Fri Oct 15 05:19:19 2010
@@ -26,6 +26,8 @@
#include <dns/message.h>
#include <dns/messagerenderer.h>
#include <dns/question.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
#include <dns/rrclass.h>
Modified: branches/trac191-rebased/src/lib/datasrc/tests/query_unittest.cc
==============================================================================
--- branches/trac191-rebased/src/lib/datasrc/tests/query_unittest.cc (original)
+++ branches/trac191-rebased/src/lib/datasrc/tests/query_unittest.cc Fri Oct 15 05:19:19 2010
@@ -19,6 +19,7 @@
#include <dns/buffer.h>
#include <dns/message.h>
#include <dns/name.h>
+#include <dns/opcode.h>
#include <dns/rrtype.h>
#include <dns/rrclass.h>
Modified: branches/trac191-rebased/src/lib/dns/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/lib/dns/Makefile.am (original)
+++ branches/trac191-rebased/src/lib/dns/Makefile.am Fri Oct 15 05:19:19 2010
@@ -69,6 +69,8 @@
libdns___la_SOURCES += message.h message.cc
libdns___la_SOURCES += messagerenderer.h messagerenderer.cc
libdns___la_SOURCES += name.h name.cc
+libdns___la_SOURCES += opcode.h opcode.cc
+libdns___la_SOURCES += rcode.h rcode.cc
libdns___la_SOURCES += rdata.h rdata.cc
libdns___la_SOURCES += rrclass.cc
libdns___la_SOURCES += rrparamregistry.h
Modified: branches/trac191-rebased/src/lib/dns/exceptions.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/exceptions.cc (original)
+++ branches/trac191-rebased/src/lib/dns/exceptions.cc Fri Oct 15 05:19:19 2010
@@ -15,7 +15,7 @@
// $Id$
#include <dns/exceptions.h>
-#include <dns/message.h>
+#include <dns/rcode.h>
namespace isc {
namespace dns {
Modified: branches/trac191-rebased/src/lib/dns/message.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/message.cc (original)
+++ branches/trac191-rebased/src/lib/dns/message.cc Fri Oct 15 05:19:19 2010
@@ -33,6 +33,8 @@
#include <dns/message.h>
#include <dns/messagerenderer.h>
#include <dns/name.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <dns/question.h>
#include <dns/rdataclass.h>
#include <dns/rrclass.h>
@@ -62,95 +64,12 @@
const flags_t FLAG_AD = 0x0020;
const flags_t FLAG_CD = 0x0010;
-//
-// EDNS related constants
-//
-const uint32_t EXTRCODE_MASK = 0xff000000;
-
const unsigned int OPCODE_MASK = 0x7800;
const unsigned int OPCODE_SHIFT = 11;
const unsigned int RCODE_MASK = 0x000f;
const unsigned int FLAG_MASK = 0x8ff0;
const unsigned int MESSAGE_REPLYPRESERVE = (FLAG_RD | FLAG_CD);
-
-const Rcode rcodes[] = {
- Rcode::NOERROR(),
- Rcode::FORMERR(),
- Rcode::SERVFAIL(),
- Rcode::NXDOMAIN(),
- Rcode::NOTIMP(),
- Rcode::REFUSED(),
- Rcode::YXDOMAIN(),
- Rcode::YXRRSET(),
- Rcode::NXRRSET(),
- Rcode::NOTAUTH(),
- Rcode::NOTZONE(),
- Rcode::RESERVED11(),
- Rcode::RESERVED12(),
- Rcode::RESERVED13(),
- Rcode::RESERVED14(),
- Rcode::RESERVED15(),
- Rcode::BADVERS()
-};
-
-const char *rcodetext[] = {
- "NOERROR",
- "FORMERR",
- "SERVFAIL",
- "NXDOMAIN",
- "NOTIMP",
- "REFUSED",
- "YXDOMAIN",
- "YXRRSET",
- "NXRRSET",
- "NOTAUTH",
- "NOTZONE",
- "RESERVED11",
- "RESERVED12",
- "RESERVED13",
- "RESERVED14",
- "RESERVED15",
- "BADVERS"
-};
-
-const Opcode* opcodes[] = {
- &Opcode::QUERY(),
- &Opcode::IQUERY(),
- &Opcode::STATUS(),
- &Opcode::RESERVED3(),
- &Opcode::NOTIFY(),
- &Opcode::UPDATE(),
- &Opcode::RESERVED6(),
- &Opcode::RESERVED7(),
- &Opcode::RESERVED8(),
- &Opcode::RESERVED9(),
- &Opcode::RESERVED10(),
- &Opcode::RESERVED11(),
- &Opcode::RESERVED12(),
- &Opcode::RESERVED13(),
- &Opcode::RESERVED14(),
- &Opcode::RESERVED15()
-};
-
-const char *opcodetext[] = {
- "QUERY",
- "IQUERY",
- "STATUS",
- "RESERVED3",
- "NOTIFY",
- "UPDATE",
- "RESERVED6",
- "RESERVED7",
- "RESERVED8",
- "RESERVED9",
- "RESERVED10",
- "RESERVED11",
- "RESERVED12",
- "RESERVED13",
- "RESERVED14",
- "RESERVED15"
-};
const char *sectiontext[] = {
"QUESTION",
@@ -158,55 +77,6 @@
"AUTHORITY",
"ADDITIONAL"
};
-}
-
-string
-Opcode::toText() const {
- return (opcodetext[code_]);
-}
-
-namespace {
-// This diagram shows the wire-format representation of the 12-bit extended
-// form RCODEs and its relationship with implementation specific parameters.
-//
-// 0 3 11 15
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// |UNUSED | EXTENDED-RCODE | RCODE |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// <= EXTRCODE_SHIFT (4 bits)
-const unsigned int EXTRCODE_SHIFT = 4;
-}
-
-Rcode::Rcode(const uint16_t code) : code_(code) {
- if (code_ > MAX_RCODE) {
- isc_throw(OutOfRange, "Rcode is too large to construct: " << code_);
- }
-}
-
-Rcode::Rcode(const uint8_t code, const uint8_t extended_code) :
- code_((extended_code << EXTRCODE_SHIFT) | (code & RCODE_MASK))
-{
- if (code > RCODE_MASK) {
- isc_throw(OutOfRange,
- "Base Rcode is too large to construct: "
- << static_cast<unsigned int>(code));
- }
-}
-
-uint8_t
-Rcode::getExtendedCode() const {
- return (code_ >> EXTRCODE_SHIFT);
-}
-
-string
-Rcode::toText() const {
- if (code_ < sizeof(rcodetext) / sizeof (const char *)) {
- return (rcodetext[code_]);
- }
-
- ostringstream oss;
- oss << code_;
- return (oss.str());
}
namespace {
@@ -225,8 +95,16 @@
// for efficiency?
Message::Mode mode_;
qid_t qid_;
- Rcode rcode_;
+
+ // We want to use NULL for [op,r]code_ to mean the code being not
+ // correctly parsed or set. We store the real code object in
+ // xxcode_placeholder_ and have xxcode_ refer to it when the object
+ // is valid.
+ const Rcode* rcode_;
+ Rcode rcode_placeholder_;
const Opcode* opcode_;
+ Opcode opcode_placeholder_;
+
flags_t flags_;
bool header_parsed_;
@@ -242,12 +120,16 @@
#endif
void init();
+ void setOpcode(const Opcode& opcode);
+ void setRcode(const Rcode& rcode);
int parseQuestion(InputBuffer& buffer);
int parseSection(const Section& section, InputBuffer& buffer);
};
MessageImpl::MessageImpl(Message::Mode mode) :
- mode_(mode), rcode_(Rcode::NOERROR())
+ mode_(mode),
+ rcode_placeholder_(Rcode(0)), // as a placeholder the value doesn't matter
+ opcode_placeholder_(Opcode(0)) // ditto
{
init();
}
@@ -256,7 +138,7 @@
MessageImpl::init() {
flags_ = 0;
qid_ = 0;
- rcode_ = Rcode::NOERROR(); // XXX
+ rcode_ = NULL;
opcode_ = NULL;
edns_ = EDNSPtr();
@@ -271,6 +153,18 @@
rrsets_[sectionCodeToId(Section::ADDITIONAL())].clear();
}
+void
+MessageImpl::setOpcode(const Opcode& opcode) {
+ opcode_placeholder_ = opcode;
+ opcode_ = &opcode_placeholder_;
+}
+
+void
+MessageImpl::setRcode(const Rcode& rcode) {
+ rcode_placeholder_ = rcode;
+ rcode_ = &rcode_placeholder_;
+}
+
Message::Message(Mode mode) :
impl_(new MessageImpl(mode))
{}
@@ -318,7 +212,10 @@
const Rcode&
Message::getRcode() const {
- return (impl_->rcode_);
+ if (impl_->rcode_ == NULL) {
+ isc_throw(InvalidMessageOperation, "getRcode attempted before set");
+ }
+ return (*impl_->rcode_);
}
void
@@ -327,11 +224,14 @@
isc_throw(InvalidMessageOperation,
"setRcode performed in non-render mode");
}
- impl_->rcode_ = rcode;
+ impl_->setRcode(rcode);
}
const Opcode&
Message::getOpcode() const {
+ if (impl_->opcode_ == NULL) {
+ isc_throw(InvalidMessageOperation, "getOpcode attempted before set");
+ }
return (*impl_->opcode_);
}
@@ -341,7 +241,7 @@
isc_throw(InvalidMessageOperation,
"setOpcode performed in non-render mode");
}
- impl_->opcode_ = &opcode;
+ impl_->setOpcode(opcode);
}
ConstEDNSPtr
@@ -446,6 +346,14 @@
isc_throw(InvalidMessageOperation,
"Message rendering attempted in non render mode");
}
+ if (impl_->rcode_ == NULL) {
+ isc_throw(InvalidMessageOperation,
+ "Message rendering attempted without Rcode set");
+ }
+ if (impl_->opcode_ == NULL) {
+ isc_throw(InvalidMessageOperation,
+ "Message rendering attempted without Opcode set");
+ }
// reserve room for the header
renderer.skip(HEADERLEN);
@@ -484,12 +392,12 @@
// no EDNS has been set we generate a temporary local EDNS and use it.
if (!renderer.isTruncated()) {
ConstEDNSPtr local_edns = impl_->edns_;
- if (!local_edns && impl_->rcode_.getExtendedCode() != 0) {
+ if (!local_edns && impl_->rcode_->getExtendedCode() != 0) {
local_edns = ConstEDNSPtr(new EDNS());
}
if (local_edns) {
arcount += local_edns->toWire(renderer,
- impl_->rcode_.getExtendedCode());
+ impl_->rcode_->getExtendedCode());
}
}
@@ -512,7 +420,7 @@
uint16_t codes_and_flags =
(impl_->opcode_->getCode() << OPCODE_SHIFT) & OPCODE_MASK;
- codes_and_flags |= (impl_->rcode_.getCode() & RCODE_MASK);
+ codes_and_flags |= (impl_->rcode_->getCode() & RCODE_MASK);
codes_and_flags |= (impl_->flags_ & FLAG_MASK);
renderer.writeUint16At(codes_and_flags, header_pos);
header_pos += sizeof(uint16_t);
@@ -541,8 +449,8 @@
impl_->qid_ = buffer.readUint16();
const uint16_t codes_and_flags = buffer.readUint16();
- impl_->opcode_ = opcodes[((codes_and_flags & OPCODE_MASK) >> OPCODE_SHIFT)];
- impl_->rcode_ = rcodes[(codes_and_flags & RCODE_MASK)];
+ impl_->setOpcode(Opcode((codes_and_flags & OPCODE_MASK) >> OPCODE_SHIFT));
+ impl_->setRcode(Rcode(codes_and_flags & RCODE_MASK));
impl_->flags_ = (codes_and_flags & FLAG_MASK);
impl_->counts_[Section::QUESTION().getCode()] = buffer.readUint16();
impl_->counts_[Section::ANSWER().getCode()] = buffer.readUint16();
@@ -677,7 +585,7 @@
uint8_t extended_rcode;
edns_ = ConstEDNSPtr(createEDNSFromRR(name, rrclass, rrtype, ttl,
*rdata, extended_rcode));
- rcode_ = Rcode(rcode_.getCode(), extended_rcode);
+ setRcode(Rcode(rcode_->getCode(), extended_rcode));
continue;
} else {
vector<RRsetPtr>::iterator it =
@@ -718,11 +626,20 @@
string
Message::toText() const {
+ if (impl_->rcode_ == NULL) {
+ isc_throw(InvalidMessageOperation,
+ "Message::toText() attempted without Rcode set");
+ }
+ if (impl_->opcode_ == NULL) {
+ isc_throw(InvalidMessageOperation,
+ "Message::toText() attempted without Opcode set");
+ }
+
string s;
s += ";; ->>HEADER<<- opcode: " + impl_->opcode_->toText();
// for simplicity we don't consider extended rcode (unlike BIND9)
- s += ", status: " + impl_->rcode_.toText();
+ s += ", status: " + impl_->rcode_->toText();
s += ", id: " + boost::lexical_cast<string>(impl_->qid_);
s += "\n;; flags: ";
if (getHeaderFlag(MessageFlag::QR()))
@@ -948,16 +865,6 @@
}
ostream&
-operator<<(ostream& os, const Opcode& opcode) {
- return (os << opcode.toText());
-}
-
-ostream&
-operator<<(ostream& os, const Rcode& rcode) {
- return (os << rcode.toText());
-}
-
-ostream&
operator<<(ostream& os, const Message& message) {
return (os << message.toText());
}
Modified: branches/trac191-rebased/src/lib/dns/message.h
==============================================================================
--- branches/trac191-rebased/src/lib/dns/message.h (original)
+++ branches/trac191-rebased/src/lib/dns/message.h Fri Oct 15 05:19:19 2010
@@ -82,6 +82,8 @@
class MessageRenderer;
class Message;
class MessageImpl;
+class Opcode;
+class Rcode;
template <typename T>
struct SectionIteratorImpl;
@@ -160,312 +162,6 @@
return (f);
}
-/// \brief The \c Opcode class objects represent standard OPCODEs
-/// of the header section of DNS messages.
-///
-/// Note: since there are only 15 possible values, it may make more sense to
-/// simply define an enum type to represent these values.
-///
-/// Constant objects are defined for standard flags.
-class Opcode {
-public:
- uint16_t getCode() const { return (code_); }
- bool operator==(const Opcode& other) const
- { return (code_ == other.code_); }
- bool operator!=(const Opcode& other) const
- { return (code_ != other.code_); }
- std::string toText() const;
- static const Opcode& QUERY();
- static const Opcode& IQUERY();
- static const Opcode& STATUS();
- static const Opcode& RESERVED3();
- static const Opcode& NOTIFY();
- static const Opcode& UPDATE();
- static const Opcode& RESERVED6();
- static const Opcode& RESERVED7();
- static const Opcode& RESERVED8();
- static const Opcode& RESERVED9();
- static const Opcode& RESERVED10();
- static const Opcode& RESERVED11();
- static const Opcode& RESERVED12();
- static const Opcode& RESERVED13();
- static const Opcode& RESERVED14();
- static const Opcode& RESERVED15();
-private:
- Opcode(uint16_t code) : code_(code) {}
- uint16_t code_;
-};
-
-inline const Opcode&
-Opcode::QUERY()
-{
- static Opcode c(0);
- return (c);
-}
-
-inline const Opcode&
-Opcode::IQUERY()
-{
- static Opcode c(1);
- return (c);
-}
-
-inline const Opcode&
-Opcode::STATUS()
-{
- static Opcode c(2);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED3()
-{
- static Opcode c(3);
- return (c);
-}
-
-inline const Opcode&
-Opcode::NOTIFY()
-{
- static Opcode c(4);
- return (c);
-}
-
-inline const Opcode&
-Opcode::UPDATE()
-{
- static Opcode c(5);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED6()
-{
- static Opcode c(6);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED7()
-{
- static Opcode c(7);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED8()
-{
- static Opcode c(8);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED9()
-{
- static Opcode c(9);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED10()
-{
- static Opcode c(10);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED11()
-{
- static Opcode c(11);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED12()
-{
- static Opcode c(12);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED13()
-{
- static Opcode c(13);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED14()
-{
- static Opcode c(14);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED15()
-{
- static Opcode c(15);
- return (c);
-}
-
-/// \brief The \c Rcode class objects represent standard Response Codes
-/// (RCODEs) of the header section of DNS messages, and extended response
-/// codes as defined in the EDNS specification.
-///
-/// Constant objects are defined for standard flags.
-class Rcode {
-public:
- Rcode(const uint16_t code);
- Rcode(const uint8_t code, const uint8_t extended_code);
- uint16_t getCode() const { return (code_); }
- uint8_t getExtendedCode() const;
- bool operator==(const Rcode& other) const { return (code_ == other.code_); }
- bool operator!=(const Rcode& other) const { return (code_ != other.code_); }
- std::string toText() const;
- static const Rcode& NOERROR();
- static const Rcode& FORMERR();
- static const Rcode& SERVFAIL();
- static const Rcode& NXDOMAIN();
- static const Rcode& NOTIMP();
- static const Rcode& REFUSED();
- static const Rcode& YXDOMAIN();
- static const Rcode& YXRRSET();
- static const Rcode& NXRRSET();
- static const Rcode& NOTAUTH();
- static const Rcode& NOTZONE();
- static const Rcode& RESERVED11();
- static const Rcode& RESERVED12();
- static const Rcode& RESERVED13();
- static const Rcode& RESERVED14();
- static const Rcode& RESERVED15();
- // Extended Rcodes follow (EDNS required):
- static const Rcode& BADVERS();
-private:
- uint16_t code_;
-
- // EDNS-extended RCODEs are 12-bit unsigned integers.
- static const uint16_t MAX_RCODE = 0xfff;
-};
-
-inline const Rcode&
-Rcode::NOERROR()
-{
- static Rcode c(0);
- return (c);
-}
-
-inline const Rcode&
-Rcode::FORMERR()
-{
- static Rcode c(1);
- return (c);
-}
-
-inline const Rcode&
-Rcode::SERVFAIL()
-{
- static Rcode c(2);
- return (c);
-}
-
-inline const Rcode&
-Rcode::NXDOMAIN()
-{
- static Rcode c(3);
- return (c);
-}
-
-inline const Rcode&
-Rcode::NOTIMP()
-{
- static Rcode c(4);
- return (c);
-}
-
-inline const Rcode&
-Rcode::REFUSED()
-{
- static Rcode c(5);
- return (c);
-}
-
-inline const Rcode&
-Rcode::YXDOMAIN()
-{
- static Rcode c(6);
- return (c);
-}
-
-inline const Rcode&
-Rcode::YXRRSET()
-{
- static Rcode c(7);
- return (c);
-}
-
-inline const Rcode&
-Rcode::NXRRSET()
-{
- static Rcode c(8);
- return (c);
-}
-
-inline const Rcode&
-Rcode::NOTAUTH()
-{
- static Rcode c(9);
- return (c);
-}
-
-inline const Rcode&
-Rcode::NOTZONE()
-{
- static Rcode c(10);
- return (c);
-}
-
-inline const Rcode&
-Rcode::RESERVED11()
-{
- static Rcode c(11);
- return (c);
-}
-
-inline const Rcode&
-Rcode::RESERVED12()
-{
- static Rcode c(12);
- return (c);
-}
-
-inline const Rcode&
-Rcode::RESERVED13()
-{
- static Rcode c(13);
- return (c);
-}
-
-inline const Rcode&
-Rcode::RESERVED14()
-{
- static Rcode c(14);
- return (c);
-}
-
-inline const Rcode&
-Rcode::RESERVED15()
-{
- static Rcode c(15);
- return (c);
-}
-
-inline const Rcode&
-Rcode::BADVERS()
-{
- static Rcode c(16);
- return (c);
-}
-
/// \brief The \c Section class objects represent DNS message sections such
/// as the header, question, or answer.
///
@@ -644,6 +340,11 @@
/// included). In the \c PARSE mode, if the received message contains
/// an EDNS OPT RR, the corresponding extended code is identified and
/// returned.
+ ///
+ /// The message must have been properly parsed (in the case of the
+ /// \c PARSE mode) or an \c Rcode has been set (in the case of the
+ /// \c RENDER mode) beforehand. Otherwise, an exception of class
+ /// \c InvalidMessageOperation will be thrown.
const Rcode& getRcode() const;
/// \brief Set the Response Code of the message.
@@ -655,6 +356,11 @@
void setRcode(const Rcode& rcode);
/// \brief Return the OPCODE given in the header section of the message.
+ ///
+ /// The message must have been properly parsed (in the case of the
+ /// \c PARSE mode) or an \c Opcode has been set (in the case of the
+ /// \c RENDER mode) beforehand. Otherwise, an exception of class
+ /// \c InvalidMessageOperation will be thrown.
const Opcode& getOpcode() const;
/// \brief Set the OPCODE of the header section of the message.
@@ -750,10 +456,19 @@
void makeResponse();
/// \brief Convert the Message to a string.
+ ///
+ /// At least \c Opcode and \c Rcode must be validly set in the \c Message
+ /// (as a result of parse in the \c PARSE mode or by explicitly setting
+ /// in the \c RENDER mode); otherwise, an exception of
+ /// class \c InvalidMessageOperation will be thrown.
std::string toText() const;
/// \brief Render the message in wire formant into a \c MessageRenderer
/// object.
+ ///
+ /// This \c Message must be in the \c RENDER mode and both \c Opcode and
+ /// \c Rcode must have been set beforehand; otherwise, an exception of
+ /// class \c InvalidMessageOperation will be thrown.
void toWire(MessageRenderer& renderer);
/// \brief Parse the header section of the \c Message.
@@ -780,8 +495,6 @@
MessageImpl* impl_;
};
-std::ostream& operator<<(std::ostream& os, const Opcode& opcode);
-std::ostream& operator<<(std::ostream& os, const Rcode& rcode);
std::ostream& operator<<(std::ostream& os, const Message& message);
}
}
Modified: branches/trac191-rebased/src/lib/dns/python/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/lib/dns/python/Makefile.am (original)
+++ branches/trac191-rebased/src/lib/dns/python/Makefile.am Fri Oct 15 05:19:19 2010
@@ -16,6 +16,8 @@
EXTRA_DIST += message_python.cc
EXTRA_DIST += rrclass_python.cc
EXTRA_DIST += name_python.cc
+EXTRA_DIST += opcode_python.cc
+EXTRA_DIST += rcode_python.cc
EXTRA_DIST += rrset_python.cc
EXTRA_DIST += question_python.cc
EXTRA_DIST += rrttl_python.cc
Modified: branches/trac191-rebased/src/lib/dns/python/message_python.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/python/message_python.cc (original)
+++ branches/trac191-rebased/src/lib/dns/python/message_python.cc Fri Oct 15 05:19:19 2010
@@ -188,594 +188,6 @@
//
// End of MessageFlag wrapper
//
-
-
-//
-// Opcode
-//
-class s_Opcode : public PyObject {
-public:
- const Opcode* opcode;
-};
-
-static int Opcode_init(s_Opcode* self, PyObject* args);
-static void Opcode_destroy(s_Opcode* self);
-
-static PyObject* Opcode_getCode(s_Opcode* self);
-static PyObject* Opcode_toText(s_Opcode* self);
-static PyObject* Opcode_str(PyObject* self);
-static PyObject* Opcode_QUERY(s_Opcode* self);
-static PyObject* Opcode_IQUERY(s_Opcode* self);
-static PyObject* Opcode_STATUS(s_Opcode* self);
-static PyObject* Opcode_RESERVED3(s_Opcode* self);
-static PyObject* Opcode_NOTIFY(s_Opcode* self);
-static PyObject* Opcode_UPDATE(s_Opcode* self);
-static PyObject* Opcode_RESERVED6(s_Opcode* self);
-static PyObject* Opcode_RESERVED7(s_Opcode* self);
-static PyObject* Opcode_RESERVED8(s_Opcode* self);
-static PyObject* Opcode_RESERVED9(s_Opcode* self);
-static PyObject* Opcode_RESERVED10(s_Opcode* self);
-static PyObject* Opcode_RESERVED11(s_Opcode* self);
-static PyObject* Opcode_RESERVED12(s_Opcode* self);
-static PyObject* Opcode_RESERVED13(s_Opcode* self);
-static PyObject* Opcode_RESERVED14(s_Opcode* self);
-static PyObject* Opcode_RESERVED15(s_Opcode* self);
-static PyObject* Opcode_richcmp(s_Opcode* self, s_Opcode* other, int op);
-
-static PyMethodDef Opcode_methods[] = {
- { "get_code", reinterpret_cast<PyCFunction>(Opcode_getCode), METH_NOARGS, "Returns the code value" },
- { "to_text", reinterpret_cast<PyCFunction>(Opcode_toText), METH_NOARGS, "Returns the text representation" },
- { "QUERY", reinterpret_cast<PyCFunction>(Opcode_QUERY), METH_NOARGS | METH_STATIC, "Creates a QUERY Opcode" },
- { "IQUERY", reinterpret_cast<PyCFunction>(Opcode_IQUERY), METH_NOARGS | METH_STATIC, "Creates a IQUERY Opcode" },
- { "STATUS", reinterpret_cast<PyCFunction>(Opcode_STATUS), METH_NOARGS | METH_STATIC, "Creates a STATUS Opcode" },
- { "RESERVED3", reinterpret_cast<PyCFunction>(Opcode_RESERVED3), METH_NOARGS | METH_STATIC, "Creates a RESERVED3 Opcode" },
- { "NOTIFY", reinterpret_cast<PyCFunction>(Opcode_NOTIFY), METH_NOARGS | METH_STATIC, "Creates a NOTIFY Opcode" },
- { "UPDATE", reinterpret_cast<PyCFunction>(Opcode_UPDATE), METH_NOARGS | METH_STATIC, "Creates a UPDATE Opcode" },
- { "RESERVED6", reinterpret_cast<PyCFunction>(Opcode_RESERVED6), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
- { "RESERVED7", reinterpret_cast<PyCFunction>(Opcode_RESERVED7), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
- { "RESERVED8", reinterpret_cast<PyCFunction>(Opcode_RESERVED8), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
- { "RESERVED9", reinterpret_cast<PyCFunction>(Opcode_RESERVED9), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
- { "RESERVED10", reinterpret_cast<PyCFunction>(Opcode_RESERVED10), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
- { "RESERVED11", reinterpret_cast<PyCFunction>(Opcode_RESERVED11), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
- { "RESERVED12", reinterpret_cast<PyCFunction>(Opcode_RESERVED12), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
- { "RESERVED13", reinterpret_cast<PyCFunction>(Opcode_RESERVED13), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
- { "RESERVED14", reinterpret_cast<PyCFunction>(Opcode_RESERVED14), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
- { "RESERVED15", reinterpret_cast<PyCFunction>(Opcode_RESERVED15), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
- { NULL, NULL, 0, NULL }
-};
-
-static PyTypeObject opcode_type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "pydnspp.Opcode",
- sizeof(s_Opcode), // tp_basicsize
- 0, // tp_itemsize
- (destructor)Opcode_destroy, // tp_dealloc
- NULL, // tp_print
- NULL, // tp_getattr
- NULL, // tp_setattr
- NULL, // tp_reserved
- NULL, // tp_repr
- NULL, // tp_as_number
- NULL, // tp_as_sequence
- NULL, // tp_as_mapping
- NULL, // tp_hash
- NULL, // tp_call
- Opcode_str, // tp_str
- NULL, // tp_getattro
- NULL, // tp_setattro
- NULL, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "The Opcode class objects represent standard OPCODEs "
- "of the header section of DNS messages.",
- NULL, // tp_traverse
- NULL, // tp_clear
- (richcmpfunc)Opcode_richcmp, // tp_richcompare
- 0, // tp_weaklistoffset
- NULL, // tp_iter
- NULL, // tp_iternext
- Opcode_methods, // tp_methods
- NULL, // tp_members
- NULL, // tp_getset
- NULL, // tp_base
- NULL, // tp_dict
- NULL, // tp_descr_get
- NULL, // tp_descr_set
- 0, // tp_dictoffset
- (initproc)Opcode_init, // tp_init
- NULL, // tp_alloc
- PyType_GenericNew, // tp_new
- NULL, // tp_free
- NULL, // tp_is_gc
- NULL, // tp_bases
- NULL, // tp_mro
- NULL, // tp_cache
- NULL, // tp_subclasses
- NULL, // tp_weaklist
- NULL, // tp_del
- 0 // tp_version_tag
-};
-
-
-static int
-Opcode_init(s_Opcode* self UNUSED_PARAM, PyObject* args UNUSED_PARAM) {
- PyErr_SetString(PyExc_NotImplementedError,
- "Opcode can't be built directly");
- return (-1);
-}
-
-static void
-Opcode_destroy(s_Opcode* self) {
- // We only use the consts from Opcode, so don't
- // delete self->opcode here
- self->opcode = NULL;
- Py_TYPE(self)->tp_free(self);
-}
-
-static PyObject*
-Opcode_getCode(s_Opcode* self) {
- return (Py_BuildValue("I", self->opcode->getCode()));
-}
-
-static PyObject*
-Opcode_toText(s_Opcode* self) {
- return (Py_BuildValue("s", self->opcode->toText().c_str()));
-}
-
-static PyObject*
-Opcode_str(PyObject* self) {
- // Simply call the to_text method we already defined
- return (PyObject_CallMethod(self,
- const_cast<char*>("to_text"),
- const_cast<char*>("")));
-}
-
-static PyObject*
-Opcode_createStatic(const Opcode& opcode) {
- s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
- if (ret != NULL) {
- ret->opcode = &opcode;
- }
- return (ret);
-}
-
-static PyObject*
-Opcode_QUERY(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::QUERY()));
-}
-
-static PyObject*
-Opcode_IQUERY(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::IQUERY()));
-}
-
-static PyObject*
-Opcode_STATUS(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::STATUS()));
-}
-
-static PyObject*
-Opcode_RESERVED3(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED3()));
-}
-
-static PyObject*
-Opcode_NOTIFY(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::NOTIFY()));
-}
-
-static PyObject*
-Opcode_UPDATE(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::UPDATE()));
-}
-
-static PyObject*
-Opcode_RESERVED6(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED6()));
-}
-
-static PyObject*
-Opcode_RESERVED7(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED7()));
-}
-
-static PyObject*
-Opcode_RESERVED8(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED8()));
-}
-
-static PyObject*
-Opcode_RESERVED9(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED9()));
-}
-
-static PyObject*
-Opcode_RESERVED10(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED10()));
-}
-
-static PyObject*
-Opcode_RESERVED11(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED11()));
-}
-
-static PyObject*
-Opcode_RESERVED12(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED12()));
-}
-
-static PyObject*
-Opcode_RESERVED13(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED13()));
-}
-
-static PyObject*
-Opcode_RESERVED14(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED14()));
-}
-
-static PyObject*
-Opcode_RESERVED15(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED15()));
-}
-
-static PyObject*
-Opcode_richcmp(s_Opcode* self, s_Opcode* other, int op) {
- bool c = false;
-
- // Check for null and if the types match. If different type,
- // simply return False
- if (!other || (self->ob_type != other->ob_type)) {
- Py_RETURN_FALSE;
- }
-
- // Only equals and not equals here, unorderable type
- switch (op) {
- case Py_LT:
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
- return (NULL);
- break;
- case Py_LE:
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
- return (NULL);
- break;
- case Py_EQ:
- c = (*self->opcode == *other->opcode);
- break;
- case Py_NE:
- c = (*self->opcode != *other->opcode);
- break;
- case Py_GT:
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
- return (NULL);
- break;
- case Py_GE:
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
- return (NULL);
- break;
- }
- if (c)
- Py_RETURN_TRUE;
- else
- Py_RETURN_FALSE;
-}
-
-//
-// End of Opcode wrapper
-//
-
-//
-// Rcode
-//
-
-// We added a helper variable static_code here
-// Since we can create Rcodes dynamically with Rcode(int), but also
-// use the static globals (Rcode::NOERROR() etc), we use this
-// variable to see if the code came from one of the latter, in which
-// case Rcode_destroy should not free it (the other option is to
-// allocate new Rcodes for every use of the static ones, but this
-// seems more efficient).
-class s_Rcode : public PyObject {
-public:
- const Rcode* rcode;
- bool static_code;
-};
-
-static int Rcode_init(s_Rcode* self, PyObject* args);
-static void Rcode_destroy(s_Rcode* self);
-
-static PyObject* Rcode_getCode(s_Rcode* self);
-static PyObject* Rcode_getExtendedCode(const s_Rcode* self);
-static PyObject* Rcode_toText(s_Rcode* self);
-static PyObject* Rcode_str(PyObject* self);
-static PyObject* Rcode_NOERROR(s_Rcode* self);
-static PyObject* Rcode_FORMERR(s_Rcode* self);
-static PyObject* Rcode_SERVFAIL(s_Rcode* self);
-static PyObject* Rcode_NXDOMAIN(s_Rcode* self);
-static PyObject* Rcode_NOTIMP(s_Rcode* self);
-static PyObject* Rcode_REFUSED(s_Rcode* self);
-static PyObject* Rcode_YXDOMAIN(s_Rcode* self);
-static PyObject* Rcode_YXRRSET(s_Rcode* self);
-static PyObject* Rcode_NXRRSET(s_Rcode* self);
-static PyObject* Rcode_NOTAUTH(s_Rcode* self);
-static PyObject* Rcode_NOTZONE(s_Rcode* self);
-static PyObject* Rcode_RESERVED11(s_Rcode* self);
-static PyObject* Rcode_RESERVED12(s_Rcode* self);
-static PyObject* Rcode_RESERVED13(s_Rcode* self);
-static PyObject* Rcode_RESERVED14(s_Rcode* self);
-static PyObject* Rcode_RESERVED15(s_Rcode* self);
-static PyObject* Rcode_BADVERS(s_Rcode* self);
-static PyObject* Rcode_richcmp(s_Rcode* self, s_Rcode* other, int op);
-
-static PyMethodDef Rcode_methods[] = {
- { "get_code", reinterpret_cast<PyCFunction>(Rcode_getCode), METH_NOARGS, "Returns the code value" },
- { "get_extended_code",
- reinterpret_cast<PyCFunction>(Rcode_getExtendedCode),
- METH_NOARGS, "Returns the extended code value." },
- { "to_text", reinterpret_cast<PyCFunction>(Rcode_toText), METH_NOARGS, "Returns the text representation" },
- { "NOERROR", reinterpret_cast<PyCFunction>(Rcode_NOERROR), METH_NOARGS | METH_STATIC, "Creates a NOERROR Rcode" },
- { "FORMERR", reinterpret_cast<PyCFunction>(Rcode_FORMERR), METH_NOARGS | METH_STATIC, "Creates a FORMERR Rcode" },
- { "SERVFAIL", reinterpret_cast<PyCFunction>(Rcode_SERVFAIL), METH_NOARGS | METH_STATIC, "Creates a SERVFAIL Rcode" },
- { "NXDOMAIN", reinterpret_cast<PyCFunction>(Rcode_NXDOMAIN), METH_NOARGS | METH_STATIC, "Creates a NXDOMAIN Rcode" },
- { "NOTIMP", reinterpret_cast<PyCFunction>(Rcode_NOTIMP), METH_NOARGS | METH_STATIC, "Creates a NOTIMP Rcode" },
- { "REFUSED", reinterpret_cast<PyCFunction>(Rcode_REFUSED), METH_NOARGS | METH_STATIC, "Creates a REFUSED Rcode" },
- { "YXDOMAIN", reinterpret_cast<PyCFunction>(Rcode_YXDOMAIN), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
- { "YXRRSET", reinterpret_cast<PyCFunction>(Rcode_YXRRSET), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
- { "NXRRSET", reinterpret_cast<PyCFunction>(Rcode_NXRRSET), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
- { "NOTAUTH", reinterpret_cast<PyCFunction>(Rcode_NOTAUTH), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
- { "NOTZONE", reinterpret_cast<PyCFunction>(Rcode_NOTZONE), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
- { "RESERVED11", reinterpret_cast<PyCFunction>(Rcode_RESERVED11), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
- { "RESERVED12", reinterpret_cast<PyCFunction>(Rcode_RESERVED12), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
- { "RESERVED13", reinterpret_cast<PyCFunction>(Rcode_RESERVED13), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
- { "RESERVED14", reinterpret_cast<PyCFunction>(Rcode_RESERVED14), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
- { "RESERVED15", reinterpret_cast<PyCFunction>(Rcode_RESERVED15), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
- { "BADVERS", reinterpret_cast<PyCFunction>(Rcode_BADVERS), METH_NOARGS | METH_STATIC, "Creates a BADVERS Rcode" },
- { NULL, NULL, 0, NULL }
-};
-
-static PyTypeObject rcode_type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "pydnspp.Rcode",
- sizeof(s_Rcode), // tp_basicsize
- 0, // tp_itemsize
- (destructor)Rcode_destroy, // tp_dealloc
- NULL, // tp_print
- NULL, // tp_getattr
- NULL, // tp_setattr
- NULL, // tp_reserved
- NULL, // tp_repr
- NULL, // tp_as_number
- NULL, // tp_as_sequence
- NULL, // tp_as_mapping
- NULL, // tp_hash
- NULL, // tp_call
- Rcode_str, // tp_str
- NULL, // tp_getattro
- NULL, // tp_setattro
- NULL, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "The Rcode class objects represent standard RCODEs"
- "of the header section of DNS messages.",
- NULL, // tp_traverse
- NULL, // tp_clear
- (richcmpfunc)Rcode_richcmp, // tp_richcompare
- 0, // tp_weaklistoffset
- NULL, // tp_iter
- NULL, // tp_iternext
- Rcode_methods, // tp_methods
- NULL, // tp_members
- NULL, // tp_getset
- NULL, // tp_base
- NULL, // tp_dict
- NULL, // tp_descr_get
- NULL, // tp_descr_set
- 0, // tp_dictoffset
- (initproc)Rcode_init, // tp_init
- NULL, // tp_alloc
- PyType_GenericNew, // tp_new
- NULL, // tp_free
- NULL, // tp_is_gc
- NULL, // tp_bases
- NULL, // tp_mro
- NULL, // tp_cache
- NULL, // tp_subclasses
- NULL, // tp_weaklist
- NULL, // tp_del
- 0 // tp_version_tag
-};
-
-
-static int
-Rcode_init(s_Rcode* self UNUSED_PARAM, PyObject* args UNUSED_PARAM) {
- uint16_t code = 0;
- if (PyArg_ParseTuple(args, "h", &code)) {
- try {
- self->rcode = new Rcode(code);
- self->static_code = false;
- } catch (const isc::OutOfRange&) {
- PyErr_SetString(PyExc_OverflowError,
- "rcode out of range");
- return (-1);
- }
- return (0);
- } else {
- return (-1);
- }
-}
-
-static void
-Rcode_destroy(s_Rcode* self) {
- // Depending on whether we created the rcode or are referring
- // to a global static one, we do or do not delete self->rcode here
- if (!self->static_code) {
- delete self->rcode;
- }
- self->rcode = NULL;
- Py_TYPE(self)->tp_free(self);
-}
-
-static PyObject*
-Rcode_getCode(s_Rcode* self) {
- return (Py_BuildValue("I", self->rcode->getCode()));
-}
-
-static PyObject*
-Rcode_getExtendedCode(const s_Rcode* self) {
- return (Py_BuildValue("B", self->rcode->getExtendedCode()));
-}
-
-static PyObject*
-Rcode_toText(s_Rcode* self) {
- return (Py_BuildValue("s", self->rcode->toText().c_str()));
-}
-
-static PyObject*
-Rcode_str(PyObject* self) {
- // Simply call the to_text method we already defined
- return (PyObject_CallMethod(self,
- const_cast<char*>("to_text"),
- const_cast<char*>("")));
-}
-
-static PyObject*
-Rcode_createStatic(const Rcode& rcode) {
- s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
- if (ret != NULL) {
- ret->rcode = &rcode;
- ret->static_code = true;
- }
- return (ret);
-}
-
-static PyObject*
-Rcode_NOERROR(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::NOERROR()));
-}
-
-static PyObject*
-Rcode_FORMERR(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::FORMERR()));
-}
-
-static PyObject*
-Rcode_SERVFAIL(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::SERVFAIL()));
-}
-
-static PyObject*
-Rcode_NXDOMAIN(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::NXDOMAIN()));
-}
-
-static PyObject*
-Rcode_NOTIMP(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::NOTIMP()));
-}
-
-static PyObject*
-Rcode_REFUSED(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::REFUSED()));
-}
-
-static PyObject*
-Rcode_YXDOMAIN(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::YXDOMAIN()));
-}
-
-static PyObject*
-Rcode_YXRRSET(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::YXRRSET()));
-}
-
-static PyObject*
-Rcode_NXRRSET(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::NXRRSET()));
-}
-
-static PyObject*
-Rcode_NOTAUTH(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::NOTAUTH()));
-}
-
-static PyObject*
-Rcode_NOTZONE(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::NOTZONE()));
-}
-
-static PyObject*
-Rcode_RESERVED11(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::RESERVED11()));
-}
-
-static PyObject*
-Rcode_RESERVED12(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::RESERVED12()));
-}
-
-static PyObject*
-Rcode_RESERVED13(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::RESERVED13()));
-}
-
-static PyObject*
-Rcode_RESERVED14(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::RESERVED14()));
-}
-
-static PyObject*
-Rcode_RESERVED15(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::RESERVED15()));
-}
-
-static PyObject*
-Rcode_BADVERS(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::BADVERS()));
-}
-
-static PyObject*
-Rcode_richcmp(s_Rcode* self, s_Rcode* other, int op) {
- bool c = false;
-
- // Check for null and if the types match. If different type,
- // simply return False
- if (!other || (self->ob_type != other->ob_type)) {
- Py_RETURN_FALSE;
- }
-
- // Only equals and not equals here, unorderable type
- switch (op) {
- case Py_LT:
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
- return (NULL);
- break;
- case Py_LE:
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
- return (NULL);
- break;
- case Py_EQ:
- c = (*self->rcode == *other->rcode);
- break;
- case Py_NE:
- c = (*self->rcode != *other->rcode);
- break;
- case Py_GT:
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
- return (NULL);
- break;
- case Py_GE:
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
- return (NULL);
- break;
- }
- if (c)
- Py_RETURN_TRUE;
- else
- Py_RETURN_FALSE;
-}
-
-//
-// End of Rcode wrapper
-//
-
//
// Section
@@ -1255,12 +667,18 @@
rcode = static_cast<s_Rcode*>(rcode_type.tp_alloc(&rcode_type, 0));
if (rcode != NULL) {
- rcode->rcode = new Rcode(self->message->getRcode());
- if (rcode->rcode == NULL)
- {
+ rcode->rcode = NULL;
+ try {
+ rcode->rcode = new Rcode(self->message->getRcode());
+ } catch (const InvalidMessageOperation& imo) {
+ PyErr_SetString(po_InvalidMessageOperation, imo.what());
+ } catch (...) {
+ PyErr_SetString(po_IscException, "Unexpected exception");
+ }
+ if (rcode->rcode == NULL) {
Py_DECREF(rcode);
return (NULL);
- }
+ }
}
return (rcode);
@@ -1287,15 +705,18 @@
opcode = static_cast<s_Opcode*>(opcode_type.tp_alloc(&opcode_type, 0));
if (opcode != NULL) {
- // Note that we do not new and delete for opcodes.
- // all rcodes point to the statics defined in
- // message.cc
- opcode->opcode = &self->message->getOpcode();
- if (opcode->opcode == NULL)
- {
+ opcode->opcode = NULL;
+ try {
+ opcode->opcode = new Opcode(self->message->getOpcode());
+ } catch (const InvalidMessageOperation& imo) {
+ PyErr_SetString(po_InvalidMessageOperation, imo.what());
+ } catch (...) {
+ PyErr_SetString(po_IscException, "Unexpected exception");
+ }
+ if (opcode->opcode == NULL) {
Py_DECREF(opcode);
return (NULL);
- }
+ }
}
return (opcode);
@@ -1486,7 +907,16 @@
static PyObject*
Message_toText(s_Message* self) {
// Py_BuildValue makes python objects from native data
- return (Py_BuildValue("s", self->message->toText().c_str()));
+ try {
+ return (Py_BuildValue("s", self->message->toText().c_str()));
+ } catch (const InvalidMessageOperation& imo) {
+ PyErr_Clear();
+ PyErr_SetString(po_InvalidMessageOperation, imo.what());
+ return (NULL);
+ } catch (...) {
+ PyErr_SetString(po_IscException, "Unexpected exception");
+ return (NULL);
+ }
}
static PyObject*
Modified: branches/trac191-rebased/src/lib/dns/python/pydnspp.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/python/pydnspp.cc (original)
+++ branches/trac191-rebased/src/lib/dns/python/pydnspp.cc Fri Oct 15 05:19:19 2010
@@ -57,6 +57,8 @@
#include <dns/python/rrset_python.cc> // needs Rdata, RRTTL
#include <dns/python/question_python.cc> // needs RRClass, RRType, RRTTL,
// Name
+#include <dns/python/opcode_python.cc>
+#include <dns/python/rcode_python.cc>
#include <dns/python/edns_python.cc> // needs Messagerenderer, Rcode
#include <dns/python/message_python.cc> // needs RRset, Question
@@ -128,6 +130,14 @@
return (NULL);
}
+ if (!initModulePart_Opcode(mod)) {
+ return (NULL);
+ }
+
+ if (!initModulePart_Rcode(mod)) {
+ return (NULL);
+ }
+
if (!initModulePart_Message(mod)) {
return (NULL);
}
Modified: branches/trac191-rebased/src/lib/dns/python/tests/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/lib/dns/python/tests/Makefile.am (original)
+++ branches/trac191-rebased/src/lib/dns/python/tests/Makefile.am Fri Oct 15 05:19:19 2010
@@ -3,6 +3,8 @@
PYTESTS += messagerenderer_python_test.py
PYTESTS += name_python_test.py
PYTESTS += question_python_test.py
+PYTESTS += opcode_python_test.py
+PYTESTS += rcode_python_test.py
PYTESTS += rdata_python_test.py
PYTESTS += rrclass_python_test.py
PYTESTS += rrset_python_test.py
@@ -10,6 +12,7 @@
PYTESTS += rrtype_python_test.py
EXTRA_DIST = $(PYTESTS)
+EXTRA_DIST += testutil.py
# If necessary (rare cases), explicitly specify paths to dynamic libraries
# required by loadable python modules.
Modified: branches/trac191-rebased/src/lib/dns/python/tests/message_python_test.py
==============================================================================
--- branches/trac191-rebased/src/lib/dns/python/tests/message_python_test.py (original)
+++ branches/trac191-rebased/src/lib/dns/python/tests/message_python_test.py Fri Oct 15 05:19:19 2010
@@ -34,163 +34,6 @@
self.assertEqual(0x0080, MessageFlag.RA().get_bit())
self.assertEqual(0x0020, MessageFlag.AD().get_bit())
self.assertEqual(0x0010, MessageFlag.CD().get_bit())
-
-class OpcodeTest(unittest.TestCase):
- def test_init(self):
- self.assertRaises(NotImplementedError, Opcode)
-
- def test_get_code(self):
- self.assertEqual(0, Opcode.QUERY().get_code())
- self.assertEqual(1, Opcode.IQUERY().get_code())
- self.assertEqual(2, Opcode.STATUS().get_code())
- self.assertEqual(3, Opcode.RESERVED3().get_code())
- self.assertEqual(4, Opcode.NOTIFY().get_code())
- self.assertEqual(5, Opcode.UPDATE().get_code())
- self.assertEqual(6, Opcode.RESERVED6().get_code())
- self.assertEqual(7, Opcode.RESERVED7().get_code())
- self.assertEqual(8, Opcode.RESERVED8().get_code())
- self.assertEqual(9, Opcode.RESERVED9().get_code())
- self.assertEqual(10, Opcode.RESERVED10().get_code())
- self.assertEqual(11, Opcode.RESERVED11().get_code())
- self.assertEqual(12, Opcode.RESERVED12().get_code())
- self.assertEqual(13, Opcode.RESERVED13().get_code())
- self.assertEqual(14, Opcode.RESERVED14().get_code())
- self.assertEqual(15, Opcode.RESERVED15().get_code())
-
- def test_to_text(self):
- self.assertEqual("QUERY", Opcode.QUERY().to_text())
- self.assertEqual("QUERY", str(Opcode.QUERY()))
- self.assertEqual("IQUERY", Opcode.IQUERY().to_text())
- self.assertEqual("STATUS", Opcode.STATUS().to_text())
- self.assertEqual("RESERVED3", Opcode.RESERVED3().to_text())
- self.assertEqual("NOTIFY", Opcode.NOTIFY().to_text())
- self.assertEqual("UPDATE", Opcode.UPDATE().to_text())
- self.assertEqual("RESERVED6", Opcode.RESERVED6().to_text())
- self.assertEqual("RESERVED7", Opcode.RESERVED7().to_text())
- self.assertEqual("RESERVED8", Opcode.RESERVED8().to_text())
- self.assertEqual("RESERVED9", Opcode.RESERVED9().to_text())
- self.assertEqual("RESERVED10", Opcode.RESERVED10().to_text())
- self.assertEqual("RESERVED11", Opcode.RESERVED11().to_text())
- self.assertEqual("RESERVED12", Opcode.RESERVED12().to_text())
- self.assertEqual("RESERVED13", Opcode.RESERVED13().to_text())
- self.assertEqual("RESERVED14", Opcode.RESERVED14().to_text())
- self.assertEqual("RESERVED15", Opcode.RESERVED15().to_text())
-
- def test_richcmp(self):
- o1 = Opcode.QUERY()
- o2 = Opcode.NOTIFY()
- o3 = Opcode.NOTIFY()
- self.assertTrue(o2 == o3)
- self.assertFalse(o2 != o3)
- self.assertTrue(o1 != o2)
- self.assertFalse(o1 == 1)
- self.assertFalse(o1 == o2)
- # can't use assertRaises here...
- try:
- o1 < o2
- self.fail("operation that should have raised an error unexpectedly succeeded")
- except Exception as err:
- self.assertEqual(TypeError, type(err))
- try:
- o1 <= o2
- self.fail("operation that should have raised an error unexpectedly succeeded")
- except Exception as err:
- self.assertEqual(TypeError, type(err))
- try:
- o1 > o2
- self.fail("operation that should have raised an error unexpectedly succeeded")
- except Exception as err:
- self.assertEqual(TypeError, type(err))
- try:
- o1 >= o2
- self.fail("operation that should have raised an error unexpectedly succeeded")
- except Exception as err:
- self.assertEqual(TypeError, type(err))
-
-class RcodeTest(unittest.TestCase):
- def test_init(self):
- self.assertRaises(TypeError, Rcode, "wrong")
- self.assertRaises(OverflowError, Rcode, 65536)
- self.assertEqual(Rcode(0).get_code(), 0)
-
- self.assertEqual(0, Rcode(0).get_code())
- self.assertEqual(0xfff, Rcode(0xfff).get_code()) # possible max code
-
- # should fail on attempt of construction with an out of range code
- self.assertRaises(OverflowError, Rcode, 0x1000)
- self.assertRaises(OverflowError, Rcode, 0xffff)
-
- def test_get_code(self):
- self.assertEqual(0, Rcode.NOERROR().get_code())
- self.assertEqual(1, Rcode.FORMERR().get_code())
- self.assertEqual(2, Rcode.SERVFAIL().get_code())
- self.assertEqual(3, Rcode.NXDOMAIN().get_code())
- self.assertEqual(4, Rcode.NOTIMP().get_code())
- self.assertEqual(5, Rcode.REFUSED().get_code())
- self.assertEqual(6, Rcode.YXDOMAIN().get_code())
- self.assertEqual(7, Rcode.YXRRSET().get_code())
- self.assertEqual(8, Rcode.NXRRSET().get_code())
- self.assertEqual(9, Rcode.NOTAUTH().get_code())
- self.assertEqual(10, Rcode.NOTZONE().get_code())
- self.assertEqual(11, Rcode.RESERVED11().get_code())
- self.assertEqual(12, Rcode.RESERVED12().get_code())
- self.assertEqual(13, Rcode.RESERVED13().get_code())
- self.assertEqual(14, Rcode.RESERVED14().get_code())
- self.assertEqual(15, Rcode.RESERVED15().get_code())
- self.assertEqual(16, Rcode.BADVERS().get_code())
-
- def test_to_text(self):
- self.assertEqual("NOERROR", Rcode(0).to_text())
- self.assertEqual("NOERROR", str(Rcode(0)))
- self.assertEqual("FORMERR", Rcode(1).to_text())
- self.assertEqual("SERVFAIL", Rcode(2).to_text())
- self.assertEqual("NXDOMAIN", Rcode(3).to_text())
- self.assertEqual("NOTIMP", Rcode(4).to_text())
- self.assertEqual("REFUSED", Rcode(5).to_text())
- self.assertEqual("YXDOMAIN", Rcode(6).to_text())
- self.assertEqual("YXRRSET", Rcode(7).to_text())
- self.assertEqual("NXRRSET", Rcode(8).to_text())
- self.assertEqual("NOTAUTH", Rcode(9).to_text())
- self.assertEqual("NOTZONE", Rcode(10).to_text())
- self.assertEqual("RESERVED11", Rcode(11).to_text())
- self.assertEqual("RESERVED12", Rcode(12).to_text())
- self.assertEqual("RESERVED13", Rcode(13).to_text())
- self.assertEqual("RESERVED14", Rcode(14).to_text())
- self.assertEqual("RESERVED15", Rcode(15).to_text())
- self.assertEqual("BADVERS", Rcode(16).to_text())
-
- self.assertEqual("17", Rcode(Rcode.BADVERS().get_code() + 1).to_text())
- self.assertEqual("4095", Rcode(0xfff).to_text())
-
- def test_richcmp(self):
- r1 = Rcode.NOERROR()
- r2 = Rcode.FORMERR()
- r3 = Rcode.FORMERR()
- self.assertTrue(r2 == r3)
- self.assertTrue(r1 != r2)
- self.assertFalse(r1 == r2)
- self.assertFalse(r1 != 1)
- # can't use assertRaises here...
- try:
- r1 < r2
- self.fail("operation that should have raised an error unexpectedly succeeded")
- except Exception as err:
- self.assertEqual(TypeError, type(err))
- try:
- r1 <= r2
- self.fail("operation that should have raised an error unexpectedly succeeded")
- except Exception as err:
- self.assertEqual(TypeError, type(err))
- try:
- r1 > r2
- self.fail("operation that should have raised an error unexpectedly succeeded")
- except Exception as err:
- self.assertEqual(TypeError, type(err))
- try:
- r1 >= r2
- self.fail("operation that should have raised an error unexpectedly succeeded")
- except Exception as err:
- self.assertEqual(TypeError, type(err))
class SectionTest(unittest.TestCase):
@@ -320,6 +163,7 @@
self.assertRaises(InvalidMessageOperation,
self.p.set_rcode, rcode)
+ self.assertRaises(InvalidMessageOperation, self.p.get_rcode)
def test_set_opcode(self):
self.assertRaises(TypeError, self.r.set_opcode, "wrong")
@@ -331,11 +175,13 @@
self.assertRaises(InvalidMessageOperation,
self.p.set_opcode, opcode)
+ self.assertRaises(InvalidMessageOperation, self.p.get_opcode)
+
def test_get_edns(self):
self.assertEqual(None, self.p.get_edns())
message_parse = Message(Message.PARSE)
- factoryFromFile(message_parse, "message_fromWire10")
+ factoryFromFile(message_parse, "message_fromWire10.wire")
edns = message_parse.get_edns()
self.assertEqual(0, edns.get_version())
self.assertEqual(4096, edns.get_udp_size())
@@ -413,6 +259,16 @@
self.assertEqual(b'\x105\x85\x00\x00\x01\x00\x02\x00\x00\x00\x00\x04test\x07example\x03com\x00\x00\x01\x00\x01\xc0\x0c\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x04\xc0\x00\x02\x01\xc0\x0c\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x04\xc0\x00\x02\x02',
renderer.get_data())
+ def test_to_wire_without_opcode(self):
+ self.r.set_rcode(Rcode.NOERROR())
+ self.assertRaises(InvalidMessageOperation, self.r.to_wire,
+ MessageRenderer())
+
+ def test_to_wire_without_rcode(self):
+ self.r.set_opcode(Opcode.QUERY())
+ self.assertRaises(InvalidMessageOperation, self.r.to_wire,
+ MessageRenderer())
+
def test_to_text(self):
message_render = create_message()
@@ -429,6 +285,14 @@
"""
self.assertEqual(msg_str, message_render.to_text())
self.assertEqual(msg_str, str(message_render))
+
+ def test_to_text_without_opcode(self):
+ self.r.set_rcode(Rcode.NOERROR())
+ self.assertRaises(InvalidMessageOperation, self.r.to_text)
+
+ def test_to_text_without_rcode(self):
+ self.r.set_opcode(Opcode.QUERY())
+ self.assertRaises(InvalidMessageOperation, self.r.to_text)
def test_from_wire(self):
self.assertRaises(TypeError, self.r.from_wire, 1)
@@ -473,12 +337,12 @@
def test_EDNS0ExtCode(self):
# Extended Rcode = BADVERS
message_parse = Message(Message.PARSE)
- factoryFromFile(message_parse, "message_fromWire10")
+ factoryFromFile(message_parse, "message_fromWire10.wire")
self.assertEqual(Rcode.BADVERS(), message_parse.get_rcode())
# Maximum extended Rcode
message_parse.clear(Message.PARSE)
- factoryFromFile(message_parse, "message_fromWire11")
+ factoryFromFile(message_parse, "message_fromWire11.wire")
self.assertEqual(0xfff, message_parse.get_rcode().get_code())
def test_BadEDNS0(self):
Modified: branches/trac191-rebased/src/lib/dns/python/tests/messagerenderer_python_test.py
==============================================================================
--- branches/trac191-rebased/src/lib/dns/python/tests/messagerenderer_python_test.py (original)
+++ branches/trac191-rebased/src/lib/dns/python/tests/messagerenderer_python_test.py Fri Oct 15 05:19:19 2010
@@ -32,6 +32,7 @@
message = Message(Message.RENDER)
message.set_qid(123)
message.set_opcode(Opcode.QUERY())
+ message.set_rcode(Rcode.NOERROR())
message.add_question(Question(name, c, t))
self.message1 = message
Modified: branches/trac191-rebased/src/lib/dns/rdata/template.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/rdata/template.cc (original)
+++ branches/trac191-rebased/src/lib/dns/rdata/template.cc Fri Oct 15 05:19:19 2010
@@ -34,36 +34,29 @@
// If you added member functions specific to this derived class, you'll need
// to implement them here, of course.
-MyType::MyType(const string& type_str)
-{
+MyType::MyType(const string& type_str) {
}
-MyType::MyType(InputBuffer& buffer, size_t rdata_len)
-{
+MyType::MyType(InputBuffer& buffer, size_t rdata_len) {
}
-MyType::MyType(const MyType& source)
-{
+MyType::MyType(const MyType& source) {
}
std::string
-MyType::toText() const
-{
+MyType::toText() const {
}
void
-MyType::toWire(OutputBuffer& buffer) const
-{
+MyType::toWire(OutputBuffer& buffer) const {
}
void
-MyType::toWire(MessageRenderer& renderer) const
-{
+MyType::toWire(MessageRenderer& renderer) const {
}
int
-MyType::compare(const Rdata& other) const
-{
+MyType::compare(const Rdata& other) const {
// The compare method normally begins with this dynamic cast.
const MyType& other_mytype = dynamic_cast<const MyType&>(other);
// ...
Modified: branches/trac191-rebased/src/lib/dns/tests/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/lib/dns/tests/Makefile.am (original)
+++ branches/trac191-rebased/src/lib/dns/tests/Makefile.am Fri Oct 15 05:19:19 2010
@@ -3,7 +3,7 @@
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
AM_CPPFLAGS += -DTEST_DATA_SRCDIR=\"$(srcdir)/testdata\"
-AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(top_builddir)/src/lib/dns/tests/testdata\"
+AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/lib/dns/tests/testdata\"
AM_CXXFLAGS = $(B10_CXXFLAGS)
if USE_STATIC_LINK
@@ -22,6 +22,8 @@
run_unittests_SOURCES += rrclass_unittest.cc rrtype_unittest.cc
run_unittests_SOURCES += rrttl_unittest.cc
run_unittests_SOURCES += dnssectime_unittest.cc
+run_unittests_SOURCES += opcode_unittest.cc
+run_unittests_SOURCES += rcode_unittest.cc
run_unittests_SOURCES += rdata_unittest.h rdata_unittest.cc
run_unittests_SOURCES += rdata_in_a_unittest.cc rdata_in_aaaa_unittest.cc
run_unittests_SOURCES += rdata_ns_unittest.cc rdata_soa_unittest.cc
@@ -53,101 +55,3 @@
endif
noinst_PROGRAMS = $(TESTS)
-
-# NOTE: keep this in sync with real file listing
-# so is included in tarball
-EXTRA_DIST = testdata/gen-wiredata.py.in
-EXTRA_DIST += testdata/edns_toWire1.spec testdata/edns_toWire2.spec
-EXTRA_DIST += testdata/edns_toWire3.spec testdata/edns_toWire4.spec
-EXTRA_DIST += testdata/message_fromWire1
-EXTRA_DIST += testdata/message_fromWire10
-EXTRA_DIST += testdata/message_fromWire10.spec
-EXTRA_DIST += testdata/message_fromWire11
-EXTRA_DIST += testdata/message_fromWire11.spec
-EXTRA_DIST += testdata/message_fromWire2
-EXTRA_DIST += testdata/message_fromWire3
-EXTRA_DIST += testdata/message_fromWire4
-EXTRA_DIST += testdata/message_fromWire5
-EXTRA_DIST += testdata/message_fromWire6
-EXTRA_DIST += testdata/message_fromWire7
-EXTRA_DIST += testdata/message_fromWire8
-EXTRA_DIST += testdata/message_fromWire9
-EXTRA_DIST += testdata/message_toWire1
-EXTRA_DIST += testdata/name_fromWire1
-EXTRA_DIST += testdata/name_fromWire10
-EXTRA_DIST += testdata/name_fromWire11
-EXTRA_DIST += testdata/name_fromWire12
-EXTRA_DIST += testdata/name_fromWire13
-EXTRA_DIST += testdata/name_fromWire14
-EXTRA_DIST += testdata/name_fromWire2
-EXTRA_DIST += testdata/name_fromWire3_1
-EXTRA_DIST += testdata/name_fromWire3_2
-EXTRA_DIST += testdata/name_fromWire4
-EXTRA_DIST += testdata/name_fromWire6
-EXTRA_DIST += testdata/name_fromWire7
-EXTRA_DIST += testdata/name_fromWire8
-EXTRA_DIST += testdata/name_fromWire9
-EXTRA_DIST += testdata/name_toWire1
-EXTRA_DIST += testdata/name_toWire2
-EXTRA_DIST += testdata/name_toWire3
-EXTRA_DIST += testdata/name_toWire4
-EXTRA_DIST += testdata/name_toWire5
-EXTRA_DIST += testdata/name_toWire5.spec
-EXTRA_DIST += testdata/name_toWire6
-EXTRA_DIST += testdata/name_toWire6.spec
-EXTRA_DIST += testdata/question_fromWire
-EXTRA_DIST += testdata/question_toWire1
-EXTRA_DIST += testdata/question_toWire2
-EXTRA_DIST += testdata/rdata_cname_fromWire
-EXTRA_DIST += testdata/rdata_dname_fromWire
-EXTRA_DIST += testdata/rdata_dnskey_fromWire
-EXTRA_DIST += testdata/rdata_ds_fromWire
-EXTRA_DIST += testdata/rdata_in_a_fromWire
-EXTRA_DIST += testdata/rdata_in_aaaa_fromWire
-EXTRA_DIST += testdata/rdata_mx_fromWire
-EXTRA_DIST += testdata/rdata_mx_toWire1
-EXTRA_DIST += testdata/rdata_ns_fromWire
-EXTRA_DIST += testdata/rdata_nsec3_fromWire1
-EXTRA_DIST += testdata/rdata_nsec3_fromWire2
-EXTRA_DIST += testdata/rdata_nsec3_fromWire3
-EXTRA_DIST += testdata/rdata_nsec3param_fromWire1
-EXTRA_DIST += testdata/rdata_nsec_fromWire1
-EXTRA_DIST += testdata/rdata_nsec_fromWire10
-EXTRA_DIST += testdata/rdata_nsec_fromWire10.spec
-EXTRA_DIST += testdata/rdata_nsec_fromWire2
-EXTRA_DIST += testdata/rdata_nsec_fromWire3
-EXTRA_DIST += testdata/rdata_nsec_fromWire4
-EXTRA_DIST += testdata/rdata_nsec_fromWire4.spec
-EXTRA_DIST += testdata/rdata_nsec_fromWire5
-EXTRA_DIST += testdata/rdata_nsec_fromWire5.spec
-EXTRA_DIST += testdata/rdata_nsec_fromWire6
-EXTRA_DIST += testdata/rdata_nsec_fromWire6.spec
-EXTRA_DIST += testdata/rdata_nsec_fromWire7
-EXTRA_DIST += testdata/rdata_nsec_fromWire7.spec
-EXTRA_DIST += testdata/rdata_nsec_fromWire8
-EXTRA_DIST += testdata/rdata_nsec_fromWire8.spec
-EXTRA_DIST += testdata/rdata_nsec_fromWire9
-EXTRA_DIST += testdata/rdata_nsec_fromWire9.spec
-EXTRA_DIST += testdata/rdata_opt_fromWire
-EXTRA_DIST += testdata/rdata_rrsig_fromWire1
-EXTRA_DIST += testdata/rdata_rrsig_fromWire2
-EXTRA_DIST += testdata/rdata_rrsig_fromWire2.spec
-EXTRA_DIST += testdata/rdata_soa_fromWire
-EXTRA_DIST += testdata/rdata_soa_toWireUncompressed
-EXTRA_DIST += testdata/rdata_soa_toWireUncompressed.spec
-EXTRA_DIST += testdata/rdata_txt_fromWire1
-EXTRA_DIST += testdata/rdata_txt_fromWire2
-EXTRA_DIST += testdata/rdata_txt_fromWire2.spec
-EXTRA_DIST += testdata/rdata_txt_fromWire3
-EXTRA_DIST += testdata/rdata_txt_fromWire3.spec
-EXTRA_DIST += testdata/rdata_txt_fromWire4
-EXTRA_DIST += testdata/rdata_txt_fromWire4.spec
-EXTRA_DIST += testdata/rdata_txt_fromWire5
-EXTRA_DIST += testdata/rdata_txt_fromWire5.spec
-EXTRA_DIST += testdata/rdata_unknown_fromWire
-EXTRA_DIST += testdata/rrcode16_fromWire1
-EXTRA_DIST += testdata/rrcode16_fromWire2
-EXTRA_DIST += testdata/rrcode32_fromWire1
-EXTRA_DIST += testdata/rrcode32_fromWire2
-EXTRA_DIST += testdata/rrset_toWire1
-EXTRA_DIST += testdata/rrset_toWire2
Modified: branches/trac191-rebased/src/lib/dns/tests/edns_unittest.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/tests/edns_unittest.cc (original)
+++ branches/trac191-rebased/src/lib/dns/tests/edns_unittest.cc Fri Oct 15 05:19:19 2010
@@ -24,6 +24,7 @@
#include <dns/message.h>
#include <dns/messagerenderer.h>
#include <dns/name.h>
+#include <dns/rcode.h>
#include <dns/rdataclass.h>
#include <dns/rrclass.h>
#include <dns/rrttl.h>
Modified: branches/trac191-rebased/src/lib/dns/tests/message_unittest.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/tests/message_unittest.cc (original)
+++ branches/trac191-rebased/src/lib/dns/tests/message_unittest.cc Fri Oct 15 05:19:19 2010
@@ -22,6 +22,8 @@
#include <dns/message.h>
#include <dns/messagerenderer.h>
#include <dns/question.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <dns/rdataclass.h>
#include <dns/rrclass.h>
#include <dns/rrttl.h>
@@ -77,27 +79,10 @@
message.fromWire(buffer);
}
-TEST_F(MessageTest, RcodeConstruct) {
- // normal cases
- EXPECT_EQ(0, Rcode(0).getCode());
- EXPECT_EQ(0xfff, Rcode(0xfff).getCode()); // possible max code
-
- // should fail on attempt of construction with an out of range code
- EXPECT_THROW(Rcode(0x1000), isc::OutOfRange);
- EXPECT_THROW(Rcode(0xffff), isc::OutOfRange);
-}
-
-TEST_F(MessageTest, RcodeToText) {
- EXPECT_EQ("NOERROR", Rcode::NOERROR().toText());
- EXPECT_EQ("BADVERS", Rcode::BADVERS().toText());
- EXPECT_EQ("17", Rcode(Rcode::BADVERS().getCode() + 1).toText());
- EXPECT_EQ("4095", Rcode(Rcode(0xfff)).toText());
-}
-
TEST_F(MessageTest, getEDNS) {
EXPECT_FALSE(message_parse.getEDNS()); // by default EDNS isn't set
- factoryFromFile(message_parse, "message_fromWire10");
+ factoryFromFile(message_parse, "message_fromWire10.wire");
EXPECT_TRUE(message_parse.getEDNS());
EXPECT_EQ(0, message_parse.getEDNS()->getVersion());
EXPECT_EQ(4096, message_parse.getEDNS()->getUDPSize());
@@ -149,12 +134,12 @@
TEST_F(MessageTest, EDNS0ExtRcode) {
// Extended Rcode = BADVERS
- factoryFromFile(message_parse, "message_fromWire10");
+ factoryFromFile(message_parse, "message_fromWire10.wire");
EXPECT_EQ(Rcode::BADVERS(), message_parse.getRcode());
// Maximum extended Rcode
message_parse.clear(Message::PARSE);
- factoryFromFile(message_parse, "message_fromWire11");
+ factoryFromFile(message_parse, "message_fromWire11.wire");
EXPECT_EQ(0xfff, message_parse.getRcode().getCode());
}
@@ -194,4 +179,29 @@
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, obuffer.getData(),
obuffer.getLength(), &data[0], data.size());
}
-}
+
+TEST_F(MessageTest, toWireInParseMode) {
+ // toWire() isn't allowed in the parse mode.
+ EXPECT_THROW(message_parse.toWire(renderer), InvalidMessageOperation);
+}
+
+TEST_F(MessageTest, toWireWithoutOpcode) {
+ message_render.setRcode(Rcode::NOERROR());
+ EXPECT_THROW(message_render.toWire(renderer), InvalidMessageOperation);
+}
+
+TEST_F(MessageTest, toWireWithoutRcode) {
+ message_render.setOpcode(Opcode::QUERY());
+ EXPECT_THROW(message_render.toWire(renderer), InvalidMessageOperation);
+}
+
+TEST_F(MessageTest, toTextWithoutOpcode) {
+ message_render.setRcode(Rcode::NOERROR());
+ EXPECT_THROW(message_render.toText(), InvalidMessageOperation);
+}
+
+TEST_F(MessageTest, toTextWithoutRcode) {
+ message_render.setOpcode(Opcode::QUERY());
+ EXPECT_THROW(message_render.toText(), InvalidMessageOperation);
+}
+}
Modified: branches/trac191-rebased/src/lib/dns/tests/messagerenderer_unittest.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/tests/messagerenderer_unittest.cc (original)
+++ branches/trac191-rebased/src/lib/dns/tests/messagerenderer_unittest.cc Fri Oct 15 05:19:19 2010
@@ -130,7 +130,7 @@
// name compression in case sensitive manner. See the data file
// description for details.
renderer.setCompressMode(MessageRenderer::CASE_SENSITIVE);
- UnitTestUtil::readWireData("name_toWire5", data);
+ UnitTestUtil::readWireData("name_toWire5.wire", data);
renderer.writeName(Name("a.example.com."));
renderer.writeName(Name("b.eXample.com."));
renderer.writeName(Name("c.eXample.com."));
@@ -140,7 +140,7 @@
TEST_F(MessageRendererTest, writeNameMixedCaseCompress) {
renderer.setCompressMode(MessageRenderer::CASE_SENSITIVE);
- UnitTestUtil::readWireData("name_toWire6", data);
+ UnitTestUtil::readWireData("name_toWire6.wire", data);
renderer.writeName(Name("a.example.com."));
renderer.writeName(Name("b.eXample.com."));
Modified: branches/trac191-rebased/src/lib/dns/tests/rdata_nsec_unittest.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/tests/rdata_nsec_unittest.cc (original)
+++ branches/trac191-rebased/src/lib/dns/tests/rdata_nsec_unittest.cc Fri Oct 15 05:19:19 2010
@@ -70,39 +70,39 @@
// A malformed NSEC bitmap length field that could cause overflow.
EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
- "rdata_nsec_fromWire4"),
+ "rdata_nsec_fromWire4.wire"),
DNSMessageFORMERR);
// The bitmap field is incomplete (only the first byte is included)
EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
- "rdata_nsec_fromWire5"),
+ "rdata_nsec_fromWire5.wire"),
DNSMessageFORMERR);
// Bitmap length is 0, which is invalid.
EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
- "rdata_nsec_fromWire6"),
+ "rdata_nsec_fromWire6.wire"),
DNSMessageFORMERR);
// A boundary case: longest possible bitmaps (32 maps). This should be
// accepted.
EXPECT_NO_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
- "rdata_nsec_fromWire7"));
+ "rdata_nsec_fromWire7.wire"));
// Another boundary condition: 33 bitmaps, which should be rejected.
EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
- "rdata_nsec_fromWire8"),
+ "rdata_nsec_fromWire8.wire"),
DNSMessageFORMERR);
// Disordered bitmap window blocks.
EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
- "rdata_nsec_fromWire9"),
+ "rdata_nsec_fromWire9.wire"),
DNSMessageFORMERR);
// Bitmap ending with all-zero bytes. Not necessarily harmful except
// the additional overhead of parsing, but invalid according to the
// spec anyway.
EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
- "rdata_nsec_fromWire10"),
+ "rdata_nsec_fromWire10.wire"),
DNSMessageFORMERR);
}
Modified: branches/trac191-rebased/src/lib/dns/tests/rdata_rrsig_unittest.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/tests/rdata_rrsig_unittest.cc (original)
+++ branches/trac191-rebased/src/lib/dns/tests/rdata_rrsig_unittest.cc Fri Oct 15 05:19:19 2010
@@ -131,7 +131,7 @@
// RDLEN is too short
EXPECT_THROW(rdataFactoryFromFile(RRType::RRSIG(), RRClass::IN(),
- "rdata_rrsig_fromWire2"),
+ "rdata_rrsig_fromWire2.wire"),
InvalidRdataLength);
}
}
Modified: branches/trac191-rebased/src/lib/dns/tests/rdata_soa_unittest.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/tests/rdata_soa_unittest.cc (original)
+++ branches/trac191-rebased/src/lib/dns/tests/rdata_soa_unittest.cc Fri Oct 15 05:19:19 2010
@@ -65,7 +65,7 @@
obuffer.skip(2);
rdata_soa.toWire(obuffer);
vector<unsigned char> data;
- UnitTestUtil::readWireData("rdata_soa_toWireUncompressed", data);
+ UnitTestUtil::readWireData("rdata_soa_toWireUncompressed.wire", data);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
static_cast<const uint8_t *>(obuffer.getData()) + 2,
obuffer.getLength() - 2, &data[2], data.size() - 2);
Modified: branches/trac191-rebased/src/lib/dns/tests/rdata_txt_unittest.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/tests/rdata_txt_unittest.cc (original)
+++ branches/trac191-rebased/src/lib/dns/tests/rdata_txt_unittest.cc Fri Oct 15 05:19:19 2010
@@ -109,12 +109,12 @@
// Empty character string
EXPECT_EQ(0, rdata_txt_empty.compare(
*rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
- "rdata_txt_fromWire2")));
+ "rdata_txt_fromWire2.wire")));
// Multiple character strings
obuffer.clear();
rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
- "rdata_txt_fromWire3")->toWire(obuffer);
+ "rdata_txt_fromWire3.wire")->toWire(obuffer);
// the result should be 'wiredata_txt' repeated twice
vector<uint8_t> expected_data(wiredata_txt, wiredata_txt +
sizeof(wiredata_txt));
@@ -145,12 +145,12 @@
// RDATA is empty, which is invalid for TXT.
EXPECT_THROW(rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
- "rdata_txt_fromWire4"),
+ "rdata_txt_fromWire4.wire"),
DNSMessageFORMERR);
// character-string length is too large, which could cause overrun.
EXPECT_THROW(rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
- "rdata_txt_fromWire5"),
+ "rdata_txt_fromWire5.wire"),
DNSMessageFORMERR);
}
Modified: branches/trac191-rebased/src/lib/dns/tests/testdata/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/lib/dns/tests/testdata/Makefile.am (original)
+++ branches/trac191-rebased/src/lib/dns/tests/testdata/Makefile.am Fri Oct 15 05:19:19 2010
@@ -2,6 +2,55 @@
BUILT_SOURCES = edns_toWire1.wire edns_toWire2.wire edns_toWire3.wire
BUILT_SOURCES += edns_toWire4.wire
+BUILT_SOURCES += message_fromWire10.wire message_fromWire11.wire
+BUILT_SOURCES += name_toWire5.wire name_toWire6.wire
+BUILT_SOURCES += rdata_nsec_fromWire4.wire rdata_nsec_fromWire5.wire
+BUILT_SOURCES += rdata_nsec_fromWire6.wire rdata_nsec_fromWire7.wire
+BUILT_SOURCES += rdata_nsec_fromWire8.wire rdata_nsec_fromWire9.wire
+BUILT_SOURCES += rdata_nsec_fromWire10.wire
+BUILT_SOURCES += rdata_rrsig_fromWire2.wire
+BUILT_SOURCES += rdata_soa_toWireUncompressed.wire
+BUILT_SOURCES += rdata_txt_fromWire2.wire rdata_txt_fromWire3.wire
+BUILT_SOURCES += rdata_txt_fromWire4.wire rdata_txt_fromWire5.wire
+
+# NOTE: keep this in sync with real file listing
+# so is included in tarball
+EXTRA_DIST = gen-wiredata.py.in
+EXTRA_DIST += edns_toWire1.spec edns_toWire2.spec
+EXTRA_DIST += edns_toWire3.spec edns_toWire4.spec
+EXTRA_DIST += message_fromWire1 message_fromWire2
+EXTRA_DIST += message_fromWire3 message_fromWire4
+EXTRA_DIST += message_fromWire5 message_fromWire6
+EXTRA_DIST += message_fromWire7 message_fromWire8
+EXTRA_DIST += message_fromWire9 message_fromWire10.spec
+EXTRA_DIST += message_fromWire11.spec
+EXTRA_DIST += message_toWire1
+EXTRA_DIST += name_fromWire1 name_fromWire2 name_fromWire3_1 name_fromWire3_2
+EXTRA_DIST += name_fromWire4 name_fromWire6 name_fromWire7 name_fromWire8
+EXTRA_DIST += name_fromWire9 name_fromWire10 name_fromWire11 name_fromWire12
+EXTRA_DIST += name_fromWire13 name_fromWire14
+EXTRA_DIST += name_toWire1 name_toWire2 name_toWire3 name_toWire4
+EXTRA_DIST += name_toWire5.spec name_toWire6.spec
+EXTRA_DIST += question_fromWire question_toWire1 question_toWire2
+EXTRA_DIST += rdata_cname_fromWire rdata_dname_fromWire rdata_dnskey_fromWire
+EXTRA_DIST += rdata_ds_fromWire rdata_in_a_fromWire rdata_in_aaaa_fromWire
+EXTRA_DIST += rdata_mx_fromWire rdata_mx_toWire1 rdata_ns_fromWire
+EXTRA_DIST += rdata_nsec3_fromWire1 rdata_nsec3_fromWire2 rdata_nsec3_fromWire3
+EXTRA_DIST += rdata_nsec3param_fromWire1 rdata_nsec_fromWire1
+EXTRA_DIST += rdata_nsec_fromWire2 rdata_nsec_fromWire3
+EXTRA_DIST += rdata_nsec_fromWire4.spec rdata_nsec_fromWire5.spec
+EXTRA_DIST += rdata_nsec_fromWire6.spec rdata_nsec_fromWire7.spec
+EXTRA_DIST += rdata_nsec_fromWire8.spec rdata_nsec_fromWire9.spec
+EXTRA_DIST += rdata_nsec_fromWire10.spec
+EXTRA_DIST += rdata_opt_fromWire rdata_rrsig_fromWire1
+EXTRA_DIST += rdata_rrsig_fromWire2.spec
+EXTRA_DIST += rdata_soa_fromWire rdata_soa_toWireUncompressed.spec
+EXTRA_DIST += rdata_txt_fromWire1 rdata_txt_fromWire2.spec
+EXTRA_DIST += rdata_txt_fromWire3.spec rdata_txt_fromWire4.spec
+EXTRA_DIST += rdata_txt_fromWire5.spec rdata_unknown_fromWire
+EXTRA_DIST += rrcode16_fromWire1 rrcode16_fromWire2
+EXTRA_DIST += rrcode32_fromWire1 rrcode32_fromWire2
+EXTRA_DIST += rrset_toWire1 rrset_toWire2
.spec.wire:
./gen-wiredata.py -o $@ $<
Modified: branches/trac191-rebased/src/lib/dns/tests/testdata/gen-wiredata.py.in
==============================================================================
--- branches/trac191-rebased/src/lib/dns/tests/testdata/gen-wiredata.py.in (original)
+++ branches/trac191-rebased/src/lib/dns/tests/testdata/gen-wiredata.py.in Fri Oct 15 05:19:19 2010
@@ -19,9 +19,9 @@
from datetime import datetime
from optparse import OptionParser
-re_hex = re.compile('0x[0-9a-fA-F]+')
-re_decimal = re.compile('\d+$')
-re_string = re.compile("\'(.*)\'$")
+re_hex = re.compile(r'0x[0-9a-fA-F]+')
+re_decimal = re.compile(r'\d+$')
+re_string = re.compile(r"\'(.*)\'$")
dnssec_timefmt = '%Y%m%d%H%M%S'
@@ -365,9 +365,6 @@
parser.add_option('-o', '--output', action='store', dest='output',
default=None, metavar='FILE',
help='output file name [default: prefix of input_file]')
- parser.add_option('-m', '--mode', action='store', dest='mode',
- default='message', metavar='[message|custom]',
- help='specify dump mode [default: %default]')
(options, args) = parser.parse_args()
if len(args) == 0:
@@ -389,9 +386,10 @@
print_header(output, configfile)
- if options.mode == 'custom':
+ # First try the 'custom' mode; if it fails assume the standard mode.
+ try:
sections = config.get('custom', 'sections').split(':')
- else:
+ except configparser.NoSectionError:
sections = ['header', 'question', 'edns']
for s in sections:
Modified: branches/trac191-rebased/src/lib/python/isc/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/lib/python/isc/Makefile.am (original)
+++ branches/trac191-rebased/src/lib/python/isc/Makefile.am Fri Oct 15 05:19:19 2010
@@ -1,4 +1,4 @@
-SUBDIRS = datasrc cc config log notify # Util
+SUBDIRS = datasrc cc config log notify utils # Util
python_PYTHON = __init__.py
Modified: branches/trac191-rebased/src/lib/python/isc/config/ccsession.py
==============================================================================
--- branches/trac191-rebased/src/lib/python/isc/config/ccsession.py (original)
+++ branches/trac191-rebased/src/lib/python/isc/config/ccsession.py Fri Oct 15 05:19:19 2010
@@ -1,4 +1,5 @@
# Copyright (C) 2009 Internet Systems Consortium.
+# Copyright (C) 2010 CZ NIC
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -169,20 +170,30 @@
time-critical, it is strongly recommended to only use
check_command(), and not look at the socket at all."""
return self._session._socket
-
+
def close(self):
"""Close the session to the command channel"""
self._session.close()
- def check_command(self):
+ def check_command(self, nonblock=True):
"""Check whether there is a command or configuration update
on the channel. Call the corresponding callback function if
- there is. This function does a non-blocking read on the
- cc session, and returns nothing. It will respond to any
- command by either an error or the answer message returned
- by the callback, unless the latter is None."""
- msg, env = self._session.group_recvmsg(True)
-
+ there is. This function does a read on the cc session, and
+ returns nothing. It will respond to any command by either
+ an error or the answer message returned by the callback,
+ unless the latter is None.
+
+ If nonblock is True, it just checks if there's a command
+ and does nothing if there isn't. If nonblock is False, it
+ waits until it arrives. It temporarily sets timeout to infinity,
+ because commands may not come in arbitrary long time."""
+ timeout_orig = self._session.get_timeout()
+ self._session.set_timeout(0)
+ try:
+ msg, env = self._session.group_recvmsg(nonblock)
+ finally:
+ self._session.set_timeout(timeout_orig)
+
# should we default to an answer? success-by-default? unhandled error?
if msg is not None and not 'result' in msg:
answer = None
Modified: branches/trac191-rebased/src/lib/python/isc/config/tests/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/lib/python/isc/config/tests/Makefile.am (original)
+++ branches/trac191-rebased/src/lib/python/isc/config/tests/Makefile.am Fri Oct 15 05:19:19 2010
@@ -10,7 +10,7 @@
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python \
- CONFIG_TESTDATA_PATH=$(abs_top_srcdir)/src/lib/config/testdata \
- CONFIG_WR_TESTDATA_PATH=$(abs_top_builddir)/src/lib/config/testdata \
+ CONFIG_TESTDATA_PATH=$(abs_top_srcdir)/src/lib/config/tests/testdata \
+ CONFIG_WR_TESTDATA_PATH=$(abs_top_builddir)/src/lib/config/tests/testdata \
$(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
done
Modified: branches/trac191-rebased/src/lib/python/isc/config/tests/ccsession_test.py
==============================================================================
--- branches/trac191-rebased/src/lib/python/isc/config/tests/ccsession_test.py (original)
+++ branches/trac191-rebased/src/lib/python/isc/config/tests/ccsession_test.py Fri Oct 15 05:19:19 2010
@@ -23,7 +23,7 @@
import os
from isc.config.ccsession import *
from isc.config.config_data import BIND10_CONFIG_DATA_VERSION
-from unittest_fakesession import FakeModuleCCSession
+from unittest_fakesession import FakeModuleCCSession, WouldBlockForever
class TestHelperFunctions(unittest.TestCase):
def test_parse_answer(self):
@@ -125,6 +125,8 @@
self.assertTrue("Spec1" in fake_session.subscriptions)
self.assertEqual(len(fake_session.message_queue), 0)
+ fake_session.group_sendmsg(None, 'Spec1')
+ fake_session.group_sendmsg(None, 'Spec1')
self.assertRaises(ModuleCCSessionError, mccs.start)
self.assertEqual(len(fake_session.message_queue), 2)
self.assertEqual({'command': ['module_spec', {'module_name': 'Spec1'}]},
@@ -150,6 +152,8 @@
fake_session = FakeModuleCCSession()
mccs = self.create_session("spec2.spec", None, None, fake_session)
self.assertEqual(len(fake_session.message_queue), 0)
+ fake_session.group_sendmsg(None, 'Spec2')
+ fake_session.group_sendmsg(None, 'Spec2')
self.assertRaises(ModuleCCSessionError, mccs.start)
self.assertEqual(len(fake_session.message_queue), 2)
self.assertEqual({'command': ['module_spec', mccs.specification._module_spec]},
@@ -173,6 +177,8 @@
mccs = self.create_session("spec2.spec", None, None, fake_session)
mccs.set_config_handler(self.my_config_handler_ok)
self.assertEqual(len(fake_session.message_queue), 0)
+ fake_session.group_sendmsg(None, 'Spec2')
+ fake_session.group_sendmsg(None, 'Spec2')
self.assertRaises(ModuleCCSessionError, mccs.start)
self.assertEqual(len(fake_session.message_queue), 2)
self.assertEqual({'command': ['module_spec', mccs.specification._module_spec]},
@@ -196,6 +202,8 @@
mccs = self.create_session("spec2.spec", None, None, fake_session)
mccs.set_config_handler(self.my_config_handler_ok)
self.assertEqual(len(fake_session.message_queue), 0)
+ fake_session.group_sendmsg(None, 'Spec2')
+ fake_session.group_sendmsg(None, 'Spec2')
self.assertRaises(ModuleCCSessionError, mccs.start)
self.assertEqual(len(fake_session.message_queue), 2)
self.assertEqual({'command': ['module_spec', mccs.specification._module_spec]},
@@ -327,30 +335,67 @@
self.assertEqual(len(fake_session.message_queue), 1)
self.assertEqual({'result': [2, 'Spec2 has no command handler']},
fake_session.get_message('Spec2', None))
-
- def test_check_command7(self):
- fake_session = FakeModuleCCSession()
- mccs = self.create_session("spec2.spec", None, None, fake_session)
- mccs.set_command_handler(self.my_command_handler_ok)
+
+ """Many check_command tests look too similar, this is common body."""
+ def common_check_command_check(self, cmd_handler,
+ cmd_check=lambda mccs, _: mccs.check_command()):
+ fake_session = FakeModuleCCSession()
+ mccs = self.create_session("spec2.spec", None, None, fake_session)
+ mccs.set_command_handler(cmd_handler)
self.assertEqual(len(fake_session.message_queue), 0)
cmd = isc.config.ccsession.create_command("print_message", "just a message")
fake_session.group_sendmsg(cmd, 'Spec2')
self.assertEqual(len(fake_session.message_queue), 1)
- mccs.check_command()
+ cmd_check(mccs, fake_session)
+ return fake_session
+
+ def test_check_command7(self):
+ fake_session = self.common_check_command_check(
+ self.my_command_handler_ok)
self.assertEqual(len(fake_session.message_queue), 1)
self.assertEqual({'result': [0]},
fake_session.get_message('Spec2', None))
-
+
def test_check_command8(self):
- fake_session = FakeModuleCCSession()
- mccs = self.create_session("spec2.spec", None, None, fake_session)
- mccs.set_command_handler(self.my_command_handler_no_answer)
- self.assertEqual(len(fake_session.message_queue), 0)
- cmd = isc.config.ccsession.create_command("print_message", "just a message")
- fake_session.group_sendmsg(cmd, 'Spec2')
- self.assertEqual(len(fake_session.message_queue), 1)
- mccs.check_command()
- self.assertEqual(len(fake_session.message_queue), 0)
+ fake_session = self.common_check_command_check(
+ self.my_command_handler_no_answer)
+ self.assertEqual(len(fake_session.message_queue), 0)
+
+ def test_check_command_block(self):
+ """See if the message gets there even in blocking mode."""
+ fake_session = self.common_check_command_check(
+ self.my_command_handler_ok,
+ lambda mccs, _: mccs.check_command(False))
+ self.assertEqual(len(fake_session.message_queue), 1)
+ self.assertEqual({'result': [0]},
+ fake_session.get_message('Spec2', None))
+
+ def test_check_command_block_timeout(self):
+ """Check it works if session has timeout and it sets it back."""
+ def cmd_check(mccs, session):
+ session.set_timeout(1)
+ mccs.check_command(False)
+ fake_session = self.common_check_command_check(
+ self.my_command_handler_ok, cmd_check)
+ self.assertEqual(len(fake_session.message_queue), 1)
+ self.assertEqual({'result': [0]},
+ fake_session.get_message('Spec2', None))
+ self.assertEqual(fake_session.get_timeout(), 1)
+
+ def test_check_command_blocks_forever(self):
+ """Check it would wait forever checking a command."""
+ fake_session = FakeModuleCCSession()
+ mccs = self.create_session("spec2.spec", None, None, fake_session)
+ mccs.set_command_handler(self.my_command_handler_ok)
+ self.assertRaises(WouldBlockForever, lambda: mccs.check_command(False))
+
+ def test_check_command_blocks_forever_timeout(self):
+ """Like above, but it should wait forever even with timeout here."""
+ fake_session = FakeModuleCCSession()
+ fake_session.set_timeout(1)
+ mccs = self.create_session("spec2.spec", None, None, fake_session)
+ mccs.set_command_handler(self.my_command_handler_ok)
+ self.assertRaises(WouldBlockForever, lambda: mccs.check_command(False))
def test_remote_module(self):
fake_session = FakeModuleCCSession()
@@ -360,6 +405,7 @@
self.assertRaises(ModuleCCSessionError, mccs.get_remote_config_value, "Spec2", "item1")
self.assertFalse("Spec2" in fake_session.subscriptions)
+ fake_session.group_sendmsg(None, 'Spec2')
rmodname = mccs.add_remote_config(self.spec_file("spec2.spec"))
self.assertTrue("Spec2" in fake_session.subscriptions)
self.assertEqual("Spec2", rmodname)
@@ -373,6 +419,7 @@
self.assertRaises(ModuleCCSessionError, mccs.get_remote_config_value, "Spec2", "item1")
# test if unsubscription is alse sent when object is deleted
+ fake_session.group_sendmsg({'result' : [0]}, 'Spec2')
rmodname = mccs.add_remote_config(self.spec_file("spec2.spec"))
self.assertTrue("Spec2" in fake_session.subscriptions)
mccs = None
@@ -383,6 +430,7 @@
fake_session = FakeModuleCCSession()
mccs = self.create_session("spec1.spec", None, None, fake_session)
mccs.set_command_handler(self.my_command_handler_ok)
+ fake_session.group_sendmsg(None, 'Spec2')
rmodname = mccs.add_remote_config(self.spec_file("spec2.spec"))
# remove the 'get config' from the queue
Modified: branches/trac191-rebased/src/lib/python/isc/config/tests/cfgmgr_test.py
==============================================================================
--- branches/trac191-rebased/src/lib/python/isc/config/tests/cfgmgr_test.py (original)
+++ branches/trac191-rebased/src/lib/python/isc/config/tests/cfgmgr_test.py Fri Oct 15 05:19:19 2010
@@ -255,6 +255,7 @@
self.fake_session.get_message(self.name, None))
self.assertEqual(len(self.fake_session.message_queue), 0)
+ self.fake_session.group_sendmsg(None, 'ConfigManager')
self._handle_msg_helper({ "command": [ "set_config", [ ] ] },
{'result': [1, 'Wrong number of arguments']} )
self._handle_msg_helper({ "command": [ "set_config", [ self.name, { "test": 125 }] ] },
Modified: branches/trac191-rebased/src/lib/python/isc/config/tests/unittest_fakesession.py
==============================================================================
--- branches/trac191-rebased/src/lib/python/isc/config/tests/unittest_fakesession.py (original)
+++ branches/trac191-rebased/src/lib/python/isc/config/tests/unittest_fakesession.py Fri Oct 15 05:19:19 2010
@@ -16,6 +16,13 @@
# $Id$
import isc
+
+class WouldBlockForever(Exception):
+ """
+ This is thrown by the FakeModuleCCSession if it would need
+ to block forever for incoming message.
+ """
+ pass
#
# We can probably use a more general version of this
@@ -64,13 +71,18 @@
if 'group' in env:
self.message_queue.append([ env['group'], None, msg])
- def group_recvmsg(self, blocking, seq = None):
+ def group_recvmsg(self, nonblock=True, seq = None):
for qm in self.message_queue:
- if qm[0] in self.subscriptions and (qm[1] == None or qm[1] in self.subscriptions[qm[0]]):
+ if qm[0] in self.subscriptions and (qm[1] == None or qm[1] in
+ self.subscriptions[qm[0]]):
self.message_queue.remove(qm)
return qm[2], {'group': qm[0], 'from': qm[1]}
if self._timeout == 0:
- return None, None
+ if nonblock:
+ return None, None
+ else:
+ raise WouldBlockForever(
+ "Blocking read without timeout and no message ready")
else:
raise isc.cc.SessionTimeout("Timeout set but no data to "
"return to group_recvmsg()")
@@ -88,3 +100,6 @@
def set_timeout(self, timeout):
self._timeout = timeout
+
+ def get_timeout(self):
+ return self._timeout
Modified: branches/trac191-rebased/src/lib/python/isc/log/log.py
==============================================================================
--- branches/trac191-rebased/src/lib/python/isc/log/log.py (original)
+++ branches/trac191-rebased/src/lib/python/isc/log/log.py Fri Oct 15 05:19:19 2010
@@ -19,6 +19,7 @@
To use, simply 'import isc.log.log' and log away!
"""
import os
+import sys
import syslog
import logging
import logging.handlers
@@ -31,47 +32,73 @@
'error' : logging.ERROR,
'critical' : logging.CRITICAL}
-
FORMATTER = logging.Formatter("%(name)s: %(levelname)s: %(message)s")
TIME_FORMATTER = logging.Formatter("%(asctime)s.%(msecs)03d %(name)s: %(levelname)s: %(message)s",
"%d-%b-%Y %H:%M:%S")
+def log_err(err_type, err_msg):
+ sys.stderr.write(err_type + ": " + "%s.\n" % str(err_msg)[str(err_msg).find(']')+1:])
+
+
class NSFileLogHandler(logging.handlers.RotatingFileHandler):
"""RotatingFileHandler: replace RotatingFileHandler with a custom handler"""
def __init__(self, filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=0):
- dir = os.path.split(filename)
- if not (os.path.exists(dir[0])):
- os.makedirs(dir[0])
- super(NSFileLogHandler, self).__init__(filename, mode, maxBytes,
+ abs_file_name = self._get_abs_file_path(filename)
+ """Create log directory beforehand, because the underlying logging framework won't
+ create non-exsiting log directory on writing logs.
+ """
+ if not (os.path.exists(os.path.dirname(abs_file_name))):
+ os.makedirs(os.path.dirname(abs_file_name))
+ super(NSFileLogHandler, self).__init__(abs_file_name, mode, maxBytes,
backupCount, encoding, delay)
+
+ def handleError(self, record):
+ """Overwrite handleError to provide more user-friendly error messages"""
+ if logging.raiseExceptions:
+ ei = sys.exc_info()
+ if (ei[1]):
+ sys.stderr.write("[b10-logging] : " + str(ei[1]))
+
+ def _get_abs_file_path(self, file_name):
+ """ Get absolute file path"""
+ # For a bare filename, log_dir will be set the current directory.
+ if not os.path.dirname(file_name):
+ abs_file_dir = os.getcwd()
+ else:
+ abs_file_dir = os.path.abspath(os.path.dirname(file_name))
+ abs_file_name = os.path.join(abs_file_dir, os.path.basename(file_name))
+ return abs_file_name
def shouldRollover(self, record):
"""Rewrite RotatingFileHandler.shouldRollover.
If the log file is deleted at runtime, a new file will be created.
"""
- dfn = self.baseFilename
+ dfn = self.baseFilename
if (self.stream) and (not os.path.exists(dfn)): #Does log file exist?
- self.stream.close()
- dir = os.path.split(dfn)
- if not (os.path.exists(dir[0])): #Does log subdirectory exist?
- os.makedirs(dir[0])
+ self.stream = None
+ """ Log directory may be deleted while bind10 running or updated with a
+ non-existing directory. Need to create log directory beforehand, because
+ the underlying logging framework won't create non-exsiting log directory
+ on writing logs.
+ """
+ if not (os.path.exists(os.path.dirname(dfn))): #Does log subdirectory exist?
+ os.makedirs(os.path.dirname(dfn))
self.stream = self._open()
return super(NSFileLogHandler, self).shouldRollover(record)
def update_config(self, file_name, backup_count, max_bytes):
"""Update RotatingFileHandler configuration.
-
- If the file path does not exist, we will use the old log file.
+ Changes will be picked up in the next call to shouldRollover().
+
input:
log file name
max backup count
predetermined log file size
"""
- dir = os.path.split(file_name)
- if (os.path.exists(dir[0])):
- self.baseFilename = file_name
+ abs_file_name = self._get_abs_file_path(file_name)
+ self.baseFilename = abs_file_name
self.maxBytes = max_bytes
self.backupCount = backup_count
@@ -162,8 +189,9 @@
try:
self._file_handler = NSFileLogHandler(filename = log_file,
maxBytes = max_bytes, backupCount = backup_count)
- except IOError:
+ except (IOError, OSError) as e:
self._file_handler = None
+ log_err("[b10-logging] Add file handler fail", str(e))
return
self._file_handler.setFormatter(TIME_FORMATTER)
self.addHandler(self._file_handler)
@@ -244,6 +272,9 @@
logger.log_message('info', "We have a %s", "mysterious problem").
"""
logLevel = LEVELS.get(level, logging.NOTSET)
- self.log(logLevel, msg, *args, **kwargs)
-
-
+ try:
+ self.log(logLevel, msg, *args, **kwargs)
+ except (TypeError, KeyError) as e:
+ sys.stderr.write("[b10-logging] Log message fail %s\n" % (str(e)))
+
+
Modified: branches/trac191-rebased/src/lib/python/isc/log/tests/log_test.py
==============================================================================
--- branches/trac191-rebased/src/lib/python/isc/log/tests/log_test.py (original)
+++ branches/trac191-rebased/src/lib/python/isc/log/tests/log_test.py Fri Oct 15 05:19:19 2010
@@ -20,6 +20,7 @@
from isc.log.log import *
import unittest
import os
+import sys
import tempfile
@@ -46,21 +47,48 @@
self.handler.shouldRollover(record)
self.assertTrue(os.path.exists(self.FILE_LOG1.name))
+ def test_get_absolute_file_path(self):
+ abs_file_name = self.handler._get_abs_file_path(self.FILE_LOG1.name)
+ self.assertEqual(abs_file_name, self.FILE_LOG1.name)
+ # test bare filename
+ file_name1 = "bind10.py"
+ abs_file_name = self.handler._get_abs_file_path(file_name1)
+ self.assertEqual(abs_file_name, os.path.join(os.getcwd(), file_name1))
+ # test relative path
+ file_name2 = "./bind10.py"
+ abs_file_name = self.handler._get_abs_file_path(file_name2)
+ self.assertEqual(abs_file_name, os.path.join(os.getcwd(), os.path.basename(file_name2)))
+
def test_update_config(self):
self.handler.update_config(self.FILE_LOG2.name, 3, 512)
self.assertEqual(self.handler.baseFilename, self.FILE_LOG2.name)
self.assertEqual(self.handler.maxBytes, 512)
self.assertEqual(self.handler.backupCount, 3)
- dir = os.path.split(self.FILE_LOG3.name)
- path = dir[0] + "path_not_exists"
- update_file = os.path.join(path, dir[1])
-
- if not os.path.exists(path):
- self.handler.update_config(update_file, 4, 1024)
- self.assertEqual(self.handler.baseFilename, self.FILE_LOG2.name)
- self.assertEqual(self.handler.maxBytes, 1024)
- self.assertEqual(self.handler.backupCount, 4)
+ # check the existence of new log file.
+ # emit() will call shouldRollover() to update the log file
+ if(os.path.exists(self.FILE_LOG2.name)):
+ os.remove(self.FILE_LOG2.name)
+ record = logging.LogRecord(None, None, "", 0, "rotate file handler", (), None, None)
+ self.handler.emit(record)
+ self.assertTrue(os.path.exists(self.FILE_LOG2.name))
+
+ def test_handle_Error(self):
+ if(os.path.exists(self.FILE_LOG3.name)):
+ os.remove(self.FILE_LOG3.name)
+ # redirect error message to file
+ savederr = sys.stderr
+ errfd = open(self.FILE_LOG3.name, 'w+')
+ sys.stderr = errfd
+ record = logging.LogRecord(None, None, "", 0, "record message", (), None, None)
+ try:
+ raise ValueError("ValueError")
+ except ValueError:
+ self.handler.handleError(record)
+
+ self.assertEqual("[b10-logging] : ValueError", errfd.read())
+ sys.stderr = savederr
+ errfd.close()
def tearDown(self):
self.handler.flush()
@@ -78,50 +106,46 @@
self.assertEqual(sysLevel, syslog.LOG_ERR)
def test_emit(self):
- record = logging.LogRecord(None, None, "", 0, "syslog handler", (), None, None)
+ syslog_message = "bind10 syslog testing"
+ record = logging.LogRecord(None, None, "", 0, syslog_message, (), None, None)
self.handler.emit(record)
-
class TestLogging(unittest.TestCase):
def setUp(self):
- self.FILE_STREAM_LOG1= tempfile.NamedTemporaryFile(mode='w',
+ self.FILE_STREAM_LOG1 = tempfile.NamedTemporaryFile(mode='w',
prefix="b10",
delete=True)
- self.FILE_STREAM_LOG2= tempfile.NamedTemporaryFile(mode='w',
+ self.FILE_STREAM_LOG2 = tempfile.NamedTemporaryFile(mode='w',
prefix="b10",
delete=True)
- self.FILE_STREAM_LOG3= tempfile.NamedTemporaryFile(mode='w',
+ self.FILE_STREAM_LOG3 = tempfile.NamedTemporaryFile(mode='w',
prefix="b10",
delete=True)
self.file_stream_logger = NSLogger('File_Stream_Logger',
self.FILE_STREAM_LOG1.name,
'debug', 5, 1024, True)
self.syslog_logger = NSLogger('SysLogger', '', 'info', 5, 1024, False)
+ self.stderr_bak = sys.stderr
+ sys.stderr = open(os.devnull, 'w')
def test_logging_init(self):
self.assertNotEqual(self.file_stream_logger._file_handler, None)
self.assertNotEqual(self.file_stream_logger._stream_handler, None)
self.assertEqual(self.file_stream_logger._syslog_handler, None)
- ret = self.file_stream_logger._file_handler in self.file_stream_logger.handlers
- self.assertTrue(ret)
- ret = self.file_stream_logger._stream_handler in self.file_stream_logger.handlers
- self.assertTrue(ret)
- ret = self.file_stream_logger._syslog_handler in self.file_stream_logger.handlers
- self.assertFalse(ret)
+ self.assertIn(self.file_stream_logger._file_handler, self.file_stream_logger.handlers)
+ self.assertIn(self.file_stream_logger._stream_handler, self.file_stream_logger.handlers)
+ self.assertNotIn(self.file_stream_logger._syslog_handler, self.file_stream_logger.handlers)
logLevel = LEVELS.get('debug', logging.NOTSET)
self.assertEqual(self.file_stream_logger.getEffectiveLevel(), logLevel)
self.assertEqual(self.syslog_logger._file_handler, None)
self.assertEqual(self.syslog_logger._stream_handler, None)
self.assertNotEqual(self.syslog_logger._syslog_handler, None)
- ret = self.syslog_logger._file_handler in self.syslog_logger.handlers
- self.assertFalse(ret)
- ret = self.syslog_logger._stream_handler in self.syslog_logger.handlers
- self.assertFalse(ret)
- ret = self.syslog_logger._syslog_handler in self.syslog_logger.handlers
- self.assertTrue(ret)
+ self.assertNotIn(self.syslog_logger._file_handler, self.syslog_logger.handlers)
+ self.assertNotIn(self.syslog_logger._stream_handler, self.syslog_logger.handlers)
+ self.assertIn(self.syslog_logger._syslog_handler, self.syslog_logger.handlers)
logLevel = LEVELS.get('info', logging.NOTSET)
self.assertEqual(self.syslog_logger.getEffectiveLevel(), logLevel)
@@ -131,41 +155,52 @@
self.syslog_logger.removeHandler(self.syslog_logger._file_handler)
self.syslog_logger._add_rotate_handler('', 5, 1024)
- ret = self.syslog_logger._file_handler in self.syslog_logger.handlers
- self.assertFalse(ret)
+ self.assertNotIn(self.syslog_logger._file_handler, self.syslog_logger.handlers)
self.syslog_logger._add_rotate_handler(self.FILE_STREAM_LOG1.name, 5, 1024)
- ret = self.syslog_logger._file_handler in self.syslog_logger.handlers
- self.assertTrue(ret)
+ self.assertIn(self.syslog_logger._file_handler, self.syslog_logger.handlers)
+
+ # test IOError exception
+ self.syslog_logger.removeHandler(self.syslog_logger._file_handler)
+ log_file = self.FILE_STREAM_LOG1.name + '/logfile'
+ self.syslog_logger._add_rotate_handler(log_file, 5, 1024)
+ self.assertNotIn(self.syslog_logger._file_handler, self.syslog_logger.handlers)
def test_add_stream_handler(self):
if(self.file_stream_logger._stream_handler in self.file_stream_logger.handlers):
self.file_stream_logger.removeHandler(self.file_stream_logger._stream_handler)
self.file_stream_logger._add_stream_handler()
- ret = self.file_stream_logger._stream_handler in self.file_stream_logger.handlers
- self.assertTrue(ret)
+ self.assertIn(self.file_stream_logger._stream_handler, self.file_stream_logger.handlers)
def test_add_syslog_handler(self):
if(self.syslog_logger._syslog_handler in self.syslog_logger.handlers):
self.syslog_logger.removeHandler(self.syslog_logger._syslog_handler)
self.syslog_logger._add_syslog_handler()
- ret = self.syslog_logger._syslog_handler in self.syslog_logger.handlers
- self.assertTrue(ret)
+ self.assertIn(self.syslog_logger._syslog_handler, self.syslog_logger.handlers)
def test_update_rotate_handler(self):
self.file_stream_logger._update_rotate_handler(self.FILE_STREAM_LOG2.name, 4, 1024)
- ret = self.file_stream_logger._file_handler in self.file_stream_logger.handlers
- self.assertTrue(ret)
+ self.assertIn(self.file_stream_logger._file_handler, self.file_stream_logger.handlers)
self.file_stream_logger._update_rotate_handler('', 5, 1024)
- ret = self.file_stream_logger._file_handler in self.file_stream_logger.handlers
- self.assertFalse(ret)
+ self.assertNotIn(self.file_stream_logger._file_handler, self.file_stream_logger.handlers)
self.file_stream_logger._update_rotate_handler(self.FILE_STREAM_LOG1.name, 4, 1024)
- ret = self.file_stream_logger._file_handler in self.file_stream_logger.handlers
- self.assertTrue(ret)
+ self.assertIn(self.file_stream_logger._file_handler, self.file_stream_logger.handlers)
+
+ def test_get_config(self):
+ config_data = {'log_file' : self.FILE_STREAM_LOG1.name,
+ 'log_severity' : 'critical',
+ 'log_versions' : 4,
+ 'log_max_bytes' : 1024}
+ self.file_stream_logger._get_config(config_data)
+ self.assertEqual(self.file_stream_logger._log_file, self.FILE_STREAM_LOG1.name)
+ self.assertEqual(self.file_stream_logger._severity, 'critical')
+ self.assertEqual(self.file_stream_logger._versions, 4)
+ self.assertEqual(self.file_stream_logger._max_bytes, 1024)
+
def test_update_config(self):
update_config = {'log_file' : self.FILE_STREAM_LOG1.name,
@@ -183,15 +218,20 @@
'log_max_bytes' : 1024}
self.file_stream_logger.update_config(update_config)
self.file_stream_logger.log_message('debug', 'debug message')
- self.file_stream_logger.log_message('info', 'info message')
self.file_stream_logger.log_message('warning', 'warning message')
self.file_stream_logger.log_message('error', 'error message')
+ #test non-exist log level
+ self.assertRaises(None, self.file_stream_logger.log_message('not-exist', 'not exist message'))
+ #test log_message KeyError exception
+ self.assertRaises(None, self.file_stream_logger.log_message('critical', 'critical message', extra=['message', 'asctime']))
self.assertTrue(os.path.exists(self.FILE_STREAM_LOG3.name))
def tearDown(self):
self.FILE_STREAM_LOG1.close()
self.FILE_STREAM_LOG2.close()
self.FILE_STREAM_LOG3.close()
+ sys.stderr.flush();
+ sys.stderr = self.stderr_bak
if __name__ == '__main__':
unittest.main()
More information about the bind10-changes
mailing list