[svn] commit: r3248 - in /branches/trac292: ./ doc/guide/ src/bin/ src/bin/auth/ src/bin/auth/tests/ 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/usermgr/ src/bin/xfrin/ src/bin/xfrin/tests/ src/bin/xfrout/ src/bin/xfrout/tests/ src/bin/zonemgr/ src/bin/zonemgr/tests/ src/lib/bench/ src/lib/bench/tests/ src/lib/cc/ src/lib/cc/tests/ src/lib/config/ src/lib/config/tests/ 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/rdata/ch_3/ src/lib/dns/rdata/generic/ src/lib/dns/rdata/hs_4/ src/lib/dns/tests/ src/lib/dns/tests/testdata/ src/lib/dns/util/ src/lib/exceptions/ src/lib/exceptions/tests/ src/lib/python/isc/ src/lib/python/isc/cc/ src/lib/python/isc/cc/tests/ 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/notify/ src/lib/xfr/

BIND 10 source code commits bind10-changes at lists.isc.org
Mon Oct 18 10:46:08 UTC 2010


Author: fujiwara
Date: Mon Oct 18 10:46:07 2010
New Revision: 3248

Log:
merged trunk at 3240 changes into this branch

Modified:
    branches/trac292/ChangeLog
    branches/trac292/README
    branches/trac292/configure.ac
    branches/trac292/doc/guide/bind10-guide.html
    branches/trac292/doc/guide/bind10-guide.xml
    branches/trac292/src/bin/Makefile.am
    branches/trac292/src/bin/auth/Makefile.am
    branches/trac292/src/bin/auth/asio_link.cc
    branches/trac292/src/bin/auth/auth_srv.cc
    branches/trac292/src/bin/auth/auth_srv.h
    branches/trac292/src/bin/auth/b10-auth.8
    branches/trac292/src/bin/auth/b10-auth.xml
    branches/trac292/src/bin/auth/tests/Makefile.am
    branches/trac292/src/bin/auth/tests/auth_srv_unittest.cc
    branches/trac292/src/bin/auth/tests/run_unittests.cc
    branches/trac292/src/bin/bind10/Makefile.am
    branches/trac292/src/bin/bind10/bind10.8
    branches/trac292/src/bin/bind10/bind10.py.in
    branches/trac292/src/bin/bind10/bind10.xml
    branches/trac292/src/bin/bind10/run_bind10.sh.in
    branches/trac292/src/bin/bind10/tests/args_test.py
    branches/trac292/src/bin/bind10/tests/bind10_test.py
    branches/trac292/src/bin/bindctl/Makefile.am
    branches/trac292/src/bin/bindctl/bindctl-source.py.in
    branches/trac292/src/bin/cfgmgr/Makefile.am
    branches/trac292/src/bin/cfgmgr/b10-cfgmgr.py.in
    branches/trac292/src/bin/cmdctl/Makefile.am
    branches/trac292/src/bin/cmdctl/cmdctl.py.in
    branches/trac292/src/bin/host/host.cc
    branches/trac292/src/bin/loadzone/Makefile.am
    branches/trac292/src/bin/loadzone/b10-loadzone.py.in
    branches/trac292/src/bin/msgq/Makefile.am
    branches/trac292/src/bin/msgq/msgq.py.in
    branches/trac292/src/bin/usermgr/b10-cmdctl-usermgr.py.in
    branches/trac292/src/bin/xfrin/Makefile.am
    branches/trac292/src/bin/xfrin/TODO
    branches/trac292/src/bin/xfrin/b10-xfrin.8
    branches/trac292/src/bin/xfrin/b10-xfrin.xml
    branches/trac292/src/bin/xfrin/tests/xfrin_test.py
    branches/trac292/src/bin/xfrin/xfrin.py.in
    branches/trac292/src/bin/xfrout/Makefile.am
    branches/trac292/src/bin/xfrout/TODO
    branches/trac292/src/bin/xfrout/b10-xfrout.8
    branches/trac292/src/bin/xfrout/b10-xfrout.xml
    branches/trac292/src/bin/xfrout/tests/xfrout_test.py
    branches/trac292/src/bin/xfrout/xfrout.py.in
    branches/trac292/src/bin/zonemgr/Makefile.am
    branches/trac292/src/bin/zonemgr/TODO
    branches/trac292/src/bin/zonemgr/tests/zonemgr_test.py
    branches/trac292/src/bin/zonemgr/zonemgr.py.in
    branches/trac292/src/bin/zonemgr/zonemgr.spec.pre.in
    branches/trac292/src/lib/bench/benchmark_util.cc
    branches/trac292/src/lib/bench/tests/loadquery_unittest.cc
    branches/trac292/src/lib/cc/data.cc
    branches/trac292/src/lib/cc/tests/Makefile.am
    branches/trac292/src/lib/cc/tests/run_unittests.cc
    branches/trac292/src/lib/config/Makefile.am
    branches/trac292/src/lib/config/ccsession.cc
    branches/trac292/src/lib/config/tests/Makefile.am
    branches/trac292/src/lib/config/tests/ccsession_unittests.cc
    branches/trac292/src/lib/config/tests/data_def_unittests_config.h.in
    branches/trac292/src/lib/config/tests/module_spec_unittests.cc
    branches/trac292/src/lib/config/tests/run_unittests.cc
    branches/trac292/src/lib/datasrc/data_source.cc
    branches/trac292/src/lib/datasrc/static_datasrc.cc
    branches/trac292/src/lib/datasrc/tests/datasrc_unittest.cc
    branches/trac292/src/lib/datasrc/tests/query_unittest.cc
    branches/trac292/src/lib/datasrc/tests/run_unittests.cc
    branches/trac292/src/lib/dns/Makefile.am
    branches/trac292/src/lib/dns/exceptions.cc
    branches/trac292/src/lib/dns/gen-rdatacode.py.in
    branches/trac292/src/lib/dns/message.cc
    branches/trac292/src/lib/dns/message.h
    branches/trac292/src/lib/dns/name.h
    branches/trac292/src/lib/dns/python/Makefile.am
    branches/trac292/src/lib/dns/python/message_python.cc
    branches/trac292/src/lib/dns/python/messagerenderer_python.cc
    branches/trac292/src/lib/dns/python/name_python.cc
    branches/trac292/src/lib/dns/python/pydnspp.cc
    branches/trac292/src/lib/dns/python/question_python.cc
    branches/trac292/src/lib/dns/python/rdata_python.cc
    branches/trac292/src/lib/dns/python/rrclass_python.cc
    branches/trac292/src/lib/dns/python/rrset_python.cc
    branches/trac292/src/lib/dns/python/rrttl_python.cc
    branches/trac292/src/lib/dns/python/rrtype_python.cc
    branches/trac292/src/lib/dns/python/tests/Makefile.am
    branches/trac292/src/lib/dns/python/tests/message_python_test.py
    branches/trac292/src/lib/dns/python/tests/messagerenderer_python_test.py
    branches/trac292/src/lib/dns/python/tests/question_python_test.py
    branches/trac292/src/lib/dns/question.cc
    branches/trac292/src/lib/dns/rdata.cc
    branches/trac292/src/lib/dns/rdata/ch_3/a_1.cc
    branches/trac292/src/lib/dns/rdata/generic/cname_5.cc
    branches/trac292/src/lib/dns/rdata/generic/dname_39.cc
    branches/trac292/src/lib/dns/rdata/generic/dnskey_48.cc
    branches/trac292/src/lib/dns/rdata/generic/ds_43.cc
    branches/trac292/src/lib/dns/rdata/generic/mx_15.cc
    branches/trac292/src/lib/dns/rdata/generic/mx_15.h
    branches/trac292/src/lib/dns/rdata/generic/ns_2.cc
    branches/trac292/src/lib/dns/rdata/generic/nsec3_50.cc
    branches/trac292/src/lib/dns/rdata/generic/nsec3param_51.cc
    branches/trac292/src/lib/dns/rdata/generic/opt_41.cc
    branches/trac292/src/lib/dns/rdata/generic/ptr_12.cc
    branches/trac292/src/lib/dns/rdata/generic/rrsig_46.cc
    branches/trac292/src/lib/dns/rdata/generic/soa_6.cc
    branches/trac292/src/lib/dns/rdata/generic/soa_6.h
    branches/trac292/src/lib/dns/rdata/hs_4/a_1.cc
    branches/trac292/src/lib/dns/rdata/template.cc
    branches/trac292/src/lib/dns/rrclass-placeholder.h
    branches/trac292/src/lib/dns/rrclass.cc
    branches/trac292/src/lib/dns/rrparamregistry-placeholder.cc
    branches/trac292/src/lib/dns/rrset.cc
    branches/trac292/src/lib/dns/rrset.h
    branches/trac292/src/lib/dns/rrsetlist.cc
    branches/trac292/src/lib/dns/rrttl.cc
    branches/trac292/src/lib/dns/rrtype-placeholder.h
    branches/trac292/src/lib/dns/rrtype.cc
    branches/trac292/src/lib/dns/tests/Makefile.am
    branches/trac292/src/lib/dns/tests/buffer_unittest.cc
    branches/trac292/src/lib/dns/tests/message_unittest.cc
    branches/trac292/src/lib/dns/tests/messagerenderer_unittest.cc
    branches/trac292/src/lib/dns/tests/name_unittest.cc
    branches/trac292/src/lib/dns/tests/question_unittest.cc
    branches/trac292/src/lib/dns/tests/rdata_cname_unittest.cc
    branches/trac292/src/lib/dns/tests/rdata_dname_unittest.cc
    branches/trac292/src/lib/dns/tests/rdata_ns_unittest.cc
    branches/trac292/src/lib/dns/tests/rdata_nsec_unittest.cc
    branches/trac292/src/lib/dns/tests/rdata_opt_unittest.cc
    branches/trac292/src/lib/dns/tests/rdata_ptr_unittest.cc
    branches/trac292/src/lib/dns/tests/rdata_rrsig_unittest.cc
    branches/trac292/src/lib/dns/tests/rdata_soa_unittest.cc
    branches/trac292/src/lib/dns/tests/rdata_txt_unittest.cc
    branches/trac292/src/lib/dns/tests/rdata_unittest.cc
    branches/trac292/src/lib/dns/tests/rrclass_unittest.cc
    branches/trac292/src/lib/dns/tests/rrparamregistry_unittest.cc
    branches/trac292/src/lib/dns/tests/rrset_unittest.cc
    branches/trac292/src/lib/dns/tests/rrttl_unittest.cc
    branches/trac292/src/lib/dns/tests/rrtype_unittest.cc
    branches/trac292/src/lib/dns/tests/run_unittests.cc
    branches/trac292/src/lib/dns/tests/testdata/gen-wiredata.py.in
    branches/trac292/src/lib/dns/util/sha1.cc
    branches/trac292/src/lib/exceptions/exceptions.cc
    branches/trac292/src/lib/exceptions/exceptions.h
    branches/trac292/src/lib/exceptions/tests/run_unittests.cc
    branches/trac292/src/lib/python/isc/Makefile.am
    branches/trac292/src/lib/python/isc/cc/Makefile.am
    branches/trac292/src/lib/python/isc/cc/session.py
    branches/trac292/src/lib/python/isc/cc/tests/session_test.py
    branches/trac292/src/lib/python/isc/config/Makefile.am
    branches/trac292/src/lib/python/isc/config/ccsession.py
    branches/trac292/src/lib/python/isc/config/cfgmgr.py
    branches/trac292/src/lib/python/isc/config/module_spec.py
    branches/trac292/src/lib/python/isc/config/tests/Makefile.am
    branches/trac292/src/lib/python/isc/config/tests/ccsession_test.py
    branches/trac292/src/lib/python/isc/config/tests/cfgmgr_test.py
    branches/trac292/src/lib/python/isc/config/tests/unittest_fakesession.py
    branches/trac292/src/lib/python/isc/log/Makefile.am
    branches/trac292/src/lib/python/isc/log/log.py
    branches/trac292/src/lib/python/isc/log/tests/log_test.py
    branches/trac292/src/lib/python/isc/notify/Makefile.am
    branches/trac292/src/lib/xfr/python_xfr.cc
    branches/trac292/src/lib/xfr/xfrout_client.cc

Modified: branches/trac292/ChangeLog
==============================================================================
--- branches/trac292/ChangeLog (original)
+++ branches/trac292/ChangeLog Mon Oct 18 10:46:07 2010
@@ -1,4 +1,94 @@
-  91.	[bug]		jinmei
+  110.  [func]      Michal Vaner
+	Added isc.net.check module to check ip addresses and ports for correctness
+	and isc.net.addr to hold IP address. The bind10, xfrin and cmdctl programs
+	are modified to use it.
+	(Trac #353, svn r3240)
+
+  109.  [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, r3218)
+	Added the document of the stats module, which is about how stats
+	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
+	information more cleanly.  The related APIs are changed a bit,
+	although it won't affect most of higher level applications.
+	(Trac #311, svn r3020)
+
+  98.	[build]		jinmei
+	The ./configure script now tries to search some common include
+	paths for boost header files to minimize the need for explicit
+	configuration with --with-boost-include. (Trac #323, svn r3006)
+
+  97.	[func]		jinmei
+	Added a micro benchmark test for query processing of b10-auth.
+	(Trac #308, svn r2982)
+
+  96.	[bug]		jinmei
+	Fixed two small issues with configure: Do not set CXXFLAGS so that
+	it can be customized; Make sure --disable-static works.
+	(Trac #325, r2976)
+
+bind10-devel-20100917 released on September 17, 2010 
+
+  95.	[doc]		jreed
+	Add b10-zonemgr manual page. Update other docs to introduce
+	this secondary manager. (Trac #341, svn r2951)
+
+  95.	[bug]		jreed
+	bin/xfrout and bin/zonemgr: Fixed some stderr output.
+	(Trac #342, svn r2949)
+
+  94.	[bug]		jelte
+  	bin/xfrout:  Fixed a problem in xfrout where only 2 or 3 RRs
+	were used per DNS message in the xfrout stream.
+	(Trac #334, r2931)
+
+  93.	[bug]		jinmei
 	lib/datasrc: A DS query could crash the library (and therefore,
 	e.g. the authoritative server) if some RR of the same apex name
 	is stored in the hot spot cache.  (Trac #307, svn r2923)
@@ -11,7 +101,7 @@
 
   91.	[func]*		jinmei
 	lib/cc: Use const pointers and const member functions for the API
-	as much as possible for safer operations.  Basically this does
+	as much as possible for safer operations.  Basically this does not
 	change the observable behavior, but some of the API were changed
 	in a backward incompatible manner.  This change also involves more
 	copies, but at this moment the overhead is deemed acceptable.
@@ -40,8 +130,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/trac292/README
==============================================================================
--- branches/trac292/README (original)
+++ branches/trac292/README Mon Oct 18 10:46:07 2010
@@ -17,7 +17,8 @@
 bus, b10-auth authoritative DNS server (with SQLite3 backend),
 b10-cmdctl remote control daemon, b10-cfgmgr configuration manager,
 b10-xfrin AXFR inbound service, b10-xfrout outgoing AXFR service,
-and a new libdns++ library for C++ with a python wrapper.
+b10-zonemgr secondary manager, and a new libdns++ library for C++
+with a python wrapper.
 
 Documentation is included and also available via the BIND 10
 website at http://bind10.isc.org/

Modified: branches/trac292/configure.ac
==============================================================================
--- branches/trac292/configure.ac (original)
+++ branches/trac292/configure.ac Mon Oct 18 10:46:07 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])
@@ -39,6 +39,20 @@
   [build programs with static link [[default=no]]]),
   [enable_static_link=yes], [enable_static_link=no])
 AM_CONDITIONAL(USE_STATIC_LINK, test $enable_static_link = yes)
+
+# Check validity about some libtool options
+if test $enable_static_link = yes -a $enable_static = no; then
+	AC_MSG_ERROR([--enable-static-link requires --enable-static])
+fi
+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
@@ -154,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.
@@ -167,7 +193,6 @@
 # specify the default warning flags in CXXFLAGS and let specific modules
 # "override" the default.
 
-CXXFLAGS=-g
 werror_ok=0
 
 # SunStudio compiler requires special compiler options for boost
@@ -236,7 +261,6 @@
 [  --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
 	# force gtest if not set
@@ -270,14 +294,31 @@
 fi
 AC_SUBST(USE_LCOV)
 
+#
+# Configure Boost header path
+#
+# If explicitly specified, use it.
 AC_ARG_WITH([boost-include],
   AC_HELP_STRING([--with-boost-include=PATH],
     [specify exact directory for Boost headers]),
     [boost_include_path="$withval"])
+# If not specified, try some common paths.
+if test -z "$with_boost_include"; then
+	boostdirs="/usr/local /usr/pkg /opt /opt/local"
+	for d in $boostdirs
+	do
+		if test -f $d/include/boost/shared_ptr.hpp; then
+			boost_include_path=$d/include
+			break
+		fi
+	done
+fi
 if test "${boost_include_path}" ; then
 	BOOST_INCLUDES="-I${boost_include_path}"
 	CPPFLAGS="$CPPFLAGS $BOOST_INCLUDES"
 fi
+AC_CHECK_HEADERS([boost/shared_ptr.hpp boost/foreach.hpp],,
+  AC_MSG_ERROR([Missing required header files.]))
 AC_SUBST(BOOST_INCLUDES)
 
 #
@@ -351,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
@@ -389,12 +433,8 @@
 	CPPFLAGS="$CPPFLAGS -DASIO_DISABLE_DEV_POLL=1"
 fi
 
-# Check for headers from required devel kits.
-AC_CHECK_HEADERS([boost/shared_ptr.hpp boost/foreach.hpp],,
-  AC_MSG_ERROR([Missing required header files.]))
-
 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)
 
@@ -423,13 +463,23 @@
                  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
                  src/bin/xfrout/Makefile
                  src/bin/xfrout/tests/Makefile
                  src/bin/zonemgr/Makefile
                  src/bin/zonemgr/tests/Makefile
+                 src/bin/stats/Makefile
+                 src/bin/stats/tests/Makefile
+                 src/bin/stats/tests/isc/Makefile
+                 src/bin/stats/tests/isc/cc/Makefile
+                 src/bin/stats/tests/isc/config/Makefile
+                 src/bin/stats/tests/isc/utils/Makefile
+                 src/bin/stats/tests/testdata/Makefile
                  src/bin/usermgr/Makefile
+                 src/bin/tests/Makefile
                  src/lib/Makefile
                  src/lib/bench/Makefile
                  src/lib/bench/example/Makefile
@@ -438,6 +488,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
@@ -445,13 +497,16 @@
                  src/lib/python/isc/config/tests/Makefile
                  src/lib/python/isc/log/Makefile
                  src/lib/python/isc/log/tests/Makefile
+                 src/lib/python/isc/net/Makefile
+                 src/lib/python/isc/net/tests/Makefile
                  src/lib/python/isc/notify/Makefile
                  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
                  src/lib/dns/python/Makefile
                  src/lib/dns/python/tests/Makefile
                  src/lib/exceptions/Makefile
@@ -468,7 +523,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
@@ -478,6 +532,12 @@
            src/bin/zonemgr/zonemgr.spec.pre
            src/bin/zonemgr/tests/zonemgr_test
            src/bin/zonemgr/run_b10-zonemgr.sh
+           src/bin/stats/stats.py
+           src/bin/stats/stats_stub.py
+           src/bin/stats/stats.spec.pre
+           src/bin/stats/run_b10-stats.sh
+           src/bin/stats/run_b10-stats_stub.sh
+           src/bin/stats/tests/stats_test
            src/bin/bind10/bind10.py
            src/bin/bind10/tests/bind10_test
            src/bin/bind10/run_bind10.sh
@@ -495,6 +555,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
@@ -510,6 +571,9 @@
            chmod +x src/bin/xfrin/run_b10-xfrin.sh
            chmod +x src/bin/xfrout/run_b10-xfrout.sh
            chmod +x src/bin/zonemgr/run_b10-zonemgr.sh
+           chmod +x src/bin/stats/tests/stats_test
+           chmod +x src/bin/stats/run_b10-stats.sh
+           chmod +x src/bin/stats/run_b10-stats_stub.sh
            chmod +x src/bin/bind10/run_bind10.sh
            chmod +x src/bin/cmdctl/tests/cmdctl_test
            chmod +x src/bin/xfrin/tests/xfrin_test
@@ -543,7 +607,6 @@
 Flags:
   DEFS:          $DEFS
   CPPFLAGS:      $CPPFLAGS
-  CFLAGS:        $CFLAGS
   CXXFLAGS:      $CXXFLAGS
   B10_CXXFLAGS:  $B10_CXXFLAGS
 dnl includes too

Modified: branches/trac292/doc/guide/bind10-guide.html
==============================================================================
--- branches/trac292/doc/guide/bind10-guide.html (original)
+++ branches/trac292/doc/guide/bind10-guide.html Mon Oct 18 10:46:07 2010
@@ -1,8 +1,8 @@
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>BIND 10 Guide</title><link rel="stylesheet" href="bind10-guide.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.75.2"><meta name="description" content="This is the reference guide for BIND 10. The most up-to-date version of this document, along with other documents for BIND 10, can be found at ."></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" title="BIND 10 Guide"><div class="titlepage"><div><div><h1 class="title"><a name="id1168230342594"></a>BIND 10 Guide</h1></div><div><h2 class="subtitle">Administrator Reference for BIND 10</h2></div><div><p class="copyright">Copyright © 2010 Internet Systems Consortium, Inc.</p></div><div><div class="abstract" title="Abstract"><p class="title"><b>Abstract</b></p><p>This is the reference guide for BIND 10.</p><p>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>BIND 10 Guide</title><link rel="stylesheet" href="bind10-guide.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.75.2"><meta name="description" content="This is the reference guide for BIND 10. The most up-to-date version of this document, along with other documents for BIND 10, can be found at ."></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" title="BIND 10 Guide"><div class="titlepage"><div><div><h1 class="title"><a name="id1168230298903"></a>BIND 10 Guide</h1></div><div><h2 class="subtitle">Administrator Reference for BIND 10</h2></div><div><p class="copyright">Copyright © 2010 Internet Systems Consortium, Inc.</p></div><div><div class="abstract" title="Abstract"><p class="title"><b>Abstract</b></p><p>This is the reference guide for BIND 10.</p><p>
         The most up-to-date version of this document, along with other documents
         for BIND 10, can be found at
         <a class="ulink" href="http://bind10.isc.org/docs" target="_top">http://bind10.isc.org/docs</a>.
-      </p></div></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="chapter"><a href="#intro">1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230342718">Supported Platforms</a></span></dt><dt><span class="section"><a href="#id1168230342746">Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">Managing BIND 10</a></span></dt></dl></dd><dt><span class="chapter"><a href="#installation">2. Installation</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230328220">Building Requirements</a></span></dt><dt><span class="section"><a href="#quickstart">Quick start</a></span></dt><dt><span class="section"><a href="#install">Installation from source</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230328406">Download Tar File</a></span></dt><dt><s
 pan class="section"><a href="#id1168230328426">Retrieve from Subversion</a></span></dt><dt><span class="section"><a href="#id1168230328486">Configure before the build</a></span></dt><dt><span class="section"><a href="#id1168230328584">Build</a></span></dt><dt><span class="section"><a href="#id1168230328599">Install</a></span></dt><dt><span class="section"><a href="#id1168230328622">Install Hierarchy</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#bind10">3. Starting BIND10 with <span class="command"><strong>bind10</strong></span></a></span></dt><dd><dl><dt><span class="section"><a href="#start">Starting BIND 10</a></span></dt></dl></dd><dt><span class="chapter"><a href="#msgq">4. Command channel</a></span></dt><dt><span class="chapter"><a href="#cfgmgr">5. Configuration manager</a></span></dt><dt><span class="chapter"><a href="#cmdctl">6. Remote control daemon</a></span></dt><dd><dl><dt><span class="section"><a href="#cmdctl.spec">Configuration specifi
 cation for b10-cmdctl</a></span></dt></dl></dd><dt><span class="chapter"><a href="#bindctl">7. Control and configure user interface</a></span></dt><dt><span class="chapter"><a href="#authserver">8. Authoritative Server</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230329190">Server Configurations</a></span></dt><dt><span class="section"><a href="#id1168230329255">Data Source Backends</a></span></dt><dt><span class="section"><a href="#id1168230329285">Loading Master Zones Files</a></span></dt></dl></dd><dt><span class="chapter"><a href="#xfrin">9. Incoming Zone Transfers</a></span></dt><dt><span class="chapter"><a href="#xfrout">10. Outbound Zone Transfers</a></span></dt></dl></div><div class="chapter" title="Chapter 1. Introduction"><div class="titlepage"><div><div><h2 class="title"><a name="intro"></a>Chapter 1. Introduction</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168230342718">S
 upported Platforms</a></span></dt><dt><span class="section"><a href="#id1168230342746">Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">Managing BIND 10</a></span></dt></dl></div><p>
+      </p></div></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="chapter"><a href="#intro">1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230299028">Supported Platforms</a></span></dt><dt><span class="section"><a href="#id1168230299056">Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">Managing BIND 10</a></span></dt></dl></dd><dt><span class="chapter"><a href="#installation">2. Installation</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230284542">Building Requirements</a></span></dt><dt><span class="section"><a href="#quickstart">Quick start</a></span></dt><dt><span class="section"><a href="#install">Installation from source</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230284728">Download Tar File</a></span></dt><dt><s
 pan class="section"><a href="#id1168230284748">Retrieve from Subversion</a></span></dt><dt><span class="section"><a href="#id1168230284809">Configure before the build</a></span></dt><dt><span class="section"><a href="#id1168230284906">Build</a></span></dt><dt><span class="section"><a href="#id1168230284921">Install</a></span></dt><dt><span class="section"><a href="#id1168230284946">Install Hierarchy</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#bind10">3. Starting BIND10 with <span class="command"><strong>bind10</strong></span></a></span></dt><dd><dl><dt><span class="section"><a href="#start">Starting BIND 10</a></span></dt></dl></dd><dt><span class="chapter"><a href="#msgq">4. Command channel</a></span></dt><dt><span class="chapter"><a href="#cfgmgr">5. Configuration manager</a></span></dt><dt><span class="chapter"><a href="#cmdctl">6. Remote control daemon</a></span></dt><dd><dl><dt><span class="section"><a href="#cmdctl.spec">Configuration specifi
 cation for b10-cmdctl</a></span></dt></dl></dd><dt><span class="chapter"><a href="#bindctl">7. Control and configure user interface</a></span></dt><dt><span class="chapter"><a href="#authserver">8. Authoritative Server</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230285515">Server Configurations</a></span></dt><dt><span class="section"><a href="#id1168230285580">Data Source Backends</a></span></dt><dt><span class="section"><a href="#id1168230285610">Loading Master Zones Files</a></span></dt></dl></dd><dt><span class="chapter"><a href="#xfrin">9. Incoming Zone Transfers</a></span></dt><dt><span class="chapter"><a href="#xfrout">10. Outbound Zone Transfers</a></span></dt><dt><span class="chapter"><a href="#zonemgr">11. Secondary Manager</a></span></dt></dl></div><div class="chapter" title="Chapter 1. Introduction"><div class="titlepage"><div><div><h2 class="title"><a name="intro"></a>Chapter 1. Introduction</h2></div></div></div><div class="toc"><p><b>T
 able of Contents</b></p><dl><dt><span class="section"><a href="#id1168230299028">Supported Platforms</a></span></dt><dt><span class="section"><a href="#id1168230299056">Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">Managing BIND 10</a></span></dt></dl></div><p>
       BIND is the popular implementation of a DNS server, developer
       interfaces, and DNS tools.
       BIND 10 is a rewrite of BIND 9.  BIND 10 is written in C++ and Python
@@ -11,10 +11,10 @@
         This guide covers the experimental prototype version of
         BIND 10.
       </p></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
-        BIND 10, at this time, does not provide an recursive
+        BIND 10, at this time, does not provide a recursive
         DNS server. It does provide a EDNS0- and DNSSEC-capable
         authoritative DNS server.
-      </p></div><div class="section" title="Supported Platforms"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230342718"></a>Supported Platforms</h2></div></div></div><p>
+      </p></div><div class="section" title="Supported Platforms"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230299028"></a>Supported Platforms</h2></div></div></div><p>
   BIND 10 builds have been tested on Debian GNU/Linux 5,
   Ubuntu 9.10, NetBSD 5, Solaris 10, FreeBSD 7, and CentOS
   Linux 5.3.
@@ -24,16 +24,16 @@
 
         It is planned for BIND 10 to build, install and run on
         Windows and standard Unix-type platforms.
-      </p></div><div class="section" title="Required Software"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230342746"></a>Required Software</h2></div></div></div><p>
+      </p></div><div class="section" title="Required Software"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230299056"></a>Required Software</h2></div></div></div><p>
         BIND 10 requires Python 3.1.  Later versions may work, but Python
         3.1 is the minimum version which will work.
       </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
 	For this development prototype release, the only supported
 	data source backend is SQLite3. The authoritative server
 	requires SQLite 3.3.9 or newer.
-        The <span class="command"><strong>b10-xfrin</strong></span> and <span class="command"><strong>b10-xfrout</strong></span>
-        modules require the libpython3 library and the Python
-        _sqlite3.so module.
+	The <span class="command"><strong>b10-xfrin</strong></span>, <span class="command"><strong>b10-xfrout</strong></span>,
+	and <span class="command"><strong>b10-zonemgr</strong></span> modules require the
+	libpython3 library and the Python _sqlite3.so module.
       </p></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
           Some operating systems do not provide these dependencies
           in their default installation nor standard packages
@@ -83,6 +83,11 @@
 	      This process is used to handle transfer requests to
 	      send a local zone to a remote secondary server,
 	      when acting as a master server.
+            </li><li class="listitem">
+              <span class="command"><strong>b10-zonemgr</strong></span> —
+              Secondary manager.
+	      This process keeps track of timers and other
+              necessary information for BIND 10 to act as a slave server.
             </li></ul></div><p>
       </p><p>
 	These are ran automatically by <span class="command"><strong>bind10</strong></span>
@@ -116,7 +121,7 @@
       and, of course, DNS. These include detailed developer
       documentation and code examples.
 
-    </p></div><div class="chapter" title="Chapter 2. Installation"><div class="titlepage"><div><div><h2 class="title"><a name="installation"></a>Chapter 2. Installation</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168230328220">Building Requirements</a></span></dt><dt><span class="section"><a href="#quickstart">Quick start</a></span></dt><dt><span class="section"><a href="#install">Installation from source</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230328406">Download Tar File</a></span></dt><dt><span class="section"><a href="#id1168230328426">Retrieve from Subversion</a></span></dt><dt><span class="section"><a href="#id1168230328486">Configure before the build</a></span></dt><dt><span class="section"><a href="#id1168230328584">Build</a></span></dt><dt><span class="section"><a href="#id1168230328599">Install</a></span></dt><dt><span class="section"><a href="#id1168230328622">Install
  Hierarchy</a></span></dt></dl></dd></dl></div><div class="section" title="Building Requirements"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230328220"></a>Building Requirements</h2></div></div></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+    </p></div><div class="chapter" title="Chapter 2. Installation"><div class="titlepage"><div><div><h2 class="title"><a name="installation"></a>Chapter 2. Installation</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168230284542">Building Requirements</a></span></dt><dt><span class="section"><a href="#quickstart">Quick start</a></span></dt><dt><span class="section"><a href="#install">Installation from source</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230284728">Download Tar File</a></span></dt><dt><span class="section"><a href="#id1168230284748">Retrieve from Subversion</a></span></dt><dt><span class="section"><a href="#id1168230284809">Configure before the build</a></span></dt><dt><span class="section"><a href="#id1168230284906">Build</a></span></dt><dt><span class="section"><a href="#id1168230284921">Install</a></span></dt><dt><span class="section"><a href="#id1168230284946">Install
  Hierarchy</a></span></dt></dl></dd></dl></div><div class="section" title="Building Requirements"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230284542"></a>Building Requirements</h2></div></div></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
             Some operating systems have split their distribution packages into
             a run-time and a development package.  You will need to install
             the development package versions, which include header files and
@@ -176,14 +181,14 @@
         the Subversion code revision control system or as a downloadable
         tar file. It may also be available in pre-compiled ready-to-use
         packages from operating system vendors.
-      </p><div class="section" title="Download Tar File"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230328406"></a>Download Tar File</h3></div></div></div><p>
+      </p><div class="section" title="Download Tar File"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230284728"></a>Download Tar File</h3></div></div></div><p>
           Downloading a release tar file is the recommended method to
           obtain the source code.
         </p><p>
           The BIND 10 releases are available as tar file downloads from
           <a class="ulink" href="ftp://ftp.isc.org/isc/bind10/" target="_top">ftp://ftp.isc.org/isc/bind10/</a>.
           Periodic development snapshots may also be available.
-        </p></div><div class="section" title="Retrieve from Subversion"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230328426"></a>Retrieve from Subversion</h3></div></div></div><p>
+        </p></div><div class="section" title="Retrieve from Subversion"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230284748"></a>Retrieve from Subversion</h3></div></div></div><p>
           Downloading this "bleeding edge" code is recommended only for
           developers or advanced users.  Using development code in a production
           environment is not recommended.
@@ -215,7 +220,7 @@
           <span class="command"><strong>autoheader</strong></span>,
           <span class="command"><strong>automake</strong></span>,
           and related commands.
-        </p></div><div class="section" title="Configure before the build"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230328486"></a>Configure before the build</h3></div></div></div><p>
+        </p></div><div class="section" title="Configure before the build"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230284809"></a>Configure before the build</h3></div></div></div><p>
           BIND 10 uses the GNU Build System to discover build environment
           details.
           To generate the makefiles using the defaults, simply run:
@@ -246,16 +251,16 @@
         </p><p>
           If the configure fails, it may be due to missing or old
           dependencies.
-        </p></div><div class="section" title="Build"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230328584"></a>Build</h3></div></div></div><p>
+        </p></div><div class="section" title="Build"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230284906"></a>Build</h3></div></div></div><p>
     After the configure step is complete, to build the executables
     from the C++ code and prepare the Python scripts, run:
 
           </p><pre class="screen">$ <strong class="userinput"><code>make</code></strong></pre><p>
-        </p></div><div class="section" title="Install"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230328599"></a>Install</h3></div></div></div><p>
+        </p></div><div class="section" title="Install"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230284921"></a>Install</h3></div></div></div><p>
           To install the BIND 10 executables, support files,
           and documentation, run:
           </p><pre class="screen">$ <strong class="userinput"><code>make install</code></strong></pre><p>
-        </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>The install step may require superuser privileges.</p></div></div><div class="section" title="Install Hierarchy"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230328622"></a>Install Hierarchy</h3></div></div></div><p>
+        </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>The install step may require superuser privileges.</p></div></div><div class="section" title="Install Hierarchy"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230284946"></a>Install Hierarchy</h3></div></div></div><p>
           The following is the layout of the complete BIND 10 installation:
           </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
                 <code class="filename">bin/</code> —
@@ -307,8 +312,9 @@
       The <span class="command"><strong>bind10</strong></span> master process will also start up
       <span class="command"><strong>b10-cmdctl</strong></span> for admins to communicate with the
       system, <span class="command"><strong>b10-auth</strong></span> for Authoritative DNS service,
-      <span class="command"><strong>b10-xfrin</strong></span> for inbound DNS zone transfers.
-      and <span class="command"><strong>b10-xfrout</strong></span> for outbound DNS zone transfers.
+      <span class="command"><strong>b10-xfrin</strong></span> for inbound DNS zone transfers,
+      <span class="command"><strong>b10-xfrout</strong></span> for outbound DNS zone transfers,
+      and <span class="command"><strong>b10-zonemgr</strong></span> for secondary service.
     </p><div class="section" title="Starting BIND 10"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="start"></a>Starting BIND 10</h2></div></div></div><p>
         To start the BIND 10 service, simply run <span class="command"><strong>bind10</strong></span>.
         Run it with the <code class="option">--verbose</code> switch to
@@ -467,7 +473,7 @@
       the details and relays (over a <span class="command"><strong>b10-msgq</strong></span> command
       channel) the configuration on to the specified module.
     </p><p>
-    </p></div><div class="chapter" title="Chapter 8. Authoritative Server"><div class="titlepage"><div><div><h2 class="title"><a name="authserver"></a>Chapter 8. Authoritative Server</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168230329190">Server Configurations</a></span></dt><dt><span class="section"><a href="#id1168230329255">Data Source Backends</a></span></dt><dt><span class="section"><a href="#id1168230329285">Loading Master Zones Files</a></span></dt></dl></div><p>
+    </p></div><div class="chapter" title="Chapter 8. Authoritative Server"><div class="titlepage"><div><div><h2 class="title"><a name="authserver"></a>Chapter 8. Authoritative Server</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168230285515">Server Configurations</a></span></dt><dt><span class="section"><a href="#id1168230285580">Data Source Backends</a></span></dt><dt><span class="section"><a href="#id1168230285610">Loading Master Zones Files</a></span></dt></dl></div><p>
       The <span class="command"><strong>b10-auth</strong></span> is the authoritative DNS server.
       It supports EDNS0 and DNSSEC. It supports IPv6.
       Normally it is started by the <span class="command"><strong>bind10</strong></span> master
@@ -475,7 +481,7 @@
     </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
       This development prototype release listens on all interfaces
       and the non-standard port 5300.
-    </p></div><div class="section" title="Server Configurations"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230329190"></a>Server Configurations</h2></div></div></div><p>
+    </p></div><div class="section" title="Server Configurations"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230285515"></a>Server Configurations</h2></div></div></div><p>
         <span class="command"><strong>b10-auth</strong></span> is configured via the
         <span class="command"><strong>b10-cfgmgr</strong></span> configuration manager.
         The module name is <span class="quote">“<span class="quote">Auth</span>”</span>.
@@ -495,7 +501,7 @@
         </p><div class="variablelist"><dl><dt><span class="term">shutdown</span></dt><dd>Stop the authoritative DNS server.
               </dd></dl></div><p>
 
-      </p></div><div class="section" title="Data Source Backends"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230329255"></a>Data Source Backends</h2></div></div></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+      </p></div><div class="section" title="Data Source Backends"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230285580"></a>Data Source Backends</h2></div></div></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
         For the development prototype release, <span class="command"><strong>b10-auth</strong></span>
         only supports the SQLite3 data source backend.
         Upcoming versions will be able to use multiple different
@@ -508,7 +514,7 @@
         The default is <code class="filename">/usr/local/var/</code>.)
   This data file location may be changed by defining the
   <span class="quote">“<span class="quote">database_file</span>”</span> configuration.
-      </p></div><div class="section" title="Loading Master Zones Files"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230329285"></a>Loading Master Zones Files</h2></div></div></div><p>
+      </p></div><div class="section" title="Loading Master Zones Files"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230285610"></a>Loading Master Zones Files</h2></div></div></div><p>
         RFC 1035 style DNS master zone files may imported
         into a BIND 10 data source by using the
         <span class="command"><strong>b10-loadzone</strong></span> utility.
@@ -544,12 +550,12 @@
       transfer. When received, it is stored in the BIND 10
       data store, and its records can be served by
       <span class="command"><strong>b10-auth</strong></span>.
-      This allows the BIND 10 server to provide
-      <span class="quote">“<span class="quote">secondary</span>”</span> service.
+      In combination with <span class="command"><strong>b10-zonemgr</strong></span> (for
+      automated SOA checks), this allows the BIND 10 server to
+      provide <span class="quote">“<span class="quote">secondary</span>”</span> service.
     </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
      The current development release of BIND 10 only supports
      AXFR. (IXFR is not supported.) 
-     It also does not yet support automated SOA checks.
     </p></div><p>
        To manually trigger a zone transfer to retrieve a remote zone,
        you may use the <span class="command"><strong>bindctl</strong></span> utility.
@@ -564,9 +570,24 @@
       sends the zone.
       This is used to provide master DNS service to share zones
       to secondary name servers.
+      The <span class="command"><strong>b10-xfrout</strong></span> is also used to send
+      NOTIFY messages to slaves.
     </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
      The current development release of BIND 10 only supports
      AXFR. (IXFR is not supported.) 
-     It also does not yet support NOTIFY.
      Access control is not yet provided.
+    </p></div></div><div class="chapter" title="Chapter 11. Secondary Manager"><div class="titlepage"><div><div><h2 class="title"><a name="zonemgr"></a>Chapter 11. Secondary Manager</h2></div></div></div><p>
+      The <span class="command"><strong>b10-zonemgr</strong></span> process is started by
+      <span class="command"><strong>bind10</strong></span>.
+      It keeps track of SOA refresh, retry, and expire timers
+      and other details for BIND 10 to perform as a slave.
+      When the <span class="command"><strong>b10-auth</strong></span> authoritative DNS server
+      receives a NOTIFY message, <span class="command"><strong>b10-zonemgr</strong></span>
+      may tell <span class="command"><strong>b10-xfrin</strong></span> to do a refresh
+      to start an inbound zone transfer.
+      The secondary manager resets its counters when a new zone is
+      transferred in.
+    </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+     Access control (such as allowing notifies) is not yet provided.
+     The primary/secondary service is not yet complete.
     </p></div></div></div></body></html>

Modified: branches/trac292/doc/guide/bind10-guide.xml
==============================================================================
--- branches/trac292/doc/guide/bind10-guide.xml (original)
+++ branches/trac292/doc/guide/bind10-guide.xml Mon Oct 18 10:46:07 2010
@@ -42,7 +42,7 @@
 
     <note>
       <para>
-        BIND 10, at this time, does not provide an recursive
+        BIND 10, at this time, does not provide a recursive
         DNS server. It does provide a EDNS0- and DNSSEC-capable
         authoritative DNS server.
       </para>
@@ -74,9 +74,9 @@
 	For this development prototype release, the only supported
 	data source backend is SQLite3. The authoritative server
 	requires SQLite 3.3.9 or newer.
-        The <command>b10-xfrin</command> and <command>b10-xfrout</command>
-        modules require the libpython3 library and the Python
-        _sqlite3.so module.
+	The <command>b10-xfrin</command>, <command>b10-xfrout</command>,
+	and <command>b10-zonemgr</command> modules require the
+	libpython3 library and the Python _sqlite3.so module.
       </para></note>
 <!-- TODO: this will change ... -->
 
@@ -165,6 +165,15 @@
             </simpara>
           </listitem>
 
+          <listitem>
+            <simpara>
+              <command>b10-zonemgr</command> —
+              Secondary manager.
+	      This process keeps track of timers and other
+              necessary information for BIND 10 to act as a slave server.
+            </simpara>
+          </listitem>
+
         </itemizedlist>
       </para>
 
@@ -650,8 +659,9 @@
       The <command>bind10</command> master process will also start up
       <command>b10-cmdctl</command> for admins to communicate with the
       system, <command>b10-auth</command> for Authoritative DNS service,
-      <command>b10-xfrin</command> for inbound DNS zone transfers.
-      and <command>b10-xfrout</command> for outbound DNS zone transfers.
+      <command>b10-xfrin</command> for inbound DNS zone transfers,
+      <command>b10-xfrout</command> for outbound DNS zone transfers,
+      and <command>b10-zonemgr</command> for secondary service.
     </para>
 
     <section id="start">
@@ -1173,14 +1183,14 @@
       transfer. When received, it is stored in the BIND 10
       data store, and its records can be served by
       <command>b10-auth</command>.
-      This allows the BIND 10 server to provide
-      <quote>secondary</quote> service.
+      In combination with <command>b10-zonemgr</command> (for
+      automated SOA checks), this allows the BIND 10 server to
+      provide <quote>secondary</quote> service.
     </para>
 
     <note><simpara>
      The current development release of BIND 10 only supports
      AXFR. (IXFR is not supported.) 
-     It also does not yet support automated SOA checks.
     </simpara></note>
 
     <para>
@@ -1204,12 +1214,13 @@
       sends the zone.
       This is used to provide master DNS service to share zones
       to secondary name servers.
+      The <command>b10-xfrout</command> is also used to send
+      NOTIFY messages to slaves.
     </para>
 
     <note><simpara>
      The current development release of BIND 10 only supports
      AXFR. (IXFR is not supported.) 
-     It also does not yet support NOTIFY.
      Access control is not yet provided.
     </simpara></note>
 
@@ -1226,6 +1237,31 @@
 
   </chapter>
 
+  <chapter id="zonemgr">
+    <title>Secondary Manager</title>
+
+    <para>
+      The <command>b10-zonemgr</command> process is started by
+      <command>bind10</command>.
+      It keeps track of SOA refresh, retry, and expire timers
+      and other details for BIND 10 to perform as a slave.
+      When the <command>b10-auth</command> authoritative DNS server
+      receives a NOTIFY message, <command>b10-zonemgr</command>
+      may tell <command>b10-xfrin</command> to do a refresh
+      to start an inbound zone transfer.
+      The secondary manager resets its counters when a new zone is
+      transferred in.
+    </para>
+
+    <note><simpara>
+     Access control (such as allowing notifies) is not yet provided.
+     The primary/secondary service is not yet complete.
+    </simpara></note>
+
+<!-- TODO: lots to describe for zonemgr -->
+
+  </chapter>
+
 <!-- TODO: how to help: run unit tests, join lists, review trac tickets -->
 
   <!-- <index>    <title>Index</title> </index> -->

Modified: branches/trac292/src/bin/Makefile.am
==============================================================================
--- branches/trac292/src/bin/Makefile.am (original)
+++ branches/trac292/src/bin/Makefile.am Mon Oct 18 10:46:07 2010
@@ -1,1 +1,4 @@
-SUBDIRS = bind10 bindctl cfgmgr loadzone msgq host cmdctl auth xfrin xfrout usermgr zonemgr
+SUBDIRS = bind10 bindctl cfgmgr loadzone msgq host cmdctl auth xfrin xfrout \
+	usermgr zonemgr stats tests
+
+check-recursive: all-recursive

Modified: branches/trac292/src/bin/auth/Makefile.am
==============================================================================
--- branches/trac292/src/bin/auth/Makefile.am (original)
+++ branches/trac292/src/bin/auth/Makefile.am Mon Oct 18 10:46:07 2010
@@ -1,4 +1,4 @@
-SUBDIRS = . tests
+SUBDIRS = . tests benchmarks
 
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin

Modified: branches/trac292/src/bin/auth/asio_link.cc
==============================================================================
--- branches/trac292/src/bin/auth/asio_link.cc (original)
+++ branches/trac292/src/bin/auth/asio_link.cc Mon Oct 18 10:46:07 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 bug 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/trac292/src/bin/auth/auth_srv.cc
==============================================================================
--- branches/trac292/src/bin/auth/auth_srv.cc (original)
+++ branches/trac292/src/bin/auth/auth_srv.cc Mon Oct 18 10:46:07 2010
@@ -24,10 +24,13 @@
 #include <exceptions/exceptions.h>
 
 #include <dns/buffer.h>
+#include <dns/edns.h>
 #include <dns/exceptions.h>
 #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>
@@ -164,7 +167,6 @@
     message.setQid(qid);
     message.setOpcode(opcode);
     message.setHeaderFlag(MessageFlag::QR());
-    message.setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
     if (rd) {
         message.setHeaderFlag(MessageFlag::RD());
     }
@@ -193,6 +195,16 @@
 }
 
 void
+AuthSrv::setCacheSlots(const size_t slots) {
+    impl_->cache_.setSlots(slots);
+}
+
+size_t
+AuthSrv::getCacheSlots() const {
+    return (impl_->cache_.getSlots());
+}
+
+void
 AuthSrv::setXfrinSession(AbstractSession* xfrin_session) {
     impl_->xfrin_session_ = xfrin_session;
 }
@@ -203,7 +215,7 @@
 }
 
 ModuleCCSession*
-AuthSrv::configSession() const {
+AuthSrv::getConfigSession() const {
     return (impl_->config_session_);
 }
 
@@ -292,14 +304,21 @@
 AuthSrvImpl::processNormalQuery(const IOMessage& io_message, Message& message,
                                 MessageRenderer& response_renderer)
 {
-    const bool dnssec_ok = message.isDNSSECSupported();
-    const uint16_t remote_bufsize = message.getUDPSize();
+    ConstEDNSPtr remote_edns = message.getEDNS();
+    const bool dnssec_ok = remote_edns && remote_edns->getDNSSECAwareness();
+    const uint16_t remote_bufsize = remote_edns ? remote_edns->getUDPSize() :
+        Message::DEFAULT_MAX_UDPSIZE; 
 
     message.makeResponse();
     message.setHeaderFlag(MessageFlag::AA());
     message.setRcode(Rcode::NOERROR());
-    message.setDNSSECSupported(dnssec_ok);
-    message.setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
+
+    if (remote_edns) {
+        EDNSPtr local_edns = EDNSPtr(new EDNS());
+        local_edns->setDNSSECAwareness(dnssec_ok);
+        local_edns->setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
+        message.setEDNS(local_edns);
+    }
 
     try {
         Query query(message, cache_, dnssec_ok);

Modified: branches/trac292/src/bin/auth/auth_srv.h
==============================================================================
--- branches/trac292/src/bin/auth/auth_srv.h (original)
+++ branches/trac292/src/bin/auth/auth_srv.h Mon Oct 18 10:46:07 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,12 +89,101 @@
     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.
+    ///
+    /// If the specified size is 0, it means the size will be unlimited.
+    /// The specified size is recorded even if the cache is disabled; the
+    /// new size will be effective when the cache is enabled.
+    ///
+    /// This method never throws an exception.
+    ///
+    /// \param slots The number of cache slots.
+    void setCacheSlots(const size_t slots);
+
+    /// \brief Get the current size (number of slots) of hot spot cache.
+    ///
+    /// It always returns the recorded size regardless of the cache is enabled.
+    ///
+    /// This method never throws an exception.
+    ///
+    /// \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
@@ -85,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/trac292/src/bin/auth/b10-auth.8
==============================================================================
--- branches/trac292/src/bin/auth/b10-auth.8 (original)
+++ branches/trac292/src/bin/auth/b10-auth.8 Mon Oct 18 10:46:07 2010
@@ -137,6 +137,7 @@
 \fBb10-cmdctl\fR(8),
 \fBb10-loadzone\fR(8),
 \fBb10-msgq\fR(8),
+\fBb10-zonemgr\fR(8),
 \fBbind10\fR(8),
 BIND 10 Guide\&.
 .SH "HISTORY"

Modified: branches/trac292/src/bin/auth/b10-auth.xml
==============================================================================
--- branches/trac292/src/bin/auth/b10-auth.xml (original)
+++ branches/trac292/src/bin/auth/b10-auth.xml Mon Oct 18 10:46:07 2010
@@ -201,6 +201,9 @@
         <refentrytitle>b10-msgq</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
       <citerefentry>
+        <refentrytitle>b10-zonemgr</refentrytitle><manvolnum>8</manvolnum>
+      </citerefentry>,
+      <citerefentry>
         <refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
       <citetitle>BIND 10 Guide</citetitle>.

Modified: branches/trac292/src/bin/auth/tests/Makefile.am
==============================================================================
--- branches/trac292/src/bin/auth/tests/Makefile.am (original)
+++ branches/trac292/src/bin/auth/tests/Makefile.am Mon Oct 18 10:46:07 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/trac292/src/bin/auth/tests/auth_srv_unittest.cc
==============================================================================
--- branches/trac292/src/bin/auth/tests/auth_srv_unittest.cc (original)
+++ branches/trac292/src/bin/auth/tests/auth_srv_unittest.cc Mon Oct 18 10:46:07 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,17 +444,24 @@
 
 // Query with unsupported version of EDNS.
 TEST_F(AuthSrvTest, ednsBadVers) {
-    createDataFromFile("queryBadEDNS_fromWire");
-    EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
-                                          response_renderer));
-
-    // The response must have an EDNS OPT RR in the additional section.
+    createDataFromFile("queryBadEDNS_fromWire.wire");
+    EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
+                                          response_renderer));
+
+    // The response must have an EDNS OPT RR in the additional section, but
+    // it will be added automatically at the render time.
     // Note that the DNSSEC DO bit is cleared even if this bit in the query
     // is set.  This is a limitation of the current implementation.
     headerCheck(parse_message, default_qid, Rcode::BADVERS(), opcode.getCode(),
                 QR_FLAG, 1, 0, 0, 1);
-    EXPECT_EQ(4096, parse_message.getUDPSize());
-    EXPECT_FALSE(parse_message.isDNSSECSupported());
+    EXPECT_FALSE(parse_message.getEDNS()); // EDNS isn't added at this point
+
+    parse_message.clear(Message::PARSE);
+    InputBuffer ib(response_renderer.getData(), response_renderer.getLength());
+    parse_message.fromWire(ib);
+    EXPECT_EQ(Rcode::BADVERS(), parse_message.getRcode());
+    EXPECT_TRUE(parse_message.getEDNS());
+    EXPECT_FALSE(parse_message.getEDNS()->getDNSSECAwareness());
 }
 
 TEST_F(AuthSrvTest, AXFROverUDP) {
@@ -577,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);
@@ -715,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(),
@@ -729,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(),
@@ -744,10 +755,20 @@
     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(),
                 QR_FLAG | AA_FLAG, 1, 1, 1, 0);
 }
-}
+
+TEST_F(AuthSrvTest, cacheSlots) {
+    // simple check for the get/set operations
+    server.setCacheSlots(10);    // 10 = arbitrary choice
+    EXPECT_EQ(10, server.getCacheSlots());
+
+    // 0 is a valid size
+    server.setCacheSlots(0);
+    EXPECT_EQ(00, server.getCacheSlots());
+}
+}

Modified: branches/trac292/src/bin/auth/tests/run_unittests.cc
==============================================================================
--- branches/trac292/src/bin/auth/tests/run_unittests.cc (original)
+++ branches/trac292/src/bin/auth/tests/run_unittests.cc Mon Oct 18 10:46:07 2010
@@ -19,10 +19,10 @@
 #include <dns/tests/unittest_util.h>
 
 int
-main(int argc, char* argv[])
-{
+main(int argc, char* argv[]) {
     ::testing::InitGoogleTest(&argc, argv);
     isc::UnitTestUtil::addDataPath(TEST_DATA_DIR);
+    isc::UnitTestUtil::addDataPath(TEST_DATA_BUILDDIR);
 
     return (RUN_ALL_TESTS());
 }

Modified: branches/trac292/src/bin/bind10/Makefile.am
==============================================================================
--- branches/trac292/src/bin/bind10/Makefile.am (original)
+++ branches/trac292/src/bin/bind10/Makefile.am Mon Oct 18 10:46:07 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 sbin_SCRIPTS = bind10
 CLEANFILES = bind10 bind10.pyc

Modified: branches/trac292/src/bin/bind10/bind10.8
==============================================================================
--- branches/trac292/src/bin/bind10/bind10.8 (original)
+++ branches/trac292/src/bin/bind10/bind10.8 Mon Oct 18 10:46:07 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
@@ -101,6 +119,8 @@
 \fBb10-cmdctl\fR(8),
 \fBb10-msgq\fR(8),
 \fBb10-xfrin\fR(8),
+\fBb10-xfrout\fR(8),
+\fBb10-zonemgr\fR(8),
 BIND 10 Guide\&.
 .SH "HISTORY"
 .PP

Modified: branches/trac292/src/bin/bind10/bind10.py.in
==============================================================================
--- branches/trac292/src/bin/bind10/bind10.py.in (original)
+++ branches/trac292/src/bin/bind10/bind10.py.in Mon Oct 18 10:46:07 2010
@@ -63,9 +63,19 @@
 import posix
 
 import isc.cc
+import isc.net.parse
+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.
-__version__ = "v20100531"
+# The VERSION string consists of the module name, the module version
+# number, and the overall BIND 10 version number (set in configure.ac).
+VERSION = "bind10 20100916 (BIND 10 @PACKAGE_VERSION@)"
+
+# This is for bind10.boottime of stats module
+_BASETIME = time.gmtime()
 
 class RestartSchedule:
     """
@@ -174,35 +184,10 @@
     def respawn(self):
         self._spawn()
 
-class IPAddr:
-    """Stores an IPv4 or IPv6 address."""
-    family = None
-    addr = None
-
-    def __init__(self, addr):
-        try:
-            a = socket.inet_pton(socket.AF_INET, addr)
-            self.family = socket.AF_INET
-            self.addr = a
-            return
-        except:
-            pass
-
-        try:
-            a = socket.inet_pton(socket.AF_INET6, addr)
-            self.family = socket.AF_INET6
-            self.addr = a
-            return
-        except Exception as e:
-            raise e
-    
-    def __str__(self):
-        return socket.inet_ntop(self.family, self.addr)
-
 class BoB:
     """Boss of BIND class."""
     
-    def __init__(self, msgq_socket_file=None, auth_port=5300, address='',
+    def __init__(self, msgq_socket_file=None, auth_port=5300, address=None,
                  nocache=False, verbose=False, setuid=None, username=None):
         """Initialize the Boss of BIND. This is a singleton (only one
         can run).
@@ -216,7 +201,7 @@
         self.auth_port = auth_port
         self.address = None
         if address:
-            self.address = IPAddr(address)
+            self.address = address
         self.cc_session = None
         self.ccs = None
         self.processes = {}
@@ -418,6 +403,27 @@
             sys.stdout.write("[bind10] Started b10-zonemgr(PID %d)\n" % 
                              zonemgr.pid)
 
+        # start b10-stats
+        stats_args = ['b10-stats']
+        if self.verbose:
+            sys.stdout.write("[bind10] Starting b10-stats\n")
+            stats_args += ['-v']
+        try:
+            statsd = ProcessInfo("b10-stats", stats_args,
+                                 c_channel_env)
+        except Exception as e:
+            c_channel.process.kill()
+            bind_cfgd.process.kill()
+            xfrout.process.kill()
+            auth.process.kill()
+            xfrind.process.kill()
+            zonemgr.process.kill()
+            return "Unable to start b10-stats; " + str(e)
+
+        self.processes[statsd.pid] = statsd
+        if self.verbose:
+            sys.stdout.write("[bind10] Started b10-stats (PID %d)\n" % statsd.pid)
+
         # start the b10-cmdctl
         # XXX: we hardcode port 8080
         cmdctl_args = ['b10-cmdctl']
@@ -434,6 +440,7 @@
             auth.process.kill()
             xfrind.process.kill()
             zonemgr.process.kill()
+            statsd.process.kill()
             return "Unable to start b10-cmdctl; " + str(e)
         self.processes[cmd_ctrld.pid] = cmd_ctrld
         if self.verbose:
@@ -453,6 +460,7 @@
         self.cc_session.group_sendmsg(cmd, "Boss", "Xfrout")
         self.cc_session.group_sendmsg(cmd, "Boss", "Xfrin")
         self.cc_session.group_sendmsg(cmd, "Boss", "Zonemgr")
+        self.cc_session.group_sendmsg(cmd, "Boss", "Stats")
 
     def stop_process(self, process):
         """Stop the given process, friendly-like."""
@@ -576,7 +584,7 @@
     # the Python signal handler has been set up to write
     # down a pipe, waking up our select() bit
     pass
-                   
+
 def get_signame(signal_number):
     """Return the symbolic name for a signal."""
     for sig in dir(signal):
@@ -598,27 +606,29 @@
 def check_port(option, opt_str, value, parser):
     """Function to insure that the port we are passed is actually 
     a valid port number. Used by OptionParser() on startup."""
-    if not re.match('^(6553[0-5]|655[0-2]\d|65[0-4]\d\d|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3}|0)$', value):
-        raise OptionValueError("%s requires a port number (0-65535)" % opt_str)
-    if (opt_str == '-m' or opt_str == '--msgq-port'):
-        parser.values.msgq_port = value
-    elif (opt_str == '-p' or opt_str == '--port'):
-        parser.values.auth_port = value
-    else:
-        raise OptionValueError("Unknown option " + opt_str)
-  
+    try:
+        if opt_str in ['-p', '--port']:
+            parser.values.auth_port = isc.net.parse.port_parse(value)
+        else:
+            raise OptionValueError("Unknown option " + opt_str)
+    except ValueError as e:
+        raise OptionValueError(str(e))
+
 def check_addr(option, opt_str, value, parser):
     """Function to insure that the address we are passed is actually 
     a valid address. Used by OptionParser() on startup."""
     try:
-        IPAddr(value)
-    except:
+        if opt_str in ['-a', '--address']:
+            parser.values.address = isc.net.parse.addr_parse(value)
+        else:
+            raise OptionValueError("Unknown option " + opt_str)
+    except ValueError:
         raise OptionValueError("%s requires a valid IPv4 or IPv6 address" % opt_str)
-    if (opt_str == '-a' or opt_str == '--address'):
-        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
@@ -627,7 +637,7 @@
 
 
     # Parse any command-line options.
-    parser = OptionParser(version=__version__)
+    parser = OptionParser(version=VERSION)
     parser.add_option("-a", "--address", dest="address", type="string",
                       action="callback", callback=check_addr, default='',
                       help="address the b10-auth daemon will use (default: listen on all addresses)")
@@ -636,14 +646,17 @@
                       help="UNIX domain socket file the b10-msgq daemon will use")
     parser.add_option("-n", "--no-cache", action="store_true", dest="nocache",
                       default=False, help="disable hot-spot cache in b10-auth")
-    parser.add_option("-p", "--port", dest="auth_port", type="string",
-                      action="callback", callback=check_port, default="5300",
+    parser.add_option("-p", "--port", dest="auth_port", type="int",
+                      action="callback", callback=check_port, default=5300,
                       help="port the b10-auth daemon will use (default 5300)")
     parser.add_option("-u", "--user", dest="user",
                       type="string", default=None,
                       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()
@@ -680,7 +693,7 @@
 
     # Announce startup.
     if options.verbose:
-        sys.stdout.write("BIND 10 %s\n" % __version__)
+        sys.stdout.write("%s\n" % VERSION)
 
     # TODO: set process name, perhaps by:
     #       http://code.google.com/p/procname/
@@ -697,8 +710,11 @@
     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),
+    boss_of_bind = BoB(options.msgq_socket_file, options.auth_port,
                        options.address, options.nocache, options.verbose,
                        setuid, username)
     startup_result = boss_of_bind.startup()
@@ -706,6 +722,17 @@
         sys.stderr.write("[bind10] Error on startup: %s\n" % startup_result)
         sys.exit(1)
     sys.stdout.write("[bind10] BIND 10 started\n")
+
+    # send "bind10.boot_time" to b10-stats
+    time.sleep(1) # wait a second
+    if options.verbose:
+        sys.stdout.write("[bind10] send \"bind10.boot_time\" to b10-stats\n")
+    cmd = isc.config.ccsession.create_command('set', 
+            { "stats_data": {
+              'bind10.boot_time': time.strftime('%Y-%m-%dT%H:%M:%SZ', _BASETIME)
+              }
+            })
+    boss_of_bind.cc_session.group_sendmsg(cmd, 'Stats')
 
     # In our main loop, we check for dead processes or messages 
     # on the c-channel.
@@ -735,7 +762,12 @@
 
         for fd in rlist + xlist:
             if fd == ccs_fd:
-                boss_of_bind.ccs.check_command()
+                try:
+                    boss_of_bind.ccs.check_command()
+                except isc.cc.session.ProtocolError:
+                    if options.verbose:
+                        sys.stderr.write("[bind10] msgq channel disappeared.\n")
+                    break
             elif fd == wakeup_fd:
                 os.read(wakeup_fd, 32)
 

Modified: branches/trac292/src/bin/bind10/bind10.xml
==============================================================================
--- branches/trac292/src/bin/bind10/bind10.xml (original)
+++ branches/trac292/src/bin/bind10/bind10.xml Mon Oct 18 10:46:07 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
@@ -188,6 +200,12 @@
       </citerefentry>,
       <citerefentry>
         <refentrytitle>b10-xfrin</refentrytitle><manvolnum>8</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>b10-xfrout</refentrytitle><manvolnum>8</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>b10-zonemgr</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
       <citetitle>BIND 10 Guide</citetitle>.
     </para>

Modified: branches/trac292/src/bin/bind10/run_bind10.sh.in
==============================================================================
--- branches/trac292/src/bin/bind10/run_bind10.sh.in (original)
+++ branches/trac292/src/bin/bind10/run_bind10.sh.in Mon Oct 18 10:46:07 2010
@@ -20,7 +20,7 @@
 
 BIND10_PATH=@abs_top_builddir@/src/bin/bind10
 
-PATH=@abs_top_builddir@/src/bin/msgq:@abs_top_builddir@/src/bin/auth:@abs_top_builddir@/src/bin/cfgmgr:@abs_top_builddir@/src/bin/cmdctl:@abs_top_builddir@/src/bin/xfrin:@abs_top_builddir@/src/bin/xfrout:@abs_top_builddir@/src/bin/zonemgr:$PATH
+PATH=@abs_top_builddir@/src/bin/msgq:@abs_top_builddir@/src/bin/auth:@abs_top_builddir@/src/bin/cfgmgr:@abs_top_builddir@/src/bin/cmdctl:@abs_top_builddir@/src/bin/stats:@abs_top_builddir@/src/bin/xfrin:@abs_top_builddir@/src/bin/xfrout:@abs_top_builddir@/src/bin/zonemgr:$PATH
 export PATH
 
 PYTHONPATH=@abs_top_builddir@/src/lib/python:@abs_top_builddir@/src/lib/dns/python/.libs:@abs_top_builddir@/src/lib/xfr/.libs

Modified: branches/trac292/src/bin/bind10/tests/args_test.py
==============================================================================
--- branches/trac292/src/bin/bind10/tests/args_test.py (original)
+++ branches/trac292/src/bin/bind10/tests/args_test.py Mon Oct 18 10:46:07 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/trac292/src/bin/bind10/tests/bind10_test.py
==============================================================================
--- branches/trac292/src/bin/bind10/tests/bind10_test.py (original)
+++ branches/trac292/src/bin/bind10/tests/bind10_test.py Mon Oct 18 10:46:07 2010
@@ -1,4 +1,4 @@
-from bind10 import ProcessInfo, BoB, IPAddr
+from bind10 import ProcessInfo, BoB
 
 # XXX: environment tests are currently disabled, due to the preprocessor
 #      setup that we have now complicating the environment
@@ -8,6 +8,7 @@
 import os
 import signal
 import socket
+from isc.net.addr import IPAddr
 
 class TestProcessInfo(unittest.TestCase):
     def setUp(self):
@@ -72,28 +73,6 @@
         self.assertTrue(type(pi.pid) is int)
         self.assertNotEqual(pi.pid, old_pid)
 
-class TestIPAddr(unittest.TestCase):
-    def test_v6ok(self):
-        addr = IPAddr('2001:4f8::1')
-        self.assertEqual(addr.family, socket.AF_INET6)
-        self.assertEqual(addr.addr, socket.inet_pton(socket.AF_INET6, '2001:4f8::1'))
-
-    def test_v4ok(self):
-        addr = IPAddr('127.127.127.127')
-        self.assertEqual(addr.family, socket.AF_INET)
-        self.assertEqual(addr.addr, socket.inet_aton('127.127.127.127'))
-
-    def test_badaddr(self):
-        self.assertRaises(socket.error, IPAddr, 'foobar')
-        self.assertRaises(socket.error, IPAddr, 'foo::bar')
-        self.assertRaises(socket.error, IPAddr, '123')
-        self.assertRaises(socket.error, IPAddr, '123.456.789.0')
-        self.assertRaises(socket.error, IPAddr, '127/8')
-        self.assertRaises(socket.error, IPAddr, '0/0')
-        self.assertRaises(socket.error, IPAddr, '1.2.3.4/32')
-        self.assertRaises(socket.error, IPAddr, '0')
-        self.assertRaises(socket.error, IPAddr, '')
-
 class TestBoB(unittest.TestCase):
     def test_init(self):
         bob = BoB()
@@ -127,7 +106,7 @@
         self.assertEqual(bob.runnable, False)
 
     def test_init_alternate_address(self):
-        bob = BoB(None, 5300, '127.127.127.127')
+        bob = BoB(None, 5300, IPAddr('127.127.127.127'))
         self.assertEqual(bob.verbose, False)
         self.assertEqual(bob.auth_port, 5300)
         self.assertEqual(bob.msgq_socket_file, None)

Modified: branches/trac292/src/bin/bindctl/Makefile.am
==============================================================================
--- branches/trac292/src/bin/bindctl/Makefile.am (original)
+++ branches/trac292/src/bin/bindctl/Makefile.am Mon Oct 18 10:46:07 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 bin_SCRIPTS = bindctl
 man_MANS = bindctl.1

Modified: branches/trac292/src/bin/bindctl/bindctl-source.py.in
==============================================================================
--- branches/trac292/src/bin/bindctl/bindctl-source.py.in (original)
+++ branches/trac292/src/bin/bindctl/bindctl-source.py.in Mon Oct 18 10:46:07 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/trac292/src/bin/cfgmgr/Makefile.am
==============================================================================
--- branches/trac292/src/bin/cfgmgr/Makefile.am (original)
+++ branches/trac292/src/bin/cfgmgr/Makefile.am Mon Oct 18 10:46:07 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 pkglibexecdir = $(libexecdir)/@PACKAGE@
 

Modified: branches/trac292/src/bin/cfgmgr/b10-cfgmgr.py.in
==============================================================================
--- branches/trac292/src/bin/cfgmgr/b10-cfgmgr.py.in (original)
+++ branches/trac292/src/bin/cfgmgr/b10-cfgmgr.py.in Mon Oct 18 10:46:07 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/trac292/src/bin/cmdctl/Makefile.am
==============================================================================
--- branches/trac292/src/bin/cmdctl/Makefile.am (original)
+++ branches/trac292/src/bin/cmdctl/Makefile.am Mon Oct 18 10:46:07 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 pkglibexecdir = $(libexecdir)/@PACKAGE@
 
@@ -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/trac292/src/bin/cmdctl/cmdctl.py.in
==============================================================================
--- branches/trac292/src/bin/cmdctl/cmdctl.py.in (original)
+++ branches/trac292/src/bin/cmdctl/cmdctl.py.in Mon Oct 18 10:46:07 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,16 @@
 import time
 import signal
 from isc.config import ccsession
+import isc.net.parse
+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 +325,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:
@@ -380,6 +385,7 @@
     def send_command(self, module_name, command_name, params = None):
         '''Send the command from bindctl to proper module. '''
         errstr = 'unknown error'
+        answer = None
         if self._verbose:
             self.log_info("Begin send command '%s' to module '%s'" %(command_name, module_name))
 
@@ -390,7 +396,10 @@
             msg = ccsession.create_command(command_name, params)
             seq = self._cc.group_sendmsg(msg, module_name)
             #TODO, it may be blocked, msqg need to add a new interface waiting in timeout.
-            answer, env = self._cc.group_recvmsg(False, seq)
+            try:
+                answer, env = self._cc.group_recvmsg(False, seq)
+            except isc.cc.session.SessionTimeout:
+                errstr = "Module '%s' not responding" % module_name
 
         if self._verbose:
             self.log_info("Finish send command '%s' to module '%s'" % (command_name, module_name))
@@ -410,7 +419,6 @@
             except ccsession.ModuleCCSessionError as mcse:
                 errstr = str("Error in ccsession answer:") + str(mcse)
                 self.log_info(errstr)
-        
         return 1, {'error': errstr}
     
     def log_info(self, msg):
@@ -558,22 +566,17 @@
     httpd.serve_forever()
 
 def check_port(option, opt_str, value, parser):
-    if (value < 0) or (value > 65535):
-        raise OptionValueError('%s requires a port number (0-65535)' % opt_str)
-    parser.values.port = value
+    try:
+        parser.values.port = isc.net.parse.port_parse(value)
+    except ValueError as e:
+        raise OptionValueError(str(e))
 
 def check_addr(option, opt_str, value, parser):
-    ipstr = value
-    ip_family = socket.AF_INET
-    if (ipstr.find(':') != -1):
-        ip_family = socket.AF_INET6
-
     try:
-        socket.inet_pton(ip_family, ipstr)
-    except:
-        raise OptionValueError("%s invalid ip address" % ipstr)
-
-    parser.values.addr = value
+        isc.net.parse.addr_parse(value)
+        parser.values.addr = value
+    except ValueError as e:
+        raise OptionValueError(str(e))
 
 def set_cmd_options(parser):
     parser.add_option('-p', '--port', dest = 'port', type = 'int',
@@ -602,6 +605,9 @@
     except isc.cc.SessionError as err:
         sys.stderr.write("[b10-cmdctl] Error creating b10-cmdctl, "
                          "is the command channel daemon running?\n")        
+    except isc.cc.SessionTimeout:
+        sys.stderr.write("[b10-cmdctl] Error creating b10-cmdctl, "
+                         "is the configuration manager running?\n")        
     except KeyboardInterrupt:
         sys.stderr.write("[b10-cmdctl] exit from Cmdctl\n")
     except CmdctlException as err:

Modified: branches/trac292/src/bin/host/host.cc
==============================================================================
--- branches/trac292/src/bin/host/host.cc (original)
+++ branches/trac292/src/bin/host/host.cc Mon Oct 18 10:46:07 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/trac292/src/bin/loadzone/Makefile.am
==============================================================================
--- branches/trac292/src/bin/loadzone/Makefile.am (original)
+++ branches/trac292/src/bin/loadzone/Makefile.am Mon Oct 18 10:46:07 2010
@@ -1,5 +1,4 @@
-SUBDIRS = tests/correct
-SUBDIRS += tests/error
+SUBDIRS = . tests/correct tests/error
 bin_SCRIPTS = b10-loadzone
 
 CLEANFILES = b10-loadzone

Modified: branches/trac292/src/bin/loadzone/b10-loadzone.py.in
==============================================================================
--- branches/trac292/src/bin/loadzone/b10-loadzone.py.in (original)
+++ branches/trac292/src/bin/loadzone/b10-loadzone.py.in Mon Oct 18 10:46:07 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/trac292/src/bin/msgq/Makefile.am
==============================================================================
--- branches/trac292/src/bin/msgq/Makefile.am (original)
+++ branches/trac292/src/bin/msgq/Makefile.am Mon Oct 18 10:46:07 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 pkglibexecdir = $(libexecdir)/@PACKAGE@
  

Modified: branches/trac292/src/bin/msgq/msgq.py.in
==============================================================================
--- branches/trac292/src/bin/msgq/msgq.py.in (original)
+++ branches/trac292/src/bin/msgq/msgq.py.in Mon Oct 18 10:46:07 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/trac292/src/bin/usermgr/b10-cmdctl-usermgr.py.in
==============================================================================
--- branches/trac292/src/bin/usermgr/b10-cmdctl-usermgr.py.in (original)
+++ branches/trac292/src/bin/usermgr/b10-cmdctl-usermgr.py.in Mon Oct 18 10:46:07 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/trac292/src/bin/xfrin/Makefile.am
==============================================================================
--- branches/trac292/src/bin/xfrin/Makefile.am (original)
+++ branches/trac292/src/bin/xfrin/Makefile.am Mon Oct 18 10:46:07 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 pkglibexecdir = $(libexecdir)/@PACKAGE@
 
@@ -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/trac292/src/bin/xfrin/TODO
==============================================================================
--- branches/trac292/src/bin/xfrin/TODO (original)
+++ branches/trac292/src/bin/xfrin/TODO Mon Oct 18 10:46:07 2010
@@ -66,4 +66,5 @@
 17. Do zone transfer from notifyfrom address first, if it's one master of the zone.
 18. Check soa serial first when doing zone refreshment.
 19. Add configuration items to seperate zone, including ACL, multiple masters, etc.
+20. Be able to cancel the ongoing zone transfer, and be able to disable zone transfer.
 

Modified: branches/trac292/src/bin/xfrin/b10-xfrin.8
==============================================================================
--- branches/trac292/src/bin/xfrin/b10-xfrin.8 (original)
+++ branches/trac292/src/bin/xfrin/b10-xfrin.8 Mon Oct 18 10:46:07 2010
@@ -2,12 +2,12 @@
 .\"     Title: b10-xfrin
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: March 17, 2010
+.\"      Date: September 8, 2010
 .\"    Manual: BIND10
 .\"    Source: BIND10
 .\"  Language: English
 .\"
-.TH "B10\-XFRIN" "8" "March 17, 2010" "BIND10" "BIND10"
+.TH "B10\-XFRIN" "8" "September 8, 2010" "BIND10" "BIND10"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
@@ -47,7 +47,6 @@
 .sp .5v
 .RE
 .PP
-
 This daemon communicates with BIND 10 over a
 \fBb10-msgq\fR(8)
 C\-Channel connection\&. If this connection is not established,
@@ -60,24 +59,59 @@
 \fBb10-cfgmgr\fR(8)\&.
 .SH "CONFIGURATION AND COMMANDS"
 .PP
-The configurable setting is
+The configurable settings are:
+.PP
+\fImaster_addr\fR
+The default is 127\&.0\&.0\&.1\&.
+.PP
+\fImaster_port\fR
+The default is 53\&.
+.PP
 \fItransfers\-in\fR
-which defines the maximum number of inbound zone transfers that can run concurrently\&. The default is 10\&.
+defines the maximum number of inbound zone transfers that can run concurrently\&. The default is 10\&.
 .PP
 The configuration commands are:
+.PP
+
+\fBnotify\fR
+is sent by
+\fBb10-zonemgr\fR(8)
+when a DNS NOTIFY message is received to initiate a zone transfer\&.
+This is an internal command and not exposed to the administrator\&.
+.PP
+
+\fBrefresh\fR
+triggers the transfer in for a single zone\&. It is the same as
+\fBretransfer\fR
+except it checks the SOA serial first\&.
+This is an internal command and not exposed to the administrator\&.
+
+.PP
+
+\fBrefresh_from_zonemgr\fR
+is sent by
+\fBb10-zonemgr\fR(8)
+according to the SOA\'s REFRESH time to tell
+\fBb10\-xfrin\fR
+that the zone needs to do a zone refresh\&. This is an internal command and not exposed to the administrator\&.
+.PP
+
+\fBretransfer\fR
+triggers the transfer in for a single zone without checking the zone\'s serial number\&. It has the following arguments:
+\fIzone_name\fR
+to define the zone to request,
+\fIzone_class\fR
+to define the class (defaults to
+\(lqIN\(rq),
+\fImaster\fR
+to define the IP address of the authoritative server to transfer from, and
+\fIport\fR
+to define the port number on the authoritative server (defaults to 53)\&.
 .PP
 
 \fBshutdown\fR
 stops all incoming zone transfers and exits
 \fBb10\-xfrin\fR\&. (Note that the BIND 10 boss process will restart this service\&.)
-.PP
-
-\fBretransfer\fR
-triggers the transfer in for a single zone without checking the zone\'s serial number\&. It has the following arguments:
-\fIzone_name\fR
-to define the zone to request and
-\fImaster\fR
-to define the IP address of the authoritative server to transfer from\&.
 .if n \{\
 .sp
 .\}
@@ -99,6 +133,7 @@
 
 \fBb10-cfgmgr\fR(8),
 \fBb10-msgq\fR(8),
+\fBb10-zonemgr\fR(8),
 \fBbind10\fR(8),
 BIND 10 Guide\&.
 .SH "HISTORY"

Modified: branches/trac292/src/bin/xfrin/b10-xfrin.xml
==============================================================================
--- branches/trac292/src/bin/xfrin/b10-xfrin.xml (original)
+++ branches/trac292/src/bin/xfrin/b10-xfrin.xml Mon Oct 18 10:46:07 2010
@@ -21,7 +21,7 @@
 <refentry>
 
   <refentryinfo>
-    <date>March 17, 2010</date>
+    <date>September 8, 2010</date>
   </refentryinfo>
 
   <refmeta>
@@ -68,7 +68,6 @@
     </simpara></note>
 
     <para>
-<!-- TODO: does it really use msgq? what for? -->
       This daemon communicates with BIND 10 over a
       <citerefentry><refentrytitle>b10-msgq</refentrytitle><manvolnum>8</manvolnum></citerefentry>
       C-Channel connection.  If this connection is not established,
@@ -85,39 +84,82 @@
   <refsect1>
     <title>CONFIGURATION AND COMMANDS</title>
     <para>
-      The configurable setting is <varname>transfers-in</varname>
-      which defines the maximum number of inbound zone transfers
+      The configurable settings are:
+    </para>
+
+    <para><varname>master_addr</varname>
+<!-- TODO: how can there be a single setting for this? -->
+       The default is 127.0.0.1.
+    </para>
+
+    <para><varname>master_port</varname>
+<!-- TODO: what if custom is needed per zone? -->
+      The default is 53.
+    </para>
+
+    <para><varname>transfers-in</varname>
+      defines the maximum number of inbound zone transfers
       that can run concurrently. The default is 10.
     </para>
 
 <!-- TODO: formating -->
-<!-- TODO: refresh is code but not in spec -->
-<!-- schedule immediate maintenance for a zone(check soa serial ) -->
     <para>
       The configuration commands are:
     </para>
+
+    <para>
+      <command>notify</command> is sent by
+      <citerefentry><refentrytitle>b10-zonemgr</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+      when a DNS NOTIFY message is received to initiate a zone
+      transfer.
+<!-- TODO: document that zonemgr or xfrin checks if it needs to or not -->
+      This is an internal command and not exposed to the administrator.
+<!-- not defined in spec -->
+    </para>
+
+    <para>
+      <command>refresh</command> triggers the transfer in for
+      a single zone.
+      It is the same as <command>retransfer</command> except it
+      checks the SOA serial first.
+<!-- TODO more detail -->
+      This is an internal command and not exposed to the administrator.
+<!-- not defined in spec -->
+<!-- TODO: refresh is code but not in spec, see trac ticket #328 -->
+    </para>
+
+    <para>
+      <command>refresh_from_zonemgr</command> is sent by
+      <citerefentry><refentrytitle>b10-zonemgr</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+      according to the SOA's REFRESH time
+      to tell <command>b10-xfrin</command> that the zone needs to do
+      a zone refresh.
+      This is an internal command and not exposed to the administrator. 
+<!-- not defined in spec -->
+    </para>
+
+    <para>
+      <command>retransfer</command> triggers the transfer in for
+      a single zone without checking the zone's serial number.
+      It has the following arguments: <varname>zone_name</varname>
+      to define the zone to request,
+      <varname>zone_class</varname> to define the class (defaults to
+      <quote>IN</quote>),
+      <varname>master</varname> to define the IP address of
+      the authoritative server to transfer from,
+      and <varname>port</varname> to define the port number on the
+      authoritative server (defaults to 53).
+<!-- TODO: note: not documenting db_file since that will be removed. -->
+     </para>
+<!-- TODO: later hostname for master? -->
+
     <para>
       <command>shutdown</command> stops all incoming zone transfers
       and exits <command>b10-xfrin</command>. (Note that the BIND 10
       boss process will restart this service.)
     </para>
-    <para>
-      <command>retransfer</command> triggers the transfer in for
-      a single zone without checking the zone's serial number.
-      It has the following arguments: <varname>zone_name</varname>
-      to define the zone to request and <varname>master</varname>
-      to define the IP address of the authoritative server to
-      transfer from.
-     </para>
-<!-- TODO: later hostname for master? -->
-
 <!-- TODO:
 add a usage example of xfrin -->
-
-<!-- TODO:
-
-port (defaults to 53)
-db_file (defaults to zone.sqlite3) --> <!-- TODO: fix this -->
 
 <!-- TODO:
 
@@ -182,6 +224,9 @@
         <refentrytitle>b10-msgq</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
       <citerefentry>
+        <refentrytitle>b10-zonemgr</refentrytitle><manvolnum>8</manvolnum>
+      </citerefentry>,
+      <citerefentry>
         <refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
       <citetitle>BIND 10 Guide</citetitle>.

Modified: branches/trac292/src/bin/xfrin/tests/xfrin_test.py
==============================================================================
--- branches/trac292/src/bin/xfrin/tests/xfrin_test.py (original)
+++ branches/trac292/src/bin/xfrin/tests/xfrin_test.py Mon Oct 18 10:46:07 2010
@@ -421,21 +421,21 @@
         name, rrclass = self._do_parse_zone_name_class()
         master_addrinfo = self._do_parse_master_port()
         db_file = self.args.get('db_file')
-        self.assertEqual(master_addrinfo[4][1], int(TEST_MASTER_PORT))
+        self.assertEqual(master_addrinfo[2][1], int(TEST_MASTER_PORT))
         self.assertEqual(name, TEST_ZONE_NAME)
         self.assertEqual(rrclass, TEST_RRCLASS)
-        self.assertEqual(master_addrinfo[4][0], TEST_MASTER_IPV4_ADDRESS)
+        self.assertEqual(master_addrinfo[2][0], TEST_MASTER_IPV4_ADDRESS)
         self.assertEqual(db_file, TEST_DB_FILE)
 
     def test_parse_cmd_params_default_port(self):
         del self.args['port']
         master_addrinfo = self._do_parse_master_port()
-        self.assertEqual(master_addrinfo[4][1], 53)
+        self.assertEqual(master_addrinfo[2][1], 53)
 
     def test_parse_cmd_params_ip6master(self):
         self.args['master'] = TEST_MASTER_IPV6_ADDRESS
         master_addrinfo = self._do_parse_master_port()
-        self.assertEqual(master_addrinfo[4][0], TEST_MASTER_IPV6_ADDRESS)
+        self.assertEqual(master_addrinfo[2][0], TEST_MASTER_IPV6_ADDRESS)
 
     def test_parse_cmd_params_chclass(self):
         self.args['zone_class'] = 'CH'
@@ -454,7 +454,7 @@
         # master address is mandatory.
         del self.args['master']
         master_addrinfo = self._do_parse_master_port()
-        self.assertEqual(master_addrinfo[4][0], DEFAULT_MASTER)
+        self.assertEqual(master_addrinfo[2][0], DEFAULT_MASTER)
 
     def test_parse_cmd_params_bad_ip4(self):
         self.args['master'] = '3.3.3.3.3'

Modified: branches/trac292/src/bin/xfrin/xfrin.py.in
==============================================================================
--- branches/trac292/src/bin/xfrin/xfrin.py.in (original)
+++ branches/trac292/src/bin/xfrin/xfrin.py.in Mon Oct 18 10:46:07 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,16 @@
 from optparse import OptionParser, OptionValueError
 from isc.config.ccsession import *
 from isc.notify import notify_out
+import isc.net.parse
+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
@@ -90,7 +95,7 @@
         self.setblocking(1)
         self._shutdown_event = shutdown_event
         self._verbose = verbose
-        self._master_address = master_addrinfo[4]
+        self._master_address = master_addrinfo[2]
 
     def connect_to_master(self):
         '''Connect to master in TCP.'''
@@ -326,10 +331,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,20 +402,20 @@
         '''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
         if ('master_addr' in new_config) or ('master_port' in new_config):
-            # Check if the new master is valid, there should be library for check it.
-            # and user should change the port and address together.
+            # User should change the port and address together.
             try:
                 addr = new_config.get('master_addr') or self._master_addr
                 port = new_config.get('master_port') or self._master_port
-                check_addr_port(addr, port)
+                isc.net.parse.addr_parse(addr)
+                isc.net.parse.port_parse(port)
                 self._master_addr = addr
                 self._master_port = port
-            except:
+            except ValueError:
                 errmsg = "bad format for zone's master: " + str(new_config)
                 log_error(errmsg)
                 return create_answer(1, errmsg)
@@ -435,7 +444,7 @@
                 # specify the notifyfrom address and port, according the RFC1996, zone
                 # transfer should starts first from the notifyfrom, but now, let 'TODO' it.
                 (zone_name, rrclass) = self._parse_zone_name_and_class(args)
-                (master_addr) = check_addr_port(self._master_addr, self._master_port)
+                (master_addr) = build_addr_info(self._master_addr, self._master_port)
                 ret = self.xfrin_start(zone_name, 
                                        rrclass, 
                                        self._get_db_file(),
@@ -483,7 +492,7 @@
     def _parse_master_and_port(self, args):
         port = args.get('port') or self._master_port
         master = args.get('master') or self._master_addr
-        return check_addr_port(master, port)
+        return build_addr_info(master, port)
  
     def _get_db_file(self):
         #TODO, the db file path should be got in auth server's configuration
@@ -556,30 +565,19 @@
     signal.signal(signal.SIGTERM, signal_handler)
     signal.signal(signal.SIGINT, signal_handler)
 
-def check_addr_port(addrstr, portstr):
-    # XXX: Linux (glibc)'s getaddrinfo incorrectly accepts numeric port
-    # string larger than 65535.  So we need to explicit validate it separately.
+def build_addr_info(addrstr, portstr):
+    """
+    Return tuple (family, socktype, sockaddr) for given address and port.
+    IPv4 and IPv6 are the only supported addresses now, so sockaddr will be
+    (address, port). The socktype is socket.SOCK_STREAM for now.
+    """
     try:
-        portnum = int(portstr)
-        if portnum < 0 or portnum > 65535:
-            raise ValueError("invalid port number (out of range): " + portstr)
+        port = isc.net.parse.port_parse(portstr)
+        addr = isc.net.parse.addr_parse(addrstr)
+        return (addr.family, socket.SOCK_STREAM, (addrstr, port))
     except ValueError as err:
         raise XfrinException("failed to resolve master address/port=%s/%s: %s" %
                              (addrstr, portstr, str(err)))
-
-    try:
-        addrinfo = socket.getaddrinfo(addrstr, portstr, socket.AF_UNSPEC,
-                                      socket.SOCK_STREAM, socket.IPPROTO_TCP,
-                                      socket.AI_NUMERICHOST|
-                                      socket.AI_NUMERICSERV)
-    except socket.gaierror as err:
-        raise XfrinException("failed to resolve master address/port=%s/%s: %s" %
-                             (addrstr, portstr, str(err)))
-    if len(addrinfo) != 1:
-        # with the parameters above the result must be uniquely determined.
-        errmsg = "unexpected result for address/port resolution for %s:%s"
-        raise XfrinException(errmsg % (addrstr, portstr))
-    return addrinfo[0]
 
 def set_cmd_options(parser):
     parser.add_option("-v", "--verbose", dest="verbose", action="store_true",

Modified: branches/trac292/src/bin/xfrout/Makefile.am
==============================================================================
--- branches/trac292/src/bin/xfrout/Makefile.am (original)
+++ branches/trac292/src/bin/xfrout/Makefile.am Mon Oct 18 10:46:07 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 pkglibexecdir = $(libexecdir)/@PACKAGE@
 

Modified: branches/trac292/src/bin/xfrout/TODO
==============================================================================
--- branches/trac292/src/bin/xfrout/TODO (original)
+++ branches/trac292/src/bin/xfrout/TODO Mon Oct 18 10:46:07 2010
@@ -1,1 +1,2 @@
-Add unittest code.
+Add unittest code.
+Be able to cancel the outgoing zone transfer, and also be able to disable outgoing zone transfer.

Modified: branches/trac292/src/bin/xfrout/b10-xfrout.8
==============================================================================
--- branches/trac292/src/bin/xfrout/b10-xfrout.8 (original)
+++ branches/trac292/src/bin/xfrout/b10-xfrout.8 Mon Oct 18 10:46:07 2010
@@ -2,12 +2,12 @@
 .\"     Title: b10-xfrout
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: April 20, 2010
+.\"      Date: September 8, 2010
 .\"    Manual: BIND10
 .\"    Source: BIND10
 .\"  Language: English
 .\"
-.TH "B10\-XFROUT" "8" "April 20, 2010" "BIND10" "BIND10"
+.TH "B10\-XFROUT" "8" "September 8, 2010" "BIND10" "BIND10"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
@@ -27,7 +27,7 @@
 .PP
 The
 \fBb10\-xfrout\fR
-daemon provides the BIND 10 outgoing DNS zone transfer service\&. Normally it is started by the
+daemon provides the BIND 10 outgoing DNS zone transfer service\&. It is also used to send outgoing NOTIFY messages\&. Normally it is started by the
 \fBbind10\fR(8)
 boss process\&. When the
 \fBb10\-auth\fR
@@ -67,13 +67,13 @@
 The configurable settings are:
 .PP
 
-\fItransfers\-out\fR
-defines the maximum number of outgoing zone transfers that can run concurrently\&. The default is 10\&.
-.PP
-
 \fIdb_file\fR
 defines the path to the SQLite3 data store file\&. The default is
 /usr/local/var/bind10\-devel/zone\&.sqlite3\&.
+.PP
+
+\fItransfers_out\fR
+defines the maximum number of outgoing zone transfers that can run concurrently\&. The default is 10\&.
 .if n \{\
 .sp
 .\}
@@ -91,25 +91,34 @@
 .sp .5v
 .RE
 .PP
-The configuration command is:
+The configuration commands are:
 .PP
 
 \fBshutdown\fR
 stops all outbound zone transfers and exits
 \fBb10\-xfrout\fR\&. (Note that the BIND 10 boss process will restart this service\&.)
+.PP
+
+\fBzone_new_data_ready\fR
+is sent from
+\fBb10-xfrin\fR(8)
+to indicate that the zone transferred in successfully\&. This triggers
+\fBb10\-xfrout\fR
+to send NOTIFY message(s)\&. This is an internal command and not exposed to the administrator\&.
 .SH "SEE ALSO"
 .PP
 
 \fBb10-auth\fR(8),
 \fBb10-cfgmgr\fR(8),
 \fBb10-msgq\fR(8),
+\fBb10-xfrin\fR(8),
 \fBbind10\fR(8),
 BIND 10 Guide\&.
 .SH "HISTORY"
 .PP
 The
 \fBb10\-xfrout\fR
-daemon was implemented in March 2010 by Zhang Likun of CNNIC for the ISC BIND 10 project\&.
+daemon was first implemented in March 2010 by Zhang Likun of CNNIC for the ISC BIND 10 project\&.
 .SH "COPYRIGHT"
 .br
 Copyright \(co 2010 Internet Systems Consortium, Inc. ("ISC")

Modified: branches/trac292/src/bin/xfrout/b10-xfrout.xml
==============================================================================
--- branches/trac292/src/bin/xfrout/b10-xfrout.xml (original)
+++ branches/trac292/src/bin/xfrout/b10-xfrout.xml Mon Oct 18 10:46:07 2010
@@ -21,7 +21,7 @@
 <refentry>
 
   <refentryinfo>
-    <date>April 20, 2010</date>
+    <date>September 8, 2010</date>
   </refentryinfo>
 
   <refmeta>
@@ -54,6 +54,7 @@
     <title>DESCRIPTION</title>
     <para>The <command>b10-xfrout</command> daemon provides the BIND 10
       outgoing DNS zone transfer service.
+      It is also used to send outgoing NOTIFY messages.
       Normally it is started by the
       <citerefentry><refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum></citerefentry>
       boss process.
@@ -97,12 +98,16 @@
       defines the path to the SQLite3 data store file.
       The default is
       <filename>/usr/local/var/bind10-devel/zone.sqlite3</filename>.
+<!-- TODO: db_file will be removed -->
     </para>
     <para>
       <varname>transfers_out</varname>
       defines the maximum number of outgoing zone transfers
       that can run concurrently. The default is 10.
     </para>
+
+<!-- TODO: log configurations not documented yet in here. jreed
+     has some but waiting on decisions ... -->
 
     <note><simpara>
       This prototype version uses SQLite3 as its data source backend.
@@ -112,12 +117,22 @@
 
 <!-- TODO: formating -->
     <para>
-      The configuration command is:
+      The configuration commands are:
     </para>
     <para>
       <command>shutdown</command> stops all outbound zone transfers
       and exits <command>b10-xfrout</command>. (Note that the BIND 10
       boss process will restart this service.)
+    </para>
+
+    <para>
+      <command>zone_new_data_ready</command> is sent from
+      <citerefentry><refentrytitle>b10-xfrin</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+      to indicate that the zone transferred in successfully.
+      This triggers <command>b10-xfrout</command> to send NOTIFY
+      message(s).
+      This is an internal command and not exposed to the administrator.
+<!-- not defined in spec -->
     </para>
 
   </refsect1>
@@ -161,6 +176,9 @@
         <refentrytitle>b10-msgq</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
       <citerefentry>
+        <refentrytitle>b10-xfrin</refentrytitle><manvolnum>8</manvolnum>
+      </citerefentry>,
+      <citerefentry>
         <refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
       <citetitle>BIND 10 Guide</citetitle>.
@@ -170,8 +188,8 @@
   <refsect1>
     <title>HISTORY</title>
     <para>
-      The <command>b10-xfrout</command> daemon was implemented in March 2010
-      by Zhang Likun of CNNIC for the ISC BIND 10 project.
+      The <command>b10-xfrout</command> daemon was first implemented
+      in March 2010 by Zhang Likun of CNNIC for the ISC BIND 10 project.
     </para>
   </refsect1>
 </refentry><!--

Modified: branches/trac292/src/bin/xfrout/tests/xfrout_test.py
==============================================================================
--- branches/trac292/src/bin/xfrout/tests/xfrout_test.py (original)
+++ branches/trac292/src/bin/xfrout/tests/xfrout_test.py Mon Oct 18 10:46:07 2010
@@ -40,8 +40,12 @@
         return len(data)
 
     def readsent(self):
-        result = self.sendqueue[:]
-        del self.sendqueue[:]
+        if len(self.sendqueue) >= 2:
+            size = 2 + struct.unpack("!H", self.sendqueue[:2])[0]
+        else:
+            size = 0
+        result = self.sendqueue[:size]
+        self.sendqueue = self.sendqueue[size:]
         return result
     
     def read_msg(self):
@@ -133,7 +137,7 @@
 
         msg = self.getmsg()
         msg.make_response()
-        self.xfrsess._send_message_with_last_soa(msg, self.sock, rrset_soa)
+        self.xfrsess._send_message_with_last_soa(msg, self.sock, rrset_soa, 0)
         get_msg = self.sock.read_msg()
 
         self.assertEqual(get_msg.get_rr_count(Section.QUESTION()), 1)
@@ -148,10 +152,52 @@
         rdata = answer.get_rdata()
         self.assertEqual(rdata[0].to_text(), self.soa_record[7])
 
-    def test_get_message_len(self):
-        msg = self.getmsg()
-        msg.make_response()  
-        self.assertEqual(self.xfrsess._get_message_len(msg), 29)
+    def test_trigger_send_message_with_last_soa(self):
+        rrset_a = RRset(Name("example.com"), RRClass.IN(), RRType.A(), RRTTL(3600))
+        rrset_a.add_rdata(Rdata(RRType.A(), RRClass.IN(), "192.0.2.1"))
+        rrset_soa = self.xfrsess._create_rrset_from_db_record(self.soa_record)
+
+        msg = self.getmsg()
+        msg.make_response()
+
+        msg.add_rrset(Section.ANSWER(), rrset_a)
+        # give the function a value that is larger than MAX-len(rrset)
+        self.xfrsess._send_message_with_last_soa(msg, self.sock, rrset_soa, 65520)
+
+        # this should have triggered the sending of two messages
+        # (1 with the rrset we added manually, and 1 that triggered
+        # the sending in _with_last_soa)
+        get_msg = self.sock.read_msg()
+        self.assertEqual(get_msg.get_rr_count(Section.QUESTION()), 1)
+        self.assertEqual(get_msg.get_rr_count(Section.ANSWER()), 1)
+        self.assertEqual(get_msg.get_rr_count(Section.AUTHORITY()), 0)
+
+        answer = get_msg.get_section(Section.ANSWER())[0]
+        self.assertEqual(answer.get_name().to_text(), "example.com.")
+        self.assertEqual(answer.get_class(), RRClass("IN"))
+        self.assertEqual(answer.get_type().to_text(), "A")
+        rdata = answer.get_rdata()
+        self.assertEqual(rdata[0].to_text(), "192.0.2.1")
+
+        get_msg = self.sock.read_msg()
+        self.assertEqual(get_msg.get_rr_count(Section.QUESTION()), 0)
+        self.assertEqual(get_msg.get_rr_count(Section.ANSWER()), 1)
+        self.assertEqual(get_msg.get_rr_count(Section.AUTHORITY()), 0)
+
+        #answer_rrset_iter = section_iter(get_msg, section.ANSWER())
+        answer = get_msg.get_section(Section.ANSWER())[0]
+        self.assertEqual(answer.get_name().to_text(), "example.com.")
+        self.assertEqual(answer.get_class(), RRClass("IN"))
+        self.assertEqual(answer.get_type().to_text(), "SOA")
+        rdata = answer.get_rdata()
+        self.assertEqual(rdata[0].to_text(), self.soa_record[7])
+
+        # and it should not have sent anything else
+        self.assertEqual(0, len(self.sock.sendqueue))
+
+    def test_get_rrset_len(self):
+        rrset_soa = self.xfrsess._create_rrset_from_db_record(self.soa_record)
+        self.assertEqual(82, get_rrset_len(rrset_soa))
 
     def test_zone_is_empty(self):
         global sqlite3_ds

Modified: branches/trac292/src/bin/xfrout/xfrout.py.in
==============================================================================
--- branches/trac292/src/bin/xfrout/xfrout.py.in (original)
+++ branches/trac292/src/bin/xfrout/xfrout.py.in Mon Oct 18 10:46:07 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
@@ -27,8 +28,9 @@
 import os
 from isc.config.ccsession import *
 from isc.log.log import *
-from isc.cc import SessionError
+from isc.cc import SessionError, SessionTimeout
 from isc.notify import notify_out
+import isc.utils.process
 import socket
 import select
 import errno
@@ -41,6 +43,8 @@
     # 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"
     AUTH_SPECFILE_PATH = os.environ["B10_FROM_BUILD"] + "/src/bin/auth"
@@ -57,6 +61,15 @@
 MAX_TRANSFERS_OUT = 10
 VERBOSE_MODE = False
 
+XFROUT_MAX_MESSAGE_SIZE = 65535
+
+def get_rrset_len(rrset):
+    """Returns the wire length of the given RRset"""
+    bytes = bytearray()
+    rrset.to_wire(bytes)
+    return len(bytes)
+
+
 class XfroutSession(BaseRequestHandler):
     def __init__(self, request, client_address, server, log):
         # The initializer for the superclass may call functions
@@ -121,10 +134,8 @@
 
 
     def _send_message(self, sock, msg):
-        #obuf = output_buffer(0)
-        #render = message_render(obuf)
         render = MessageRenderer()
-        render.set_length_limit(65535)
+        render.set_length_limit(XFROUT_MAX_MESSAGE_SIZE)
         msg.to_wire(render)
         header_len = struct.pack('H', socket.htons(render.get_length()))
         self._send_data(sock, header_len)
@@ -227,34 +238,20 @@
         rrset_.add_rdata(rdata_)
         return rrset_
          
-    def _send_message_with_last_soa(self, msg, sock, rrset_soa):
+    def _send_message_with_last_soa(self, msg, sock, rrset_soa, message_upper_len):
         '''Add the SOA record to the end of message. If it can't be
         added, a new message should be created to send out the last soa .
         '''
-
-        render = MessageRenderer()
-        msg.to_wire(render)
-        old_message_len = render.get_length()
-        msg.add_rrset(Section.ANSWER(), rrset_soa)
-
-        msg.to_wire(render)
-        message_len = render.get_length()
-
-        if message_len != old_message_len:
+        rrset_len = get_rrset_len(rrset_soa)
+
+        if message_upper_len + rrset_len < XFROUT_MAX_MESSAGE_SIZE:
+            msg.add_rrset(Section.ANSWER(), rrset_soa)
+        else:
             self._send_message(sock, msg)
-        else:
             msg = self._clear_message(msg)
             msg.add_rrset(Section.ANSWER(), rrset_soa)
-            self._send_message(sock, msg)
-
-    def _get_message_len(self, msg):
-        '''Get message length, every time need do like this? Actually there should be 
-        a better way, I need check with jinmei later.
-        '''
-
-        render = MessageRenderer()
-        msg.to_wire(render)
-        return render.get_length()
+
+        self._send_message(sock, msg)
 
 
     def _reply_xfrout_query(self, msg, sock, zone_name):
@@ -265,9 +262,8 @@
         rrset_soa = self._create_rrset_from_db_record(soa_record)
         msg.add_rrset(Section.ANSWER(), rrset_soa)
 
-        old_message_len = 0
-        # TODO, Since add_rrset() return nothing when rrset can't be added, so I have to compare
-        # the message length to know if the rrset has been added sucessfully.
+        message_upper_len = get_rrset_len(rrset_soa)
+
         for rr_data in sqlite3_ds.get_zone_datas(zone_name, self.server.get_db_file()):
             if  self.server._shutdown_event.is_set(): # Check if xfrout is shutdown
                 self._log.log_message("error", "shutdown!")
@@ -277,19 +273,22 @@
                 continue
 
             rrset_ = self._create_rrset_from_db_record(rr_data)
-            msg.add_rrset(Section.ANSWER(), rrset_)
-            message_len = self._get_message_len(msg)
-            if message_len != old_message_len:
-                old_message_len = message_len
+
+            # We calculate the maximum size of the RRset (i.e. the
+            # size without compression) and use that to see if we
+            # may have reached the limit
+            rrset_len = get_rrset_len(rrset_)
+            if message_upper_len + rrset_len < XFROUT_MAX_MESSAGE_SIZE:
+                msg.add_rrset(Section.ANSWER(), rrset_)
+                message_upper_len += rrset_len
                 continue
 
             self._send_message(sock, msg)
             msg = self._clear_message(msg)
             msg.add_rrset(Section.ANSWER(), rrset_) # Add the rrset to the new message
-            old_message_len = 0
-
-        self._send_message_with_last_soa(msg, sock, rrset_soa)
-
+            message_upper_len = rrset_len
+
+        self._send_message_with_last_soa(msg, sock, rrset_soa, message_upper_len)
 
 class UnixSockServer(ThreadingUnixStreamServer):
     '''The unix domain socket server which accept xfr query sent from auth server.'''
@@ -315,8 +314,8 @@
         If it's not a socket file or nobody is listening
         , it will be removed. If it can't be removed, exit from python. '''
         if self._sock_file_in_use(sock_file):
-            print("[b10-xfrout] Fail to start xfrout process, unix socket" 
-                  " file '%s' is being used by another xfrout process" % sock_file)
+            sys.stderr.write("[b10-xfrout] Fail to start xfrout process, unix socket" 
+                  " file '%s' is being used by another xfrout process\n" % sock_file)
             sys.exit(0)
         else:
             if not os.path.exists(sock_file):
@@ -325,7 +324,7 @@
             try:
                 os.unlink(sock_file)
             except OSError as err:
-                print('[b10-xfrout] Fail to remove file ' + sock_file, err)
+                sys.stderr.write('[b10-xfrout] Fail to remove file %s: %s\n' % (sock_file, err))
                 sys.exit(0)
    
     def _sock_file_in_use(self, sock_file):
@@ -409,9 +408,9 @@
         self._listen_sock_file = UNIX_SOCKET_FILE 
         self._shutdown_event = threading.Event()
         self._cc = isc.config.ModuleCCSession(SPECFILE_LOCATION, self.config_handler, self.command_handler)
-        self._cc.add_remote_config(AUTH_SPECFILE_LOCATION);
         self._config_data = self._cc.get_full_config()
         self._cc.start()
+        self._cc.add_remote_config(AUTH_SPECFILE_LOCATION);
         self._log = isc.log.NSLogger(self._config_data.get('log_name'), self._config_data.get('log_file'),
                                 self._config_data.get('log_severity'), self._config_data.get('log_versions'),
                                 self._config_data.get('log_max_bytes'), True)
@@ -496,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
@@ -525,12 +524,15 @@
         xfrout_server = XfroutServer()
         xfrout_server.run()
     except KeyboardInterrupt:
-        sys.stderr.write("[b10-xfrout] exit xfrout process")
+        sys.stderr.write("[b10-xfrout] exit xfrout process\n")
     except SessionError as e:
-        sys.stderr.write("[b10-xfrout] Error creating xfrout," 
-                           "is the command channel daemon running?")
+        sys.stderr.write("[b10-xfrout] Error creating xfrout, "
+                           "is the command channel daemon running?\n")
+    except SessionTimeout as e:
+        sys.stderr.write("[b10-xfrout] Error creating xfrout, " 
+                           "is the configuration manager running?\n")
     except ModuleCCSessionError as e:
-        sys.stderr.write("info", '[b10-xfrout] exit xfrout process:', e)
+        sys.stderr.write("[b10-xfrout] exit xfrout process:%s\n" % str(e))
 
     if xfrout_server:
         xfrout_server.shutdown()

Modified: branches/trac292/src/bin/zonemgr/Makefile.am
==============================================================================
--- branches/trac292/src/bin/zonemgr/Makefile.am (original)
+++ branches/trac292/src/bin/zonemgr/Makefile.am Mon Oct 18 10:46:07 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 pkglibexecdir = $(libexecdir)/@PACKAGE@
 
@@ -9,6 +9,16 @@
 
 CLEANFILES = b10-zonemgr zonemgr.pyc zonemgr.spec
 
+man_MANS = b10-zonemgr.8
+EXTRA_DIST = $(man_MANS) b10-zonemgr.xml
+
+if ENABLE_MAN
+
+b10-zonemgr.8: b10-zonemgr.xml
+	xsltproc --novalid --xinclude --nonet -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $(srcdir)/b10-zonemgr.xml
+
+endif
+
 zonemgr.spec: zonemgr.spec.pre
 	$(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" zonemgr.spec.pre >$@
 

Modified: branches/trac292/src/bin/zonemgr/TODO
==============================================================================
--- branches/trac292/src/bin/zonemgr/TODO (original)
+++ branches/trac292/src/bin/zonemgr/TODO Mon Oct 18 10:46:07 2010
@@ -1,5 +1,6 @@
 1. Zonemgr should support adding/deleting zones dynamically.
 2. Make zonemgr  has customizable configurations for LOWERBOUND_REFRESH, LOWERBOUND_RETRY, MAX_TRANSFER_TIMEOUT, REFRESH_OFFSET, RETRY_OFFSET, EXPIRED_OFFSET, and/or jitter?
 3. There should be one way to see the current counters/timers and other data for each zone managed by zonemgr.
+4. There should be one way to turn off zonemgr.(Does user really need it? not sure what's the purpose of user)
 
 

Modified: branches/trac292/src/bin/zonemgr/tests/zonemgr_test.py
==============================================================================
--- branches/trac292/src/bin/zonemgr/tests/zonemgr_test.py (original)
+++ branches/trac292/src/bin/zonemgr/tests/zonemgr_test.py Mon Oct 18 10:46:07 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/trac292/src/bin/zonemgr/zonemgr.py.in
==============================================================================
--- branches/trac292/src/bin/zonemgr/zonemgr.py.in (original)
+++ branches/trac292/src/bin/zonemgr/zonemgr.py.in Mon Oct 18 10:46:07 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):
@@ -261,7 +264,7 @@
         try:
             self._cc.group_sendmsg(msg, module_name)
         except socket.error:
-            sys.err.write("[b10-zonemgr] Failed to send to module %s, the session has been closed." % module_name) 
+            sys.stderr.write("[b10-zonemgr] Failed to send to module %s, the session has been closed." % module_name) 
 
     def _find_need_do_refresh_zone(self):
         """Find the first zone need do refresh, if no zone need
@@ -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
 
@@ -513,12 +526,15 @@
         zonemgrd = Zonemgr()
         zonemgrd.run()
     except KeyboardInterrupt:
-        sys.stderr.write("[b10-zonemgr] exit zonemgr process")
+        sys.stderr.write("[b10-zonemgr] exit zonemgr process\n")
     except isc.cc.session.SessionError as e:
         sys.stderr.write("[b10-zonemgr] Error creating zonemgr, " 
-                           "is the command channel daemon running?")
+                           "is the command channel daemon running?\n")
+    except isc.cc.session.SessionTimeout as e:
+        sys.stderr.write("[b10-zonemgr] Error creating zonemgr, " 
+                           "is the configuration manager running?\n")
     except isc.config.ModuleCCSessionError as e:
-        sys.stderr.write("info", "[b10-zonemgr] exit zonemgr process:", e)
+        sys.stderr.write("[b10-zonemgr] exit zonemgr process: %s\n" % str(e))
 
     if zonemgrd:
         zonemgrd.shutdown()

Modified: branches/trac292/src/bin/zonemgr/zonemgr.spec.pre.in
==============================================================================
--- branches/trac292/src/bin/zonemgr/zonemgr.spec.pre.in (original)
+++ branches/trac292/src/bin/zonemgr/zonemgr.spec.pre.in Mon Oct 18 10:46:07 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/trac292/src/lib/bench/benchmark_util.cc
==============================================================================
--- branches/trac292/src/lib/bench/benchmark_util.cc (original)
+++ branches/trac292/src/lib/bench/benchmark_util.cc Mon Oct 18 10:46:07 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/trac292/src/lib/bench/tests/loadquery_unittest.cc
==============================================================================
--- branches/trac292/src/lib/bench/tests/loadquery_unittest.cc (original)
+++ branches/trac292/src/lib/bench/tests/loadquery_unittest.cc Mon Oct 18 10:46:07 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/trac292/src/lib/cc/data.cc
==============================================================================
--- branches/trac292/src/lib/cc/data.cc (original)
+++ branches/trac292/src/lib/cc/data.cc Mon Oct 18 10:46:07 2010
@@ -184,7 +184,8 @@
 
 namespace {
 inline void
-throwJSONError(const std::string& error, const std::string& file, int line, int pos)
+throwJSONError(const std::string& error, const std::string& file, int line,
+               int pos)
 {
     std::stringstream ss;
     ss << error << " in " + file + ":" << line << ":" << pos;
@@ -427,13 +428,15 @@
 }
 
 ElementPtr
-from_stringstream_string(std::istream& in, const std::string& file, int& line, int& pos)
+from_stringstream_string(std::istream& in, const std::string& file, int& line,
+                         int& pos)
 {
     return (Element::create(str_from_stringstream(in, file, line, pos)));
 }
 
 ElementPtr
-from_stringstream_list(std::istream &in, const std::string& file, int& line, int& pos)
+from_stringstream_list(std::istream &in, const std::string& file, int& line,
+                       int& pos)
 {
     char c = 0;
     ElementPtr list = Element::createList();
@@ -484,8 +487,7 @@
 }
 
 std::string
-Element::typeToName(Element::types type)
-{
+Element::typeToName(Element::types type) {
     switch (type) {
     case Element::integer:
         return (std::string("integer"));
@@ -538,14 +540,16 @@
 }
 
 ElementPtr
-Element::fromJSON(std::istream& in, const std::string& file_name) throw(JSONError)
+Element::fromJSON(std::istream& in, const std::string& file_name)
+    throw(JSONError)
 {
     int line = 1, pos = 1;
     return (fromJSON(in, file_name, line, pos));
 }
 
 ElementPtr
-Element::fromJSON(std::istream &in, const std::string& file, int& line, int& pos) throw(JSONError)
+Element::fromJSON(std::istream &in, const std::string& file, int& line,
+                  int& pos) throw(JSONError)
 {
     char c = 0;
     ElementPtr element;
@@ -892,7 +896,7 @@
         isc_throw(TypeError, "merge arguments not MapElements");
     }
     
-    std::map<std::string, ConstElementPtr> m = other->mapValue();
+    const std::map<std::string, ConstElementPtr>& m = other->mapValue();
     for (std::map<std::string, ConstElementPtr>::const_iterator it = m.begin();
          it != m.end() ; ++it) {
         if ((*it).second && (*it).second->getType() != Element::null) {

Modified: branches/trac292/src/lib/cc/tests/Makefile.am
==============================================================================
--- branches/trac292/src/lib/cc/tests/Makefile.am (original)
+++ branches/trac292/src/lib/cc/tests/Makefile.am Mon Oct 18 10:46:07 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/trac292/src/lib/cc/tests/run_unittests.cc
==============================================================================
--- branches/trac292/src/lib/cc/tests/run_unittests.cc (original)
+++ branches/trac292/src/lib/cc/tests/run_unittests.cc Mon Oct 18 10:46:07 2010
@@ -17,8 +17,7 @@
 #include <gtest/gtest.h>
 
 int
-main(int argc, char* argv[])
-{
+main(int argc, char* argv[]) {
     ::testing::InitGoogleTest(&argc, argv);
     return (RUN_ALL_TESTS());
 }

Modified: branches/trac292/src/lib/config/Makefile.am
==============================================================================
--- branches/trac292/src/lib/config/Makefile.am (original)
+++ branches/trac292/src/lib/config/Makefile.am Mon Oct 18 10:46:07 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/trac292/src/lib/config/ccsession.cc
==============================================================================
--- branches/trac292/src/lib/config/ccsession.cc (original)
+++ branches/trac292/src/lib/config/ccsession.cc Mon Oct 18 10:46:07 2010
@@ -333,8 +333,7 @@
 }
 
 std::string
-ModuleCCSession::addRemoteConfig(const std::string& spec_file_name)
-{
+ModuleCCSession::addRemoteConfig(const std::string& spec_file_name) {
     ModuleSpec rmod_spec = readModuleSpecification(spec_file_name);
     std::string module_name = rmod_spec.getFullSpec()->get("module_name")->stringValue();
     ConfigData rmod_config = ConfigData(rmod_spec);
@@ -362,8 +361,7 @@
 }
 
 void
-ModuleCCSession::removeRemoteConfig(const std::string& module_name)
-{
+ModuleCCSession::removeRemoteConfig(const std::string& module_name) {
     std::map<std::string, ConfigData>::iterator it;
 
     it = remote_module_configs_.find(module_name);

Modified: branches/trac292/src/lib/config/tests/Makefile.am
==============================================================================
--- branches/trac292/src/lib/config/tests/Makefile.am (original)
+++ branches/trac292/src/lib/config/tests/Makefile.am Mon Oct 18 10:46:07 2010
@@ -1,3 +1,5 @@
+SUBDIRS = testdata .
+
 AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
 
 AM_CXXFLAGS = $(B10_CXXFLAGS)
@@ -24,12 +26,9 @@
 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
 run_unittests_LDADD += libfake_session.la
 run_unittests_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
-# link *only* to data.o from lib/cc (more importantly, don't link in
-# the session class provided there, since we use our own fake_session
-# here)
-run_unittests_LDADD += $(top_builddir)/src/lib/cc/data.o
 
 endif
 

Modified: branches/trac292/src/lib/config/tests/ccsession_unittests.cc
==============================================================================
--- branches/trac292/src/lib/config/tests/ccsession_unittests.cc (original)
+++ branches/trac292/src/lib/config/tests/ccsession_unittests.cc Mon Oct 18 10:46:07 2010
@@ -164,8 +164,7 @@
     EXPECT_EQ(0, session.getMsgQueue()->size());
 }
 
-TEST_F(CCSessionTest, session2)
-{
+TEST_F(CCSessionTest, session2) {
     EXPECT_EQ(false, session.haveSubscription("Spec2", "*"));
     ModuleCCSession mccs(ccspecfile("spec2.spec"), session, NULL, NULL);
     EXPECT_EQ(true, session.haveSubscription("Spec2", "*"));

Modified: branches/trac292/src/lib/config/tests/data_def_unittests_config.h.in
==============================================================================
--- branches/trac292/src/lib/config/tests/data_def_unittests_config.h.in (original)
+++ branches/trac292/src/lib/config/tests/data_def_unittests_config.h.in Mon Oct 18 10:46:07 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/trac292/src/lib/config/tests/module_spec_unittests.cc
==============================================================================
--- branches/trac292/src/lib/config/tests/module_spec_unittests.cc (original)
+++ branches/trac292/src/lib/config/tests/module_spec_unittests.cc Mon Oct 18 10:46:07 2010
@@ -105,8 +105,7 @@
                    "badname is not a valid type name");
 }
 
-TEST(ModuleSpec, SpecfileConfigData)
-{
+TEST(ModuleSpec, SpecfileConfigData) {
     module_spec_error("spec7.spec",
                    "module_name missing in {  }");
     module_spec_error("spec8.spec",
@@ -117,8 +116,7 @@
                    "commands is not a list of elements");
 }
 
-TEST(ModuleSpec, SpecfileCommands)
-{
+TEST(ModuleSpec, SpecfileCommands) {
     module_spec_error("spec17.spec",
                    "command_name missing in { \"command_args\": [ { \"item_default\": \"\", \"item_name\": \"message\", \"item_optional\": false, \"item_type\": \"string\" } ], \"command_description\": \"Print the given message to stdout\" }");
     module_spec_error("spec18.spec",

Modified: branches/trac292/src/lib/config/tests/run_unittests.cc
==============================================================================
--- branches/trac292/src/lib/config/tests/run_unittests.cc (original)
+++ branches/trac292/src/lib/config/tests/run_unittests.cc Mon Oct 18 10:46:07 2010
@@ -17,8 +17,7 @@
 #include <gtest/gtest.h>
 
 int
-main(int argc, char* argv[])
-{
+main(int argc, char* argv[]) {
     ::testing::InitGoogleTest(&argc, argv);
     return (RUN_ALL_TESTS());
 }

Modified: branches/trac292/src/lib/datasrc/data_source.cc
==============================================================================
--- branches/trac292/src/lib/datasrc/data_source.cc (original)
+++ branches/trac292/src/lib/datasrc/data_source.cc Mon Oct 18 10:46:07 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/trac292/src/lib/datasrc/static_datasrc.cc
==============================================================================
--- branches/trac292/src/lib/datasrc/static_datasrc.cc (original)
+++ branches/trac292/src/lib/datasrc/static_datasrc.cc Mon Oct 18 10:46:07 2010
@@ -110,14 +110,12 @@
                                "0 28800 7200 604800 86400"));
 }
 
-StaticDataSrc::StaticDataSrc()
-{
+StaticDataSrc::StaticDataSrc() {
     setClass(RRClass::CH());
     impl_ = new StaticDataSrcImpl;
 }
 
-StaticDataSrc::~StaticDataSrc()
-{
+StaticDataSrc::~StaticDataSrc() {
     delete impl_;
 }
 

Modified: branches/trac292/src/lib/datasrc/tests/datasrc_unittest.cc
==============================================================================
--- branches/trac292/src/lib/datasrc/tests/datasrc_unittest.cc (original)
+++ branches/trac292/src/lib/datasrc/tests/datasrc_unittest.cc Mon Oct 18 10:46:07 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/trac292/src/lib/datasrc/tests/query_unittest.cc
==============================================================================
--- branches/trac292/src/lib/datasrc/tests/query_unittest.cc (original)
+++ branches/trac292/src/lib/datasrc/tests/query_unittest.cc Mon Oct 18 10:46:07 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/trac292/src/lib/datasrc/tests/run_unittests.cc
==============================================================================
--- branches/trac292/src/lib/datasrc/tests/run_unittests.cc (original)
+++ branches/trac292/src/lib/datasrc/tests/run_unittests.cc Mon Oct 18 10:46:07 2010
@@ -19,8 +19,7 @@
 #include <dns/tests/unittest_util.h>
 
 int
-main(int argc, char* argv[])
-{
+main(int argc, char* argv[]) {
     ::testing::InitGoogleTest(&argc, argv);
     isc::UnitTestUtil::addDataPath(TEST_DATA_DIR);
 

Modified: branches/trac292/src/lib/dns/Makefile.am
==============================================================================
--- branches/trac292/src/lib/dns/Makefile.am (original)
+++ branches/trac292/src/lib/dns/Makefile.am Mon Oct 18 10:46:07 2010
@@ -63,11 +63,14 @@
 libdns___la_SOURCES += util/base16_from_binary.h util/binary_from_base16.h
 libdns___la_SOURCES += buffer.h
 libdns___la_SOURCES += dnssectime.h dnssectime.cc
+libdns___la_SOURCES += edns.h edns.cc
 libdns___la_SOURCES += exceptions.h exceptions.cc
 libdns___la_SOURCES += util/hex.h
 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
@@ -88,8 +91,8 @@
 rrclass.h rrtype.h rrparamregistry.cc rdataclass.h rdataclass.cc: Makefile
 	./gen-rdatacode.py
 
-libdns++_includedir = $(includedir)/dns
-libdns++_include_HEADERS = \
+libdns___includedir = $(includedir)/dns
+libdns___include_HEADERS = \
 	buffer.h \
 	dnssectime.h \
 	exceptions.h \

Modified: branches/trac292/src/lib/dns/exceptions.cc
==============================================================================
--- branches/trac292/src/lib/dns/exceptions.cc (original)
+++ branches/trac292/src/lib/dns/exceptions.cc Mon Oct 18 10:46:07 2010
@@ -15,7 +15,7 @@
 // $Id$
 
 #include <dns/exceptions.h>
-#include <dns/message.h>
+#include <dns/rcode.h>
 
 namespace isc {
 namespace dns {

Modified: branches/trac292/src/lib/dns/gen-rdatacode.py.in
==============================================================================
--- branches/trac292/src/lib/dns/gen-rdatacode.py.in (original)
+++ branches/trac292/src/lib/dns/gen-rdatacode.py.in Mon Oct 18 10:46:07 2010
@@ -113,7 +113,7 @@
         if re.match('\s+// BEGIN_COMMON_MEMBERS$', line):
             content += '''
     explicit ''' + type_utxt + '''(const std::string& type_str);
-    explicit ''' + type_utxt + '''(InputBuffer& buffer, size_t rdata_len);
+    ''' + type_utxt + '''(InputBuffer& buffer, size_t rdata_len);
     ''' + type_utxt + '''(const ''' + type_utxt + '''& other);
     virtual std::string toText() const;
     virtual void toWire(OutputBuffer& buffer) const;
@@ -129,12 +129,13 @@
     global rdatadef_mtime
     global rdatahdr_mtime
 
+    if classdir_mtime < getmtime('@srcdir@/rdata'):
+        classdir_mtime = getmtime('@srcdir@/rdata')
+
     for dir in list(os.listdir('@srcdir@/rdata')):
         classdir = '@srcdir@/rdata' + os.sep + dir
         m = re_typecode.match(dir)
         if os.path.isdir(classdir) and (m != None or dir == 'generic'):
-            if classdir_mtime < getmtime(classdir):
-                classdir_mtime = getmtime(classdir)
             if dir == 'generic':
                 class_txt = 'generic'
                 class_code = generic_code
@@ -219,8 +220,7 @@
         codetxt = code2txt[code].upper()
         declarationtxt += ' ' * 4 + 'static const RR' + cap_key + '& ' + codetxt + '();\n'
         deftxt += '''inline const RR''' + cap_key + '''&
-RR''' + cap_key + '''::''' + codetxt + '''()
-{
+RR''' + cap_key + '''::''' + codetxt + '''() {
     static RR''' + cap_key + ''' ''' + lower_key + '''(''' + code + ''');
     return (''' + lower_key + ''');
 }\n
@@ -284,9 +284,7 @@
         generate_rdatadef('@builddir@/rdataclass.cc', rdatadef_mtime)
         generate_rdatahdr('@builddir@/rdataclass.h', rdata_declarations,
                           rdatahdr_mtime)
-        generate_typeclasscode('rrtype',
-                               max(rdatadef_mtime, rdatahdr_mtime),
-                               typecode2txt, 'Type')
+        generate_typeclasscode('rrtype', rdatahdr_mtime, typecode2txt, 'Type')
         generate_typeclasscode('rrclass', classdir_mtime,
                                classcode2txt, 'Class')
         generate_rrparam('rrparamregistry', rdatahdr_mtime)

Modified: branches/trac292/src/lib/dns/message.cc
==============================================================================
--- branches/trac292/src/lib/dns/message.cc (original)
+++ branches/trac292/src/lib/dns/message.cc Mon Oct 18 10:46:07 2010
@@ -28,10 +28,13 @@
 #include <exceptions/exceptions.h>
 
 #include <dns/buffer.h>
+#include <dns/edns.h>
 #include <dns/exceptions.h>
 #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>
@@ -61,98 +64,12 @@
 const flags_t FLAG_AD = 0x0020;
 const flags_t FLAG_CD = 0x0010;
 
-//
-// EDNS related constants
-//
-const flags_t EXTFLAG_MASK = 0xffff;
-const flags_t EXTFLAG_DO = 0x8000;
-const uint32_t EXTRCODE_MASK = 0xff000000; 
-const uint32_t EDNSVERSION_MASK = 0x00ff0000;
-
 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",
@@ -160,28 +77,6 @@
     "AUTHORITY",
     "ADDITIONAL"
 };
-}
-
-string
-Opcode::toText() const {
-    return (opcodetext[code_]);
-}
-
-Rcode::Rcode(uint16_t code) : code_(code) {
-    if (code_ > MAX_RCODE) {
-        isc_throw(OutOfRange, "Rcode is too large to construct");
-    }
-}
-
-string
-Rcode::toText() const {
-    if (code_ < sizeof(rcodetext) / sizeof (const char *)) {
-        return (rcodetext[code_]);
-    }
-
-    ostringstream oss;
-    oss << code_;
-    return (oss.str());
 }
 
 namespace {
@@ -200,20 +95,24 @@
     // 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 dnssec_ok_;
 
     bool header_parsed_;
     static const unsigned int SECTION_MAX = 4; // TODO: revisit this design
     int counts_[SECTION_MAX];   // TODO: revisit this definition
     vector<QuestionPtr> questions_;
     vector<RRsetPtr> rrsets_[SECTION_MAX];
-    RRsetPtr remote_edns_;
-    uint16_t remote_udpsize_;
-    RRsetPtr local_edns_;
-    uint16_t udpsize_;
+    ConstEDNSPtr edns_;
 
 #ifdef notyet
     // tsig/sig0: TODO
@@ -221,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();
 }
@@ -235,13 +138,9 @@
 MessageImpl::init() {
     flags_ = 0;
     qid_ = 0;
-    rcode_ = Rcode::NOERROR();  // XXX
+    rcode_ = NULL;
     opcode_ = NULL;
-    dnssec_ok_ = false;
-    remote_edns_ = RRsetPtr();
-    remote_udpsize_ = Message::DEFAULT_MAX_UDPSIZE;
-    local_edns_ = RRsetPtr();
-    udpsize_ = Message::DEFAULT_MAX_UDPSIZE;
+    edns_ = EDNSPtr();
 
     for (int i = 0; i < SECTION_MAX; ++i) {
         counts_[i] = 0;
@@ -254,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))
 {}
@@ -285,38 +196,6 @@
     impl_->flags_ &= ~flag.getBit();
 }
 
-bool
-Message::isDNSSECSupported() const {
-    return (impl_->dnssec_ok_);
-}
-
-void
-Message::setDNSSECSupported(bool on) {
-    if (impl_->mode_ != Message::RENDER) {
-        isc_throw(InvalidMessageOperation,
-                  "setDNSSECSupported performed in non-render mode");
-    }
-    impl_->dnssec_ok_ = on;
-}
-
-uint16_t
-Message::getUDPSize() const {
-    return (impl_->udpsize_);
-}
-
-void
-Message::setUDPSize(uint16_t size) {
-    if (impl_->mode_ != Message::RENDER) {
-        isc_throw(InvalidMessageOperation,
-                  "setUDPSize performed in non-render mode");
-    }
-    if (size < DEFAULT_MAX_UDPSIZE) {
-        isc_throw(InvalidMessageUDPSize,
-                  "Specified UDP message size is too small");
-    }
-    impl_->udpsize_ = size;
-}
-
 qid_t
 Message::getQid() const {
     return (impl_->qid_);
@@ -333,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
@@ -342,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_);
 }
 
@@ -356,7 +241,21 @@
         isc_throw(InvalidMessageOperation,
                   "setOpcode performed in non-render mode");
     }
-    impl_->opcode_ = &opcode;
+    impl_->setOpcode(opcode);
+}
+
+ConstEDNSPtr
+Message::getEDNS() const {
+    return (impl_->edns_);
+}
+
+void
+Message::setEDNS(ConstEDNSPtr edns) {
+    if (impl_->mode_ != Message::RENDER) {
+        isc_throw(InvalidMessageOperation,
+                  "setEDNS performed in non-render mode");
+    }
+    impl_->edns_ = edns;
 }
 
 unsigned int
@@ -441,59 +340,19 @@
 };
 }
 
-namespace {
-bool
-addEDNS(MessageImpl* mimpl, MessageRenderer& renderer) {
-    const bool is_query = ((mimpl->flags_ & MessageFlag::QR().getBit()) == 0); 
-
-    // If this is a reply, add EDNS either when the request had it, or
-    // if the Rcode is BADVERS, which is EDNS specific.
-    // XXX: this logic is tricky.  We should revisit this later.
-    if (!is_query) {
-        if (mimpl->remote_edns_ == NULL && mimpl->rcode_ != Rcode::BADVERS()) {
-            return (false);
-        }
-    } else {
-        // For queries, we add EDNS only when necessary:
-        // Local UDP size is not the default value, or
-        // DNSSEC DO bit is to be set, or
-        // Extended Rcode is to be specified.
-        if (mimpl->udpsize_ == Message::DEFAULT_MAX_UDPSIZE &&
-            !mimpl->dnssec_ok_ &&
-            mimpl->rcode_.getCode() < 0x10) {
-            return (false);
-        }
-    }
-
-    // If adding the OPT RR would exceed the size limit, don't do it.
-    // 11 = len(".") + type(2byte) + class(2byte) + TTL(4byte) + RDLEN(2byte)
-    // (RDATA is empty in this simple implementation)
-    if (renderer.getLength() + 11 > renderer.getLengthLimit()) {
-        return (false);
-    }
-
-    // Render EDNS OPT RR
-    uint32_t extrcode_flags = ((mimpl->rcode_.getCode() & 0xff0) << 24);
-    if (mimpl->dnssec_ok_) {
-        extrcode_flags |= 0x8000; // set DO bit
-    }
-    mimpl->local_edns_ = RRsetPtr(new RRset(Name::ROOT_NAME(),
-                                            RRClass(mimpl->udpsize_),
-                                            RRType::OPT(),
-                                            RRTTL(extrcode_flags)));
-    // We don't support any options in this simple implementation
-    mimpl->local_edns_->addRdata(ConstRdataPtr(new generic::OPT()));
-    mimpl->local_edns_->toWire(renderer);
-
-    return (true);
-}
-}
-
 void
 Message::toWire(MessageRenderer& renderer) {
     if (impl_->mode_ != Message::RENDER) {
         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
@@ -528,12 +387,20 @@
                      RenderSection<RRsetPtr>(renderer, false)).getTotalCount();
     }
 
-    // Added EDNS OPT RR if necessary (we want to avoid hardcoding specialized
-    // logic, see the parser case)
-    if (!renderer.isTruncated() && addEDNS(this->impl_, renderer)) {
-        ++arcount;
-    }
-
+    // Add EDNS OPT RR if necessary.  Basically, we add it only when EDNS
+    // has been explicitly set.  However, if the RCODE would require it and
+    // 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) {
+            local_edns = ConstEDNSPtr(new EDNS());
+        }
+        if (local_edns) {
+            arcount += local_edns->toWire(renderer,
+                                          impl_->rcode_->getExtendedCode());
+        }
+    }
+ 
     // Adjust the counter buffer.
     // XXX: these may not be equal to the number of corresponding entries
     // in rrsets_[] or questions_ if truncation occurred or an EDNS OPT RR
@@ -553,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);
@@ -582,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();
@@ -657,6 +524,34 @@
 };
 }
 
+// Note about design decision:
+// we need some type specific processing here, including EDNS and TSIG.
+// how much we should generalize/hardcode the special logic is subject
+// to discussion.  In terms of modularity it would be ideal to introduce
+// an abstract class (say "MessageAttribute") and let other such
+// concrete notions as EDNS or TSIG inherit from it.  Then we would
+// just do:
+// message->addAttribute(rrtype, rrclass, buffer);
+// to create and attach type-specific concrete object to the message.
+//
+// A major downside of this approach is, as usual, complexity due to
+// indirection and performance penalty.  Also, it may not be so easy
+// to separate the processing logic because in many cases we'll need
+// parse context for which the message class is responsible (e.g.
+// to check the EDNS OPT RR only appears in the additional section,
+// and appears only once).
+//
+// Another point to consider is that we may not need so many special
+// types other than EDNS and TSIG (and when and if we implement it,
+// SIG(0)); newer optional attributes of the message would more likely
+// be standardized as new flags or options of EDNS.  If that's the case,
+// introducing an abstract class with all the overhead and complexity
+// may not make much sense.
+//
+// Conclusion: don't over-generalize type-specific logic for now.
+// introduce separate concrete classes, and move context-independent
+// logic to that class; processing logic dependent on parse context
+// is hardcoded here.
 int
 MessageImpl::parseSection(const Section& section, InputBuffer& buffer) {
     unsigned int added = 0;
@@ -678,60 +573,36 @@
         const size_t rdlen = buffer.readUint16();
         ConstRdataPtr rdata = createRdata(rrtype, rrclass, buffer, rdlen);
 
-        // XXX: we wanted to avoid hardcoding type-specific logic here,
-        // but this would be the fastest way for a proof-of-concept
-        // implementation.  We'll revisit this part later.
         if (rrtype == RRType::OPT()) {
             if (section != Section::ADDITIONAL()) {
                 isc_throw(DNSMessageFORMERR,
                           "EDNS OPT RR found in an invalid section");
             }
-            if (remote_edns_ != NULL) {
+            if (edns_) {
                 isc_throw(DNSMessageFORMERR, "multiple EDNS OPT RR found");
             }
-            if (((ttl.getValue() & EDNSVERSION_MASK) >> 16) >
-                Message::EDNS_SUPPORTED_VERSION) {
-                // XXX: we should probably not reject the message yet, because
-                // it's better to let the requestor know the responder-side
-                // highest version as indicated in Section 4.6 of RFC2671.
-                // This is probably because why BIND 9 does the version check
-                // in the client code.
-                // This is a TODO item.  Right now we simply reject it.
-                const unsigned int ver =
-                    (ttl.getValue() & EDNSVERSION_MASK) >> 16;
-                isc_throw(DNSMessageBADVERS, "unsupported EDNS version: " <<
-                          ver);
+
+            uint8_t extended_rcode;
+            edns_ = ConstEDNSPtr(createEDNSFromRR(name, rrclass, rrtype, ttl,
+                                                  *rdata, extended_rcode));
+            setRcode(Rcode(rcode_->getCode(), extended_rcode));
+            continue;
+        } else {
+            vector<RRsetPtr>::iterator it =
+                find_if(rrsets_[sectionCodeToId(section)].begin(),
+                        rrsets_[sectionCodeToId(section)].end(),
+                        MatchRR(name, rrtype, rrclass));
+            if (it != rrsets_[sectionCodeToId(section)].end()) {
+                (*it)->setTTL(min((*it)->getTTL(), ttl));
+                (*it)->addRdata(rdata);
+            } else {
+                RRsetPtr rrset =
+                    RRsetPtr(new RRset(name, rrclass, rrtype, ttl)); 
+                rrset->addRdata(rdata);
+                rrsets_[sectionCodeToId(section)].push_back(rrset);
             }
-            if (name != Name::ROOT_NAME()) {
-                isc_throw(DNSMessageFORMERR,
-                          "invalid owner name for EDNS OPT RR");
-            }
-
-            remote_edns_ = RRsetPtr(new RRset(name, rrclass, rrtype, ttl));
-            remote_edns_->addRdata(rdata);
-
-            dnssec_ok_ = (((ttl.getValue() & EXTFLAG_MASK) & EXTFLAG_DO) != 0);
-            if (rrclass.getCode() > Message::DEFAULT_MAX_UDPSIZE) {
-                udpsize_ = rrclass.getCode();
-            }
-            rcode_ = Rcode(((ttl.getValue() & EXTRCODE_MASK) >> 20) |
-                           rcode_.getCode());
-            continue;
+            ++added;
         }
-
-        vector<RRsetPtr>::iterator it =
-            find_if(rrsets_[sectionCodeToId(section)].begin(),
-                    rrsets_[sectionCodeToId(section)].end(),
-                    MatchRR(name, rrtype, rrclass));
-        if (it != rrsets_[sectionCodeToId(section)].end()) {
-            (*it)->setTTL(min((*it)->getTTL(), ttl));
-            (*it)->addRdata(rdata);
-        } else {
-            RRsetPtr rrset = RRsetPtr(new RRset(name, rrclass, rrtype, ttl)); 
-            rrset->addRdata(rdata);
-            rrsets_[sectionCodeToId(section)].push_back(rrset);
-        }
-        ++added;
     }
 
     return (added);
@@ -755,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()))
@@ -786,30 +666,14 @@
         lexical_cast<string>(impl_->counts_[Section::AUTHORITY().getCode()]);
 
     unsigned int arcount = impl_->counts_[Section::ADDITIONAL().getCode()];
-    RRsetPtr edns_rrset;
-    if (!getHeaderFlag(MessageFlag::QR()) && impl_->remote_edns_ != NULL) {
-        edns_rrset = impl_->remote_edns_;
+    if (impl_->edns_ != NULL) {
         ++arcount;
     }
     s += ", ADDITIONAL: " + lexical_cast<string>(arcount) + "\n";
 
-    if (edns_rrset != NULL) {
+    if (impl_->edns_ != NULL) {
         s += "\n;; OPT PSEUDOSECTION:\n";
-        s += "; EDNS: version: ";
-        s += lexical_cast<string>(
-            (edns_rrset->getTTL().getValue() & 0x00ff0000) >> 16);
-        s += ", flags:";
-        if ((edns_rrset->getTTL().getValue() & 0x8000) != 0) {
-            s += " do";
-        }
-        const uint32_t mbz = edns_rrset->getTTL().getValue() & ~0x8000 & 0xffff;
-        if (mbz != 0) {
-            s += "; MBZ: " + lexical_cast<string>(mbz) + ", udp: ";
-        } else {
-            s += "; udp: " +
-                lexical_cast<string>(edns_rrset->getClass().getCode());
-        }
-        s += "\n";
+        s += impl_->edns_->toText();
     }
 
     if (!impl_->questions_.empty()) {
@@ -851,8 +715,7 @@
 }
 
 void
-Message::makeResponse()
-{
+Message::makeResponse() {
     if (impl_->mode_ != Message::PARSE) {
         isc_throw(InvalidMessageOperation,
                   "makeResponse() is performed in non-parse mode");
@@ -860,11 +723,7 @@
 
     impl_->mode_ = Message::RENDER;
 
-    impl_->dnssec_ok_ = false;
-    impl_->remote_udpsize_ = impl_->udpsize_;
-    impl_->local_edns_ = RRsetPtr();
-    impl_->udpsize_ = DEFAULT_MAX_UDPSIZE;
-
+    impl_->edns_ = EDNSPtr();
     impl_->flags_ &= MESSAGE_REPLYPRESERVE;
     setHeaderFlag(MessageFlag::QR());
 
@@ -1005,16 +864,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/trac292/src/lib/dns/message.h
==============================================================================
--- branches/trac292/src/lib/dns/message.h (original)
+++ branches/trac292/src/lib/dns/message.h Mon Oct 18 10:46:07 2010
@@ -25,6 +25,7 @@
 
 #include <exceptions/exceptions.h>
 
+#include <dns/edns.h>
 #include <dns/question.h>
 #include <dns/rrset.h>
 
@@ -81,6 +82,8 @@
 class MessageRenderer;
 class Message;
 class MessageImpl;
+class Opcode;
+class Rcode;
 
 template <typename T>
 struct SectionIteratorImpl;
@@ -111,356 +114,45 @@
 };
 
 inline const MessageFlag&
-MessageFlag::QR()
-{
+MessageFlag::QR() {
     static MessageFlag f(0x8000);
     return (f);
 }
 
 inline const MessageFlag&
-MessageFlag::AA()
-{
+MessageFlag::AA() {
     static MessageFlag f(0x0400);
     return (f);
 }
 
 inline const MessageFlag&
-MessageFlag::TC()
-{
+MessageFlag::TC() {
     static MessageFlag f(0x0200);
     return (f);
 }
 
 inline const MessageFlag&
-MessageFlag::RD()
-{
+MessageFlag::RD() {
     static MessageFlag f(0x0100);
     return (f);
 }
 
 inline const MessageFlag&
-MessageFlag::RA()
-{
+MessageFlag::RA() {
     static MessageFlag f(0x0080);
     return (f);
 }
 
 inline const MessageFlag&
-MessageFlag::AD()
-{
+MessageFlag::AD() {
     static MessageFlag f(0x0020);
     return (f);
 }
 
 inline const MessageFlag&
-MessageFlag::CD()
-{
+MessageFlag::CD() {
     static MessageFlag f(0x0010);
     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(uint16_t code);
-    uint16_t getCode() const { return (code_); }
-    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
@@ -500,29 +192,25 @@
 };
 
 inline const Section&
-Section::QUESTION()
-{
+Section::QUESTION() {
     static Section s(SECTION_QUESTION);
     return (s);
 }
 
 inline const Section&
-Section::ANSWER()
-{
+Section::ANSWER() {
     static Section s(SECTION_ANSWER);
     return (s);
 }
 
 inline const Section&
-Section::AUTHORITY()
-{
+Section::AUTHORITY() {
     static Section s(SECTION_AUTHORITY);
     return (s);
 }
 
 inline const Section&
-Section::ADDITIONAL()
-{
+Section::ADDITIONAL() {
     static Section s(SECTION_ADDITIONAL);
     return (s);
 }
@@ -627,45 +315,6 @@
     /// \c setHeaderFlag() with an additional argument.
     void clearHeaderFlag(const MessageFlag& flag);
 
-    /// \brief Return whether the message sender indicates DNSSEC is supported.
-    /// If EDNS is included, this corresponds to the value of the DO bit.
-    /// Otherwise, DNSSEC is considered not supported.
-    bool isDNSSECSupported() const;
-
-    /// \brief Specify whether DNSSEC is supported in the message.
-    ///
-    /// Only allowed in the \c RENDER mode.
-    /// If EDNS is included in the message, the DO bit is set or cleared
-    /// according to the specified value of this method.
-    void setDNSSECSupported(bool on);
-
-    /// \brief Return the maximum buffer size of UDP messages for the sender
-    /// of the message.
-    ///
-    /// The semantics of this value is different based on the mode:
-    /// In the \c PARSE mode, it means the buffer size of the remote node;
-    /// in the \c RENDER mode, it means the buffer size of the local node.
-    ///
-    /// In either case, its value is the value of the UDP payload size field
-    /// of EDNS (when it's included) or \c DEFAULT_MAX_UDPSIZE.
-    ///
-    /// Note: this interface may be confusing and may have to be revisited.
-    uint16_t getUDPSize() const;
-
-    /// \brief Specify the maximum buffer size of UDP messages of the local
-    /// node.
-    ///
-    /// Only allowed in the \c RENDER mode.
-    /// If EDNS OPT RR is included in the message, its UDP payload size field
-    /// will be set to the specified value.
-    ///
-    /// Unless explicitly specified, \c DEFAULT_MAX_UDPSIZE will be assumed
-    /// for the maximum buffer size, regardless of whether EDNS OPT RR is
-    /// included or not.  This means if an application wants to send a message
-    /// with an EDNS OPT RR for specifying a larger UDP size, it must explicitly
-    /// specify the value using this method.
-    void setUDPSize(uint16_t size);
-
     /// \brief Return the query ID given in the header section of the message.
     qid_t getQid() const;
 
@@ -680,22 +329,50 @@
     /// 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 Return the Response Code of the message.
-    ///
-    /// Only allowed in the \c RENDER mode.
+    /// \brief Set the Response Code of the message.
+    ///
+    /// Only allowed in the \c RENDER mode.
+    ///
     /// If the specified code is an EDNS extended RCODE, an EDNS OPT RR will be
     /// included in the message.
     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.
     ///
     /// Only allowed in the \c RENDER mode.
     void setOpcode(const Opcode& opcode);
+
+    /// \brief Return, if any, the EDNS associated with the message.
+    ///
+    /// This method never throws an exception.
+    ///
+    /// \return A shared pointer to the EDNS.  This will be a null shared
+    /// pointer if the message is not associated with EDNS.
+    ConstEDNSPtr getEDNS() const;
+
+    /// \brief Set EDNS for the message.
+    ///
+    /// Only allowed in the \c RENDER mode; otherwise an exception of class
+    /// \c InvalidMessageOperation will be thrown.
+    ///
+    /// \param edns A shared pointer to an \c EDNS object to be set in
+    /// \c Message.
+    void setEDNS(ConstEDNSPtr edns);
 
     /// \brief Returns the number of RRs contained in the given section.
     unsigned int getRRCount(const Section& section) const;
@@ -768,10 +445,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.
@@ -798,8 +484,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/trac292/src/lib/dns/name.h
==============================================================================
--- branches/trac292/src/lib/dns/name.h (original)
+++ branches/trac292/src/lib/dns/name.h Mon Oct 18 10:46:07 2010
@@ -143,8 +143,8 @@
     ///
     /// This constructor simply initializes the object in the straightforward
     /// way.
-    explicit NameComparisonResult(int order, unsigned int nlabels,
-                                  NameRelation relation) :
+    NameComparisonResult(int order, unsigned int nlabels,
+                         NameRelation relation) :
         order_(order), nlabels_(nlabels), relation_(relation) {}
     //@}
 

Modified: branches/trac292/src/lib/dns/python/Makefile.am
==============================================================================
--- branches/trac292/src/lib/dns/python/Makefile.am (original)
+++ branches/trac292/src/lib/dns/python/Makefile.am Mon Oct 18 10:46:07 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CXXFLAGS = $(B10_CXXFLAGS)
@@ -11,10 +11,13 @@
 # directly included from source files, so these don't have their own
 # rules
 EXTRA_DIST = pydnspp_common.h
+EXTRA_DIST += edns_python.cc
 EXTRA_DIST += messagerenderer_python.cc
 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/trac292/src/lib/dns/python/message_python.cc
==============================================================================
--- branches/trac292/src/lib/dns/python/message_python.cc (original)
+++ branches/trac292/src/lib/dns/python/message_python.cc Mon Oct 18 10:46:07 2010
@@ -26,7 +26,6 @@
 static PyObject* po_InvalidMessageSection;
 static PyObject* po_InvalidMessageOperation;
 static PyObject* po_InvalidMessageUDPSize;
-static PyObject* po_DNSMessageBADVERS;
 
 //
 // Definition of the classes
@@ -120,7 +119,6 @@
     0                                   // tp_version_tag
 };
 
-
 static int
 MessageFlag_init(s_MessageFlag* self UNUSED_PARAM,
                  PyObject* args UNUSED_PARAM)
@@ -190,585 +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_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" },
-    { "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_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
@@ -973,16 +392,14 @@
 static PyObject* Message_getHeaderFlag(s_Message* self, PyObject* args);
 static PyObject* Message_setHeaderFlag(s_Message* self, PyObject* args);
 static PyObject* Message_clearHeaderFlag(s_Message* self, PyObject* args);
-static PyObject* Message_isDNSSECSupported(s_Message* self);
-static PyObject* Message_setDNSSECSupported(s_Message* self, PyObject* args);
-static PyObject* Message_getUDPSize(s_Message* self);
-static PyObject* Message_setUDPSize(s_Message* self, PyObject* args);
 static PyObject* Message_getQid(s_Message* self);
 static PyObject* Message_setQid(s_Message* self, PyObject* args);
 static PyObject* Message_getRcode(s_Message* self);
 static PyObject* Message_setRcode(s_Message* self, PyObject* args);
 static PyObject* Message_getOpcode(s_Message* self);
 static PyObject* Message_setOpcode(s_Message* self, PyObject* args);
+static PyObject* Message_getEDNS(s_Message* self);
+static PyObject* Message_setEDNS(s_Message* self, PyObject* args);
 static PyObject* Message_getRRCount(s_Message* self, PyObject* args);
 // use direct iterators for these? (or simply lists for now?)
 static PyObject* Message_getQuestion(s_Message* self);
@@ -1019,35 +436,6 @@
       "Sets the specified header flag bit to 0. The message must be in "
       "RENDER mode. If not, an InvalidMessageOperation is raised. "
       "Takes a MessageFlag object as the only argument." },
-    { "is_dnssec_supported", reinterpret_cast<PyCFunction>(Message_isDNSSECSupported), METH_NOARGS,
-      "Returns True if the message sender indicates DNSSEC is supported. "
-      "If EDNS is included, this corresponds to the value of the DO bit. "
-      "Otherwise, DNSSEC is considered not supported." },
-    { "set_dnssec_supported", reinterpret_cast<PyCFunction>(Message_setDNSSECSupported), METH_VARARGS,
-      "Specify whether DNSSEC is supported in the message. "
-      "The message must be in RENDER mode. If not, an "
-      "InvalidMessageOperation is raised."
-      "If EDNS is included in the message, the DO bit is set or cleared "
-      "according to given argument (True or False) of this method."},
-    { "get_udp_size", reinterpret_cast<PyCFunction>(Message_getUDPSize), METH_NOARGS,
-      "Return the maximum buffer size of UDP messages for the sender "
-      "of the message.\n\n"
-      "The semantics of this value is different based on the mode:\n"
-      "In the PARSE mode, it means the buffer size of the remote node;\n"
-      "in the RENDER mode, it means the buffer size of the local node.\n\n"
-      "In either case, its value is the value of the UDP payload size field "
-      "of EDNS (when it's included) or DEFAULT_MAX_UDPSIZE." },
-    { "set_udp_size", reinterpret_cast<PyCFunction>(Message_setUDPSize), METH_VARARGS,
-      "Specify the maximum buffer size of UDP messages of the local "
-      "node. If the message is not in RENDER mode, an "
-      "InvalidMessageOperation is raised.\n\n"
-      "If EDNS OPT RR is included in the message, its UDP payload size field "
-      "will be set to the specified value.\n"
-      "Unless explicitly specified, DEFAULT_MAX_UDPSIZE will be assumed "
-      "for the maximum buffer size, regardless of whether EDNS OPT RR is "
-      "included or not.  This means if an application wants to send a message "
-      "with an EDNS OPT RR for specifying a larger UDP size, it must explicitly "
-      "specify the value using this method. "},
     { "get_qid", reinterpret_cast<PyCFunction>(Message_getQid), METH_NOARGS,
       "Returns the query id" },
     { "set_qid", reinterpret_cast<PyCFunction>(Message_setQid), METH_VARARGS,
@@ -1066,6 +454,12 @@
       "Sets the message opcode (an Opcode object).\n"
       "If the message is not in RENDER mode, an "
       "InvalidMessageOperation is raised."},
+    { "get_edns", reinterpret_cast<PyCFunction>(Message_getEDNS), METH_NOARGS,
+      "Return, if any, the EDNS associated with the message."
+    },
+    { "set_edns", reinterpret_cast<PyCFunction>(Message_setEDNS), METH_VARARGS,
+      "Set EDNS for the message."
+    },
     { "get_rr_count", reinterpret_cast<PyCFunction>(Message_getRRCount), METH_VARARGS,
       "Returns the number of RRs contained in the given section." },
     { "get_question", reinterpret_cast<PyCFunction>(Message_getQuestion), METH_NOARGS,
@@ -1248,57 +642,6 @@
 }
 
 static PyObject*
-Message_isDNSSECSupported(s_Message* self) {
-    if (self->message->isDNSSECSupported()) {
-        Py_RETURN_TRUE;
-    } else {
-        Py_RETURN_FALSE;
-    }
-}
-
-static PyObject*
-Message_setDNSSECSupported(s_Message* self, PyObject* args) {
-    PyObject *b;
-    if (!PyArg_ParseTuple(args, "O!", &PyBool_Type, &b)) {
-        return (NULL);
-    }
-    try {
-        if (b == Py_True) {
-            self->message->setDNSSECSupported(true);
-        } else {
-            self->message->setDNSSECSupported(false);
-        }
-        Py_RETURN_NONE;
-    } catch (const InvalidMessageOperation& imo) {
-        PyErr_SetString(po_InvalidMessageOperation, imo.what());
-        return (NULL);
-    }
-}
-
-static PyObject*
-Message_getUDPSize(s_Message* self) {
-    return (Py_BuildValue("I", self->message->getUDPSize()));
-}
-
-static PyObject*
-Message_setUDPSize(s_Message* self, PyObject* args) {
-    uint16_t size;
-    if (!PyArg_ParseTuple(args, "H", &size)) {
-        return (NULL);
-    }
-    try {
-        self->message->setUDPSize(size);
-        Py_RETURN_NONE;
-    } catch (const InvalidMessageUDPSize& imus) {
-        PyErr_SetString(po_InvalidMessageUDPSize, imus.what());
-        return (NULL);
-    } catch (const InvalidMessageOperation& imo) {
-        PyErr_SetString(po_InvalidMessageOperation, imo.what());
-        return (NULL);
-    }
-}
-
-static PyObject*
 Message_getQid(s_Message* self) {
     return (Py_BuildValue("I", self->message->getQid()));
 }
@@ -1324,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);
@@ -1356,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);
@@ -1378,6 +730,41 @@
     }
     try {
         self->message->setOpcode(*opcode->opcode);
+        Py_RETURN_NONE;
+    } catch (const InvalidMessageOperation& imo) {
+        PyErr_SetString(po_InvalidMessageOperation, imo.what());
+        return (NULL);
+    }
+}
+
+static PyObject*
+Message_getEDNS(s_Message* self) {
+    s_EDNS* edns;
+    EDNS* edns_body;
+    ConstEDNSPtr src = self->message->getEDNS();
+
+    if (!src) {
+        Py_RETURN_NONE;
+    }
+    if ((edns_body = new(nothrow) EDNS(*src)) == NULL) {
+        return (PyErr_NoMemory());
+    }
+    edns = static_cast<s_EDNS*>(opcode_type.tp_alloc(&edns_type, 0));
+    if (edns != NULL) {
+        edns->edns = edns_body;
+    }
+
+    return (edns);
+}
+
+static PyObject*
+Message_setEDNS(s_Message* self, PyObject* args) {
+    s_EDNS* edns;
+    if (!PyArg_ParseTuple(args, "O!", &edns_type, &edns)) {
+        return (NULL);
+    }
+    try {
+        self->message->setEDNS(EDNSPtr(new EDNS(*edns->edns)));
         Py_RETURN_NONE;
     } catch (const InvalidMessageOperation& imo) {
         PyErr_SetString(po_InvalidMessageOperation, imo.what());
@@ -1520,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*
@@ -1535,7 +931,7 @@
 Message_toWire(s_Message* self, PyObject* args) {
     s_MessageRenderer* mr;
     
-    if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+    if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
         try {
             self->message->toWire(*mr->messagerenderer);
             // If we return NULL it is seen as an error, so use this for

Modified: branches/trac292/src/lib/dns/python/messagerenderer_python.cc
==============================================================================
--- branches/trac292/src/lib/dns/python/messagerenderer_python.cc (original)
+++ branches/trac292/src/lib/dns/python/messagerenderer_python.cc Mon Oct 18 10:46:07 2010
@@ -42,7 +42,7 @@
 // TODO: set/get compressmode
 static PyObject* MessageRenderer_setTruncated(s_MessageRenderer* self);
 static PyObject* MessageRenderer_setLengthLimit(s_MessageRenderer* self, PyObject* args);
-
+static PyObject* MessageRenderer_clear(s_MessageRenderer* self);
 
 static PyMethodDef MessageRenderer_methods[] = {
     { "get_data", reinterpret_cast<PyCFunction>(MessageRenderer_getData), METH_NOARGS,
@@ -57,6 +57,9 @@
       "Sets truncated to true" },
     { "set_length_limit", reinterpret_cast<PyCFunction>(MessageRenderer_setLengthLimit), METH_VARARGS,
       "Sets the length limit of the data to the given number" },
+    { "clear", reinterpret_cast<PyCFunction>(MessageRenderer_clear),
+      METH_NOARGS,
+      "Clear the internal buffer and other internal resources." },
     { NULL, NULL, 0, NULL }
 };
 
@@ -175,6 +178,12 @@
     Py_RETURN_NONE;
 }
 
+static PyObject*
+MessageRenderer_clear(s_MessageRenderer* self) {
+    self->messagerenderer->clear();
+    Py_RETURN_NONE;
+}
+
 // end of MessageRenderer
 
 

Modified: branches/trac292/src/lib/dns/python/name_python.cc
==============================================================================
--- branches/trac292/src/lib/dns/python/name_python.cc (original)
+++ branches/trac292/src/lib/dns/python/name_python.cc Mon Oct 18 10:46:07 2010
@@ -421,7 +421,7 @@
         // to prevent memory leak
         Py_DECREF(name_bytes);
         return (result);
-    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
         self->name->toWire(*mr->messagerenderer);
         // If we return NULL it is seen as an error, so use this for
         // None returns
@@ -437,7 +437,7 @@
 Name_compare(s_Name* self, PyObject* args) {
     s_Name* other;
 
-    if (!PyArg_ParseTuple(args, "O!", &name_type, (PyObject* *) &other))
+    if (!PyArg_ParseTuple(args, "O!", &name_type, &other))
         return (NULL);
 
     s_NameComparisonResult* ret = PyObject_New(s_NameComparisonResult, &name_comparison_result_type);
@@ -452,7 +452,7 @@
 Name_equals(s_Name* self, PyObject* args) {
     s_Name* other;
 
-    if (!PyArg_ParseTuple(args, "O!", &name_type, (PyObject* *) &other))
+    if (!PyArg_ParseTuple(args, "O!", &name_type, &other))
         return (NULL);
 
     if (self->name->equals(*other->name))
@@ -565,7 +565,7 @@
 Name_concatenate(s_Name* self, PyObject* args) {
     s_Name* other;
 
-    if (!PyArg_ParseTuple(args, "O!", &name_type, (PyObject**) &other))
+    if (!PyArg_ParseTuple(args, "O!", &name_type, &other))
         return (NULL);
 
     s_Name* ret = PyObject_New(s_Name, &name_type);

Modified: branches/trac292/src/lib/dns/python/pydnspp.cc
==============================================================================
--- branches/trac292/src/lib/dns/python/pydnspp.cc (original)
+++ branches/trac292/src/lib/dns/python/pydnspp.cc Mon Oct 18 10:46:07 2010
@@ -40,8 +40,12 @@
 
 #include <dns/python/pydnspp_common.h>
 
-// For our 'general' isc::Exception
+// For our 'general' isc::Exceptions
 static PyObject* po_IscException;
+static PyObject* po_InvalidParameter;
+
+// For our own isc::dns::Exception
+static PyObject* po_DNSMessageBADVERS;
 
 // order is important here!
 #include <dns/python/messagerenderer_python.cc>
@@ -53,6 +57,9 @@
 #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
 
 //
@@ -81,8 +88,13 @@
         return (NULL);
     }
 
+    // Add the exceptions to the class
     po_IscException = PyErr_NewException("pydnspp.IscException", NULL, NULL);
     PyModule_AddObject(mod, "IscException", po_IscException);
+
+    po_InvalidParameter = PyErr_NewException("pydnspp.InvalidParameter",
+                                             NULL, NULL);
+    PyModule_AddObject(mod, "InvalidParameter", po_InvalidParameter);
 
     // for each part included above, we call its specific initializer
 
@@ -118,7 +130,19 @@
         return (NULL);
     }
 
+    if (!initModulePart_Opcode(mod)) {
+        return (NULL);
+    }
+
+    if (!initModulePart_Rcode(mod)) {
+        return (NULL);
+    }
+
     if (!initModulePart_Message(mod)) {
+        return (NULL);
+    }
+
+    if (!initModulePart_EDNS(mod)) {
         return (NULL);
     }
 

Modified: branches/trac292/src/lib/dns/python/question_python.cc
==============================================================================
--- branches/trac292/src/lib/dns/python/question_python.cc (original)
+++ branches/trac292/src/lib/dns/python/question_python.cc Mon Oct 18 10:46:07 2010
@@ -254,8 +254,7 @@
         // to prevent memory leak
         Py_DECREF(n);
         return (result);
-    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type,
-                                reinterpret_cast<PyObject**>(&mr))) {
+    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
         self->question->toWire(*mr->messagerenderer);
         // If we return NULL it is seen as an error, so use this for
         // None returns

Modified: branches/trac292/src/lib/dns/python/rdata_python.cc
==============================================================================
--- branches/trac292/src/lib/dns/python/rdata_python.cc (original)
+++ branches/trac292/src/lib/dns/python/rdata_python.cc Mon Oct 18 10:46:07 2010
@@ -146,11 +146,20 @@
     s_RRType* rrtype;
     s_RRClass* rrclass;
     const char* s;
-    
+    const char* data;
+    Py_ssize_t len;
+
+    // Create from string
     if (PyArg_ParseTuple(args, "O!O!s", &rrtype_type, &rrtype,
                                         &rrclass_type, &rrclass,
                                         &s)) {
         self->rdata = createRdata(*rrtype->rrtype, *rrclass->rrclass, s);
+        return (0);
+    } else if (PyArg_ParseTuple(args, "O!O!y#", &rrtype_type, &rrtype,
+                                &rrclass_type, &rrclass, &data, &len)) {
+        InputBuffer input_buffer(data, len);
+        self->rdata = createRdata(*rrtype->rrtype, *rrclass->rrclass,
+                                  input_buffer, len);
         return (0);
     }
 
@@ -195,7 +204,7 @@
         // to prevent memory leak
         Py_DECREF(rd_bytes);
         return (result);
-    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
         self->rdata->toWire(*mr->messagerenderer);
         // If we return NULL it is seen as an error, so use this for
         // None returns

Modified: branches/trac292/src/lib/dns/python/rrclass_python.cc
==============================================================================
--- branches/trac292/src/lib/dns/python/rrclass_python.cc (original)
+++ branches/trac292/src/lib/dns/python/rrclass_python.cc Mon Oct 18 10:46:07 2010
@@ -236,7 +236,7 @@
         // to prevent memory leak
         Py_DECREF(n);
         return (result);
-    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
         self->rrclass->toWire(*mr->messagerenderer);
         // If we return NULL it is seen as an error, so use this for
         // None returns

Modified: branches/trac292/src/lib/dns/python/rrset_python.cc
==============================================================================
--- branches/trac292/src/lib/dns/python/rrset_python.cc (original)
+++ branches/trac292/src/lib/dns/python/rrset_python.cc Mon Oct 18 10:46:07 2010
@@ -315,7 +315,7 @@
             // to prevent memory leak
             Py_DECREF(n);
             return (result);
-        } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+        } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
             self->rrset->toWire(*mr->messagerenderer);
             // If we return NULL it is seen as an error, so use this for
             // None returns

Modified: branches/trac292/src/lib/dns/python/rrttl_python.cc
==============================================================================
--- branches/trac292/src/lib/dns/python/rrttl_python.cc (original)
+++ branches/trac292/src/lib/dns/python/rrttl_python.cc Mon Oct 18 10:46:07 2010
@@ -235,7 +235,7 @@
         // to prevent memory leak
         Py_DECREF(n);
         return (result);
-    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
         self->rrttl->toWire(*mr->messagerenderer);
         // If we return NULL it is seen as an error, so use this for
         // None returns

Modified: branches/trac292/src/lib/dns/python/rrtype_python.cc
==============================================================================
--- branches/trac292/src/lib/dns/python/rrtype_python.cc (original)
+++ branches/trac292/src/lib/dns/python/rrtype_python.cc Mon Oct 18 10:46:07 2010
@@ -273,7 +273,7 @@
         // to prevent memory leak
         Py_DECREF(n);
         return (result);
-    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
         self->rrtype->toWire(*mr->messagerenderer);
         // If we return NULL it is seen as an error, so use this for
         // None returns

Modified: branches/trac292/src/lib/dns/python/tests/Makefile.am
==============================================================================
--- branches/trac292/src/lib/dns/python/tests/Makefile.am (original)
+++ branches/trac292/src/lib/dns/python/tests/Makefile.am Mon Oct 18 10:46:07 2010
@@ -1,7 +1,10 @@
-PYTESTS = message_python_test.py
+PYTESTS = edns_python_test.py
+PYTESTS += message_python_test.py
 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
@@ -9,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.
@@ -23,8 +27,8 @@
 check-local:
 	for pytest in $(PYTESTS) ; do \
 	echo Running test: $$pytest ; \
-	env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/lib/dns/python/.libs \
-	TESTDATA_PATH=$(abs_top_srcdir)/src/lib/dns/tests/testdata \
+	env PYTHONPATH=$(abs_top_srcdir)/src/lib/dns/.libs:$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/lib/dns/python/.libs \
+	TESTDATA_PATH=$(abs_top_srcdir)/src/lib/dns/tests/testdata:$(abs_top_builddir)/src/lib/dns/tests/testdata \
 	$(LIBRARY_PATH_PLACEHOLDER) \
 	$(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
 	done

Modified: branches/trac292/src/lib/dns/python/tests/message_python_test.py
==============================================================================
--- branches/trac292/src/lib/dns/python/tests/message_python_test.py (original)
+++ branches/trac292/src/lib/dns/python/tests/message_python_test.py Mon Oct 18 10:46:07 2010
@@ -20,7 +20,7 @@
 import unittest
 import os
 from pydnspp import *
-
+from testutil import *
 
 class MessageFlagTest(unittest.TestCase):
     def test_init(self):
@@ -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):
 
@@ -240,19 +83,6 @@
 else:
     testdata_path = "../tests/testdata"
 
-def read_wire_data(filename):
-    data = bytes()
-    file = open(testdata_path + os.sep + filename, "r")
-    for line in file:
-        line = line.strip()
-        if line == "" or line.startswith("#"):
-            pass
-        else:
-            cur_data = bytes.fromhex(line)
-            data += cur_data
-
-    return data
-
 def factoryFromFile(message, file):
     data = read_wire_data(file)
     message.from_wire(data)
@@ -316,28 +146,6 @@
         self.assertRaises(InvalidMessageOperation,
                           self.p.clear_header_flag, MessageFlag.AA())
 
-    def test_set_DNSSEC_supported(self):
-        self.assertRaises(TypeError, self.r.set_dnssec_supported, "wrong")
-
-        self.assertFalse(self.r.is_dnssec_supported())
-        self.r.set_dnssec_supported(True)
-        self.assertTrue(self.r.is_dnssec_supported())
-        self.r.set_dnssec_supported(False)
-        self.assertFalse(self.r.is_dnssec_supported())
-
-        self.assertRaises(InvalidMessageOperation,
-                          self.p.set_dnssec_supported, True)
-        self.assertRaises(InvalidMessageOperation,
-                          self.p.set_dnssec_supported, False)
-
-    def test_set_udp_size(self):
-        self.assertRaises(TypeError, self.r.set_udp_size, "wrong")
-        self.assertRaises(InvalidMessageUDPSize, self.r.set_udp_size, 0)
-        self.assertRaises(InvalidMessageUDPSize, self.r.set_udp_size, 65536)
-        self.assertRaises(InvalidMessageOperation, self.p.set_udp_size, 1024)
-        self.r.set_udp_size(2048)
-        self.assertEqual(2048, self.r.get_udp_size())
-
     def test_set_qid(self):
         self.assertRaises(TypeError, self.r.set_qid, "wrong")
         self.assertRaises(InvalidMessageOperation,
@@ -355,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")
@@ -365,6 +174,26 @@
 
         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.wire")
+        edns = message_parse.get_edns()
+        self.assertEqual(0, edns.get_version())
+        self.assertEqual(4096, edns.get_udp_size())
+        self.assertTrue(edns.get_dnssec_awareness())
+
+    def test_set_edns(self):
+        self.assertRaises(InvalidMessageOperation, self.p.set_edns, EDNS())
+
+        edns = EDNS()
+        edns.set_udp_size(1024)
+        self.r.set_edns(edns)
+        self.assertEqual(1024, self.r.get_edns().get_udp_size())
 
     def test_get_section(self):
         self.assertRaises(TypeError, self.r.get_section, "wrong")
@@ -430,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()
         
@@ -446,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)
@@ -487,93 +334,15 @@
         self.assertEqual("192.0.2.2", rdata[1].to_text())
         self.assertEqual(2, len(rdata))
 
-    def test_GetEDNS0DOBit(self):
-        message_parse = Message(Message.PARSE)
-        ## Without EDNS0, DNSSEC is considered to be unsupported.
-        factoryFromFile(message_parse, "message_fromWire1")
-        self.assertFalse(message_parse.is_dnssec_supported())
-    
-        ## If DO bit is on, DNSSEC is considered to be supported.
-        message_parse.clear(Message.PARSE)
-        factoryFromFile(message_parse, "message_fromWire2")
-        self.assertTrue(message_parse.is_dnssec_supported())
-    
-        ## If DO bit is off, DNSSEC is considered to be unsupported.
-        message_parse.clear(Message.PARSE)
-        factoryFromFile(message_parse, "message_fromWire3")
-        self.assertFalse(message_parse.is_dnssec_supported())
-    
-    def test_SetEDNS0DOBit(self):
-        # By default, it's false, and we can enable/disable it.
-        message_parse = Message(Message.PARSE)
-        message_render = Message(Message.RENDER)
-        self.assertFalse(message_render.is_dnssec_supported())
-        message_render.set_dnssec_supported(True)
-        self.assertTrue(message_render.is_dnssec_supported())
-        message_render.set_dnssec_supported(False)
-        self.assertFalse(message_render.is_dnssec_supported())
-    
-        ## A message in the parse mode doesn't allow this flag to be set.
-        self.assertRaises(InvalidMessageOperation,
-                          message_parse.set_dnssec_supported,
-                          True)
-        ## Once converted to the render mode, it works as above
-        message_parse.make_response()
-        self.assertFalse(message_parse.is_dnssec_supported())
-        message_parse.set_dnssec_supported(True)
-        self.assertTrue(message_parse.is_dnssec_supported())
-        message_parse.set_dnssec_supported(False)
-        self.assertFalse(message_parse.is_dnssec_supported())
-    
-    def test_GetEDNS0UDPSize(self):
-        # Without EDNS0, the default max UDP size is used.
-        message_parse = Message(Message.PARSE)
-        factoryFromFile(message_parse, "message_fromWire1")
-        self.assertEqual(Message.DEFAULT_MAX_UDPSIZE, message_parse.get_udp_size())
-    
-        ## If the size specified in EDNS0 > default max, use it.
-        message_parse.clear(Message.PARSE)
-        factoryFromFile(message_parse, "message_fromWire2")
-        self.assertEqual(4096, message_parse.get_udp_size())
-    
-        ## If the size specified in EDNS0 < default max, keep using the default.
-        message_parse.clear(Message.PARSE)
-        factoryFromFile(message_parse, "message_fromWire8")
-        self.assertEqual(Message.DEFAULT_MAX_UDPSIZE, message_parse.get_udp_size())
-    
-    def test_SetEDNS0UDPSize(self):
-        # The default size if unspecified
-        message_render = Message(Message.RENDER)
-        message_parse = Message(Message.PARSE)
-        self.assertEqual(Message.DEFAULT_MAX_UDPSIZE, message_render.get_udp_size())
-        # A common buffer size with EDNS, should succeed
-        message_render.set_udp_size(4096)
-        self.assertEqual(4096, message_render.get_udp_size())
-        # Unusual large value, but accepted
-        message_render.set_udp_size(0xffff)
-        self.assertEqual(0xffff, message_render.get_udp_size())
-        # Too small is value is rejected
-        self.assertRaises(InvalidMessageUDPSize, message_render.set_udp_size, 511)
-    
-        # A message in the parse mode doesn't allow the set operation.
-        self.assertRaises(InvalidMessageOperation, message_parse.set_udp_size, 4096)
-        ## Once converted to the render mode, it works as above.
-        message_parse.make_response()
-        message_parse.set_udp_size(4096)
-        self.assertEqual(4096, message_parse.get_udp_size())
-        message_parse.set_udp_size(0xffff)
-        self.assertEqual(0xffff, message_parse.get_udp_size())
-        self.assertRaises(InvalidMessageUDPSize, message_parse.set_udp_size, 511)
-    
     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/trac292/src/lib/dns/python/tests/messagerenderer_python_test.py
==============================================================================
--- branches/trac292/src/lib/dns/python/tests/messagerenderer_python_test.py (original)
+++ branches/trac292/src/lib/dns/python/tests/messagerenderer_python_test.py Mon Oct 18 10:46:07 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/trac292/src/lib/dns/python/tests/question_python_test.py
==============================================================================
--- branches/trac292/src/lib/dns/python/tests/question_python_test.py (original)
+++ branches/trac292/src/lib/dns/python/tests/question_python_test.py Mon Oct 18 10:46:07 2010
@@ -20,24 +20,12 @@
 import unittest
 import os
 from pydnspp import *
+from testutil import *
 
 if "TESTDATA_PATH" in os.environ:
     testdata_path = os.environ["TESTDATA_PATH"]
 else:
     testdata_path = "../tests/testdata"
-
-def read_wire_data(filename):
-    data = bytes()
-    file = open(testdata_path + os.sep + filename, "r")
-    for line in file:
-        line = line.strip()
-        if line == "" or line.startswith("#"):
-            pass
-        else:
-            cur_data = bytes.fromhex(line)
-            data += cur_data
-
-    return data
 
 def question_from_wire(file, position = 0):
     data = read_wire_data(file)
@@ -102,7 +90,6 @@
         wiredata = read_wire_data("question_toWire2")
         self.assertEqual(renderer.get_data(), wiredata)
         self.assertRaises(TypeError, self.test_question1.to_wire, 1)
-    
 
 if __name__ == '__main__':
     unittest.main()

Modified: branches/trac292/src/lib/dns/question.cc
==============================================================================
--- branches/trac292/src/lib/dns/question.cc (original)
+++ branches/trac292/src/lib/dns/question.cc Mon Oct 18 10:46:07 2010
@@ -42,15 +42,13 @@
 }
 
 string
-Question::toText() const
-{
+Question::toText() const {
     return (name_.toText() + " " + rrclass_.toText() + " " +
             rrtype_.toText() + "\n");
 }
 
 unsigned int
-Question::toWire(OutputBuffer& buffer) const
-{
+Question::toWire(OutputBuffer& buffer) const {
     name_.toWire(buffer);
     rrtype_.toWire(buffer);
     rrclass_.toWire(buffer);    // number of "entries", which is always 1
@@ -59,8 +57,7 @@
 }
 
 unsigned int
-Question::toWire(MessageRenderer& renderer) const
-{
+Question::toWire(MessageRenderer& renderer) const {
     renderer.writeName(name_);
     rrtype_.toWire(renderer);
     rrclass_.toWire(renderer);
@@ -69,8 +66,7 @@
 }
 
 ostream&
-operator<<(std::ostream& os, const Question& question)
-{
+operator<<(std::ostream& os, const Question& question) {
     os << question.toText();
     return (os);
 }

Modified: branches/trac292/src/lib/dns/rdata.cc
==============================================================================
--- branches/trac292/src/lib/dns/rdata.cc (original)
+++ branches/trac292/src/lib/dns/rdata.cc Mon Oct 18 10:46:07 2010
@@ -82,8 +82,7 @@
 }
 
 int
-compareNames(const Name& n1, const Name& n2)
-{
+compareNames(const Name& n1, const Name& n2) {
     size_t len1 = n1.getLength();
     size_t len2 = n2.getLength();
     size_t cmplen = min(len1, len2);
@@ -107,8 +106,7 @@
     vector<uint8_t> data_;
 };
 
-Generic::Generic(InputBuffer& buffer, size_t rdata_len)
-{
+Generic::Generic(InputBuffer& buffer, size_t rdata_len) {
     if (rdata_len > MAX_RDLENGTH) {
         isc_throw(InvalidRdataLength, "RDLENGTH too large");
     }
@@ -119,8 +117,7 @@
     impl_ = new GenericImpl(data);
 }
 
-Generic::Generic(const string& rdata_string)
-{
+Generic::Generic(const string& rdata_string) {
     istringstream iss(rdata_string);
     string unknown_mark;
     iss >> unknown_mark;
@@ -181,8 +178,7 @@
     impl_ = new GenericImpl(data);
 }
 
-Generic::~Generic()
-{
+Generic::~Generic() {
     delete impl_;
 }
 
@@ -191,8 +187,7 @@
 {}
 
 Generic&
-Generic::operator=(const Generic& source)
-{
+Generic::operator=(const Generic& source) {
     if (impl_ == source.impl_) {
         return (*this);
     }
@@ -218,8 +213,7 @@
 }
 
 string
-Generic::toText() const
-{
+Generic::toText() const {
     ostringstream oss;
 
     oss << "\\# " << impl_->data_.size() << " ";
@@ -231,21 +225,18 @@
 }
 
 void
-Generic::toWire(OutputBuffer& buffer) const
-{
+Generic::toWire(OutputBuffer& buffer) const {
     buffer.writeData(&impl_->data_[0], impl_->data_.size());
 }
 
 void
-Generic::toWire(MessageRenderer& renderer) const
-{
+Generic::toWire(MessageRenderer& renderer) const {
     renderer.writeData(&impl_->data_[0], impl_->data_.size());
 }
 
 namespace {
 inline int
-compare_internal(const GenericImpl& lhs, const GenericImpl& rhs)
-{
+compare_internal(const GenericImpl& lhs, const GenericImpl& rhs) {
     size_t this_len = lhs.data_.size();
     size_t other_len = rhs.data_.size();
     size_t len = (this_len < other_len) ? this_len : other_len;
@@ -262,16 +253,14 @@
 }
 
 int
-Generic::compare(const Rdata& other) const
-{
+Generic::compare(const Rdata& other) const {
     const Generic& other_rdata = dynamic_cast<const Generic&>(other);
 
     return (compare_internal(*impl_, *other_rdata.impl_));
 }
 
 std::ostream&
-operator<<(std::ostream& os, const Generic& rdata)
-{
+operator<<(std::ostream& os, const Generic& rdata) {
     return (os << rdata.toText());
 }
 } // end of namespace generic

Modified: branches/trac292/src/lib/dns/rdata/ch_3/a_1.cc
==============================================================================
--- branches/trac292/src/lib/dns/rdata/ch_3/a_1.cc (original)
+++ branches/trac292/src/lib/dns/rdata/ch_3/a_1.cc Mon Oct 18 10:46:07 2010
@@ -30,13 +30,11 @@
 // BEGIN_ISC_NAMESPACE
 // BEGIN_RDATA_NAMESPACE
 
-A::A(const string& addrstr UNUSED_PARAM)
-{
+A::A(const string& addrstr UNUSED_PARAM) {
     // TBD
 }
 
-A::A(InputBuffer& buffer UNUSED_PARAM, size_t rdata_len UNUSED_PARAM)
-{
+A::A(InputBuffer& buffer UNUSED_PARAM, size_t rdata_len UNUSED_PARAM) {
     // TBD
 }
 
@@ -45,27 +43,23 @@
 }
 
 void
-A::toWire(OutputBuffer& buffer UNUSED_PARAM) const
-{
+A::toWire(OutputBuffer& buffer UNUSED_PARAM) const {
     // TBD
 }
 
 void
-A::toWire(MessageRenderer& renderer UNUSED_PARAM) const
-{
+A::toWire(MessageRenderer& renderer UNUSED_PARAM) const {
     // TBD
 }
 
 string
-A::toText() const
-{
+A::toText() const {
     // TBD
     isc_throw(InvalidRdataText, "Not implemented yet");
 }
 
 int
-A::compare(const Rdata& other UNUSED_PARAM) const
-{
+A::compare(const Rdata& other UNUSED_PARAM) const {
     return (0);                 // dummy.  TBD
 }
 

Modified: branches/trac292/src/lib/dns/rdata/generic/cname_5.cc
==============================================================================
--- branches/trac292/src/lib/dns/rdata/generic/cname_5.cc (original)
+++ branches/trac292/src/lib/dns/rdata/generic/cname_5.cc Mon Oct 18 10:46:07 2010
@@ -49,34 +49,29 @@
 {}
 
 void
-CNAME::toWire(OutputBuffer& buffer) const
-{
+CNAME::toWire(OutputBuffer& buffer) const {
     cname_.toWire(buffer);
 }
 
 void
-CNAME::toWire(MessageRenderer& renderer) const
-{
+CNAME::toWire(MessageRenderer& renderer) const {
     renderer.writeName(cname_);
 }
 
 string
-CNAME::toText() const
-{
+CNAME::toText() const {
     return (cname_.toText());
 }
 
 int
-CNAME::compare(const Rdata& other) const
-{
+CNAME::compare(const Rdata& other) const {
     const CNAME& other_cname = dynamic_cast<const CNAME&>(other);
 
     return (compareNames(cname_, other_cname.cname_));
 }
 
 const Name&
-CNAME::getCname() const
-{
+CNAME::getCname() const {
     return (cname_);
 }
 

Modified: branches/trac292/src/lib/dns/rdata/generic/dname_39.cc
==============================================================================
--- branches/trac292/src/lib/dns/rdata/generic/dname_39.cc (original)
+++ branches/trac292/src/lib/dns/rdata/generic/dname_39.cc Mon Oct 18 10:46:07 2010
@@ -49,34 +49,29 @@
 {}
 
 void
-DNAME::toWire(OutputBuffer& buffer) const
-{
+DNAME::toWire(OutputBuffer& buffer) const {
     dname_.toWire(buffer);
 }
 
 void
-DNAME::toWire(MessageRenderer& renderer) const
-{
+DNAME::toWire(MessageRenderer& renderer) const {
     renderer.writeName(dname_);
 }
 
 string
-DNAME::toText() const
-{
+DNAME::toText() const {
     return (dname_.toText());
 }
 
 int
-DNAME::compare(const Rdata& other) const
-{
+DNAME::compare(const Rdata& other) const {
     const DNAME& other_dname = dynamic_cast<const DNAME&>(other);
 
     return (compareNames(dname_, other_dname.dname_));
 }
 
 const Name&
-DNAME::getDname() const
-{
+DNAME::getDname() const {
     return (dname_);
 }
 

Modified: branches/trac292/src/lib/dns/rdata/generic/dnskey_48.cc
==============================================================================
--- branches/trac292/src/lib/dns/rdata/generic/dnskey_48.cc (original)
+++ branches/trac292/src/lib/dns/rdata/generic/dnskey_48.cc Mon Oct 18 10:46:07 2010
@@ -103,8 +103,7 @@
 {}
 
 DNSKEY&
-DNSKEY::operator=(const DNSKEY& source)
-{
+DNSKEY::operator=(const DNSKEY& source) {
     if (impl_ == source.impl_) {
         return (*this);
     }
@@ -116,14 +115,12 @@
     return (*this);
 }
 
-DNSKEY::~DNSKEY()
-{
+DNSKEY::~DNSKEY() {
     delete impl_;
 }
 
 string
-DNSKEY::toText() const
-{
+DNSKEY::toText() const {
     return (boost::lexical_cast<string>(static_cast<int>(impl_->flags_)) +
         " " + boost::lexical_cast<string>(static_cast<int>(impl_->protocol_)) +
         " " + boost::lexical_cast<string>(static_cast<int>(impl_->algorithm_)) +
@@ -131,8 +128,7 @@
 }
 
 void
-DNSKEY::toWire(OutputBuffer& buffer) const
-{
+DNSKEY::toWire(OutputBuffer& buffer) const {
     buffer.writeUint16(impl_->flags_);
     buffer.writeUint8(impl_->protocol_);
     buffer.writeUint8(impl_->algorithm_);
@@ -140,8 +136,7 @@
 }
 
 void
-DNSKEY::toWire(MessageRenderer& renderer) const
-{
+DNSKEY::toWire(MessageRenderer& renderer) const {
     renderer.writeUint16(impl_->flags_);
     renderer.writeUint8(impl_->protocol_);
     renderer.writeUint8(impl_->algorithm_);
@@ -149,8 +144,7 @@
 }
 
 int
-DNSKEY::compare(const Rdata& other) const
-{
+DNSKEY::compare(const Rdata& other) const {
     const DNSKEY& other_dnskey = dynamic_cast<const DNSKEY&>(other);
 
     if (impl_->flags_ != other_dnskey.impl_->flags_) {
@@ -176,8 +170,7 @@
 }
 
 uint16_t
-DNSKEY::getTag() const
-{
+DNSKEY::getTag() const {
     if (impl_->algorithm_ == 1) {
         int len = impl_->keydata_.size();
         return ((impl_->keydata_[len - 3] << 8) + impl_->keydata_[len - 2]);

Modified: branches/trac292/src/lib/dns/rdata/generic/ds_43.cc
==============================================================================
--- branches/trac292/src/lib/dns/rdata/generic/ds_43.cc (original)
+++ branches/trac292/src/lib/dns/rdata/generic/ds_43.cc Mon Oct 18 10:46:07 2010
@@ -77,8 +77,7 @@
     impl_ = new DSImpl(tag, algorithm, digest_type, digest);
 }
 
-DS::DS(InputBuffer& buffer, size_t rdata_len)
-{
+DS::DS(InputBuffer& buffer, size_t rdata_len) {
     if (rdata_len < 4) {
         isc_throw(InvalidRdataLength, "DS too short");
     }
@@ -99,8 +98,7 @@
 {}
 
 DS&
-DS::operator=(const DS& source)
-{
+DS::operator=(const DS& source) {
     if (impl_ == source.impl_) {
         return (*this);
     }
@@ -112,14 +110,12 @@
     return (*this);
 }
 
-DS::~DS()
-{
+DS::~DS() {
     delete impl_;
 }
 
 string
-DS::toText() const
-{
+DS::toText() const {
     using namespace boost;
     return (lexical_cast<string>(static_cast<int>(impl_->tag_)) +
         " " + lexical_cast<string>(static_cast<int>(impl_->algorithm_)) +
@@ -128,8 +124,7 @@
 }
 
 void
-DS::toWire(OutputBuffer& buffer) const
-{
+DS::toWire(OutputBuffer& buffer) const {
     buffer.writeUint16(impl_->tag_);
     buffer.writeUint8(impl_->algorithm_);
     buffer.writeUint8(impl_->digest_type_);
@@ -137,8 +132,7 @@
 }
 
 void
-DS::toWire(MessageRenderer& renderer) const
-{
+DS::toWire(MessageRenderer& renderer) const {
     renderer.writeUint16(impl_->tag_);
     renderer.writeUint8(impl_->algorithm_);
     renderer.writeUint8(impl_->digest_type_);
@@ -146,8 +140,7 @@
 }
 
 int
-DS::compare(const Rdata& other) const
-{
+DS::compare(const Rdata& other) const {
     const DS& other_ds = dynamic_cast<const DS&>(other);
 
     if (impl_->tag_ != other_ds.impl_->tag_) {

Modified: branches/trac292/src/lib/dns/rdata/generic/mx_15.cc
==============================================================================
--- branches/trac292/src/lib/dns/rdata/generic/mx_15.cc (original)
+++ branches/trac292/src/lib/dns/rdata/generic/mx_15.cc Mon Oct 18 10:46:07 2010
@@ -67,28 +67,24 @@
 {}
 
 void
-MX::toWire(OutputBuffer& buffer) const
-{
+MX::toWire(OutputBuffer& buffer) const {
     buffer.writeUint16(preference_);
     mxname_.toWire(buffer);
 }
 
 void
-MX::toWire(MessageRenderer& renderer) const
-{
+MX::toWire(MessageRenderer& renderer) const {
     renderer.writeUint16(preference_);
     renderer.writeName(mxname_);
 }
 
 string
-MX::toText() const
-{
+MX::toText() const {
     return (lexical_cast<string>(preference_) + " " + mxname_.toText());
 }
 
 int
-MX::compare(const Rdata& other) const
-{
+MX::compare(const Rdata& other) const {
     const MX& other_mx = dynamic_cast<const MX&>(other);
 
     if (preference_ < other_mx.preference_) {
@@ -101,14 +97,12 @@
 }
 
 const Name&
-MX::getMXName() const
-{
+MX::getMXName() const {
     return (mxname_);
 }
 
 uint16_t
-MX::getMXPref() const
-{
+MX::getMXPref() const {
     return (preference_);
 }
 

Modified: branches/trac292/src/lib/dns/rdata/generic/mx_15.h
==============================================================================
--- branches/trac292/src/lib/dns/rdata/generic/mx_15.h (original)
+++ branches/trac292/src/lib/dns/rdata/generic/mx_15.h Mon Oct 18 10:46:07 2010
@@ -35,7 +35,7 @@
     // BEGIN_COMMON_MEMBERS
     // END_COMMON_MEMBERS
 
-    explicit MX(uint16_t preference, const Name& mxname);
+    MX(uint16_t preference, const Name& mxname);
 
     ///
     /// Specialized methods

Modified: branches/trac292/src/lib/dns/rdata/generic/ns_2.cc
==============================================================================
--- branches/trac292/src/lib/dns/rdata/generic/ns_2.cc (original)
+++ branches/trac292/src/lib/dns/rdata/generic/ns_2.cc Mon Oct 18 10:46:07 2010
@@ -45,34 +45,29 @@
 {}
 
 void
-NS::toWire(OutputBuffer& buffer) const
-{
+NS::toWire(OutputBuffer& buffer) const {
     nsname_.toWire(buffer);
 }
 
 void
-NS::toWire(MessageRenderer& renderer) const
-{
+NS::toWire(MessageRenderer& renderer) const {
     renderer.writeName(nsname_);
 }
 
 string
-NS::toText() const
-{
+NS::toText() const {
     return (nsname_.toText());
 }
 
 int
-NS::compare(const Rdata& other) const
-{
+NS::compare(const Rdata& other) const {
     const NS& other_ns = dynamic_cast<const NS&>(other);
 
     return (compareNames(nsname_, other_ns.nsname_));
 }
 
 const Name&
-NS::getNSName() const
-{
+NS::getNSName() const {
     return (nsname_);
 }
 

Modified: branches/trac292/src/lib/dns/rdata/generic/nsec3_50.cc
==============================================================================
--- branches/trac292/src/lib/dns/rdata/generic/nsec3_50.cc (original)
+++ branches/trac292/src/lib/dns/rdata/generic/nsec3_50.cc Mon Oct 18 10:46:07 2010
@@ -127,8 +127,7 @@
     impl_ = new NSEC3Impl(hashalg, flags, iterations, salt, next, typebits);
 }
 
-NSEC3::NSEC3(InputBuffer& buffer, size_t rdata_len)
-{
+NSEC3::NSEC3(InputBuffer& buffer, size_t rdata_len) {
     if (rdata_len < 5) {
         isc_throw(InvalidRdataLength, "NSEC3 too short");
     }
@@ -189,8 +188,7 @@
 {}
 
 NSEC3&
-NSEC3::operator=(const NSEC3& source)
-{
+NSEC3::operator=(const NSEC3& source) {
     if (impl_ == source.impl_) {
         return (*this);
     }
@@ -202,14 +200,12 @@
     return (*this);
 }
 
-NSEC3::~NSEC3()
-{
+NSEC3::~NSEC3() {
     delete impl_;
 }
 
 string
-NSEC3::toText() const
-{
+NSEC3::toText() const {
     ostringstream s;
     int len = 0;
     for (int i = 0; i < impl_->typebits_.size(); i += len) {
@@ -241,8 +237,7 @@
 }
 
 void
-NSEC3::toWire(OutputBuffer& buffer) const
-{
+NSEC3::toWire(OutputBuffer& buffer) const {
     buffer.writeUint8(impl_->hashalg_);
     buffer.writeUint8(impl_->flags_);
     buffer.writeUint16(impl_->iterations_);
@@ -254,8 +249,7 @@
 }
 
 void
-NSEC3::toWire(MessageRenderer& renderer) const
-{
+NSEC3::toWire(MessageRenderer& renderer) const {
     renderer.writeUint8(impl_->hashalg_);
     renderer.writeUint8(impl_->flags_);
     renderer.writeUint16(impl_->iterations_);
@@ -267,8 +261,7 @@
 }
 
 int
-NSEC3::compare(const Rdata& other) const
-{
+NSEC3::compare(const Rdata& other) const {
     const NSEC3& other_nsec3 = dynamic_cast<const NSEC3&>(other);
 
     if (impl_->hashalg_ != other_nsec3.impl_->hashalg_) {

Modified: branches/trac292/src/lib/dns/rdata/generic/nsec3param_51.cc
==============================================================================
--- branches/trac292/src/lib/dns/rdata/generic/nsec3param_51.cc (original)
+++ branches/trac292/src/lib/dns/rdata/generic/nsec3param_51.cc Mon Oct 18 10:46:07 2010
@@ -73,8 +73,7 @@
     impl_ = new NSEC3PARAMImpl(hashalg, flags, iterations, salt);
 }
 
-NSEC3PARAM::NSEC3PARAM(InputBuffer& buffer, size_t rdata_len)
-{
+NSEC3PARAM::NSEC3PARAM(InputBuffer& buffer, size_t rdata_len) {
     if (rdata_len < 4) {
         isc_throw(InvalidRdataLength, "NSEC3PARAM too short");
     }
@@ -102,8 +101,7 @@
 {}
 
 NSEC3PARAM&
-NSEC3PARAM::operator=(const NSEC3PARAM& source)
-{
+NSEC3PARAM::operator=(const NSEC3PARAM& source) {
     if (impl_ == source.impl_) {
         return (*this);
     }
@@ -115,14 +113,12 @@
     return (*this);
 }
 
-NSEC3PARAM::~NSEC3PARAM()
-{
+NSEC3PARAM::~NSEC3PARAM() {
     delete impl_;
 }
 
 string
-NSEC3PARAM::toText() const
-{
+NSEC3PARAM::toText() const {
     using namespace boost;
     return (lexical_cast<string>(static_cast<int>(impl_->hashalg_)) +
         " " + lexical_cast<string>(static_cast<int>(impl_->flags_)) +
@@ -131,8 +127,7 @@
 }
 
 void
-NSEC3PARAM::toWire(OutputBuffer& buffer) const
-{
+NSEC3PARAM::toWire(OutputBuffer& buffer) const {
     buffer.writeUint8(impl_->hashalg_);
     buffer.writeUint8(impl_->flags_);
     buffer.writeUint16(impl_->iterations_);
@@ -141,8 +136,7 @@
 }
 
 void
-NSEC3PARAM::toWire(MessageRenderer& renderer) const
-{
+NSEC3PARAM::toWire(MessageRenderer& renderer) const {
     renderer.writeUint8(impl_->hashalg_);
     renderer.writeUint8(impl_->flags_);
     renderer.writeUint16(impl_->iterations_);
@@ -151,8 +145,7 @@
 }
 
 int
-NSEC3PARAM::compare(const Rdata& other) const
-{
+NSEC3PARAM::compare(const Rdata& other) const {
     const NSEC3PARAM& other_param = dynamic_cast<const NSEC3PARAM&>(other);
 
     if (impl_->hashalg_ != other_param.impl_->hashalg_) {

Modified: branches/trac292/src/lib/dns/rdata/generic/opt_41.cc
==============================================================================
--- branches/trac292/src/lib/dns/rdata/generic/opt_41.cc (original)
+++ branches/trac292/src/lib/dns/rdata/generic/opt_41.cc Mon Oct 18 10:46:07 2010
@@ -28,13 +28,11 @@
 // BEGIN_ISC_NAMESPACE
 // BEGIN_RDATA_NAMESPACE
 
-OPT::OPT(const string& type_str UNUSED_PARAM)
-{
+OPT::OPT(const string& type_str UNUSED_PARAM) {
     isc_throw(InvalidRdataText, "OPT RR cannot be constructed from text");
 }
 
-OPT::OPT(InputBuffer& buffer, size_t rdata_len)
-{
+OPT::OPT(InputBuffer& buffer, size_t rdata_len) {
     // setPosition() will throw against a short buffer anyway, but it's safer
     // to check it explicitly here.
     if (buffer.getLength() - buffer.getPosition() < rdata_len) {
@@ -45,32 +43,27 @@
     buffer.setPosition(buffer.getPosition() + rdata_len);
 }
 
-OPT::OPT(const OPT& source UNUSED_PARAM) : Rdata()
-{
+OPT::OPT(const OPT& source UNUSED_PARAM) : Rdata() {
     // there's nothing to copy in this simple implementation.
 }
 
 std::string
-OPT::toText() const
-{
+OPT::toText() const {
     return ("");
 }
 
 void
-OPT::toWire(OutputBuffer& buffer UNUSED_PARAM) const
-{
+OPT::toWire(OutputBuffer& buffer UNUSED_PARAM) const {
     // nothing to do, as this simple version doesn't support any options.
 }
 
 void
-OPT::toWire(MessageRenderer& renderer UNUSED_PARAM) const
-{
+OPT::toWire(MessageRenderer& renderer UNUSED_PARAM) const {
     // nothing to do, as this simple version doesn't support any options.
 }
 
 int
-OPT::compare(const Rdata& other) const
-{
+OPT::compare(const Rdata& other) const {
     //const OPT& other_opt = dynamic_cast<const OPT&>(other);
     dynamic_cast<const OPT&>(other); // right now we don't need other_opt
 

Modified: branches/trac292/src/lib/dns/rdata/generic/ptr_12.cc
==============================================================================
--- branches/trac292/src/lib/dns/rdata/generic/ptr_12.cc (original)
+++ branches/trac292/src/lib/dns/rdata/generic/ptr_12.cc Mon Oct 18 10:46:07 2010
@@ -45,26 +45,22 @@
 {}
 
 std::string
-PTR::toText() const
-{
+PTR::toText() const {
     return (ptr_name_.toText());
 }
 
 void
-PTR::toWire(OutputBuffer& buffer) const
-{
+PTR::toWire(OutputBuffer& buffer) const {
     ptr_name_.toWire(buffer);
 }
 
 void
-PTR::toWire(MessageRenderer& renderer) const
-{
+PTR::toWire(MessageRenderer& renderer) const {
     renderer.writeName(ptr_name_);
 }
 
 int
-PTR::compare(const Rdata& other) const
-{
+PTR::compare(const Rdata& other) const {
     // The compare method normally begins with this dynamic cast.
     const PTR& other_ptr = dynamic_cast<const PTR&>(other);
 
@@ -73,8 +69,7 @@
 }
 
 const Name&
-PTR::getPTRName() const
-{
+PTR::getPTRName() const {
     return (ptr_name_);
 }
 

Modified: branches/trac292/src/lib/dns/rdata/generic/rrsig_46.cc
==============================================================================
--- branches/trac292/src/lib/dns/rdata/generic/rrsig_46.cc (original)
+++ branches/trac292/src/lib/dns/rdata/generic/rrsig_46.cc Mon Oct 18 10:46:07 2010
@@ -106,8 +106,7 @@
                           Name(signer_txt), signature);
 }
 
-RRSIG::RRSIG(InputBuffer& buffer, size_t rdata_len)
-{
+RRSIG::RRSIG(InputBuffer& buffer, size_t rdata_len) {
     size_t pos = buffer.getPosition();
 
     if (rdata_len < RRSIG_MINIMUM_LEN) {
@@ -142,8 +141,7 @@
 {}
 
 RRSIG&
-RRSIG::operator=(const RRSIG& source)
-{
+RRSIG::operator=(const RRSIG& source) {
     if (impl_ == source.impl_) {
         return (*this);
     }
@@ -155,14 +153,12 @@
     return (*this);
 }
 
-RRSIG::~RRSIG()
-{
+RRSIG::~RRSIG() {
     delete impl_;
 }
 
 string
-RRSIG::toText() const
-{
+RRSIG::toText() const {
     string expire = timeToText(impl_->timeexpire_);
     string inception = timeToText(impl_->timeinception_);
 
@@ -178,8 +174,7 @@
 }
 
 void
-RRSIG::toWire(OutputBuffer& buffer) const
-{
+RRSIG::toWire(OutputBuffer& buffer) const {
     impl_->covered_.toWire(buffer);
     buffer.writeUint8(impl_->algorithm_);
     buffer.writeUint8(impl_->labels_);
@@ -192,8 +187,7 @@
 }
 
 void
-RRSIG::toWire(MessageRenderer& renderer) const
-{
+RRSIG::toWire(MessageRenderer& renderer) const {
     impl_->covered_.toWire(renderer);
     renderer.writeUint8(impl_->algorithm_);
     renderer.writeUint8(impl_->labels_);
@@ -206,8 +200,7 @@
 }
 
 int
-RRSIG::compare(const Rdata& other) const
-{
+RRSIG::compare(const Rdata& other) const {
     const RRSIG& other_rrsig = dynamic_cast<const RRSIG&>(other);
 
     if (impl_->covered_.getCode() != other_rrsig.impl_->covered_.getCode()) {

Modified: branches/trac292/src/lib/dns/rdata/generic/soa_6.cc
==============================================================================
--- branches/trac292/src/lib/dns/rdata/generic/soa_6.cc (original)
+++ branches/trac292/src/lib/dns/rdata/generic/soa_6.cc Mon Oct 18 10:46:07 2010
@@ -94,24 +94,21 @@
 }
 
 void
-SOA::toWire(OutputBuffer& buffer) const
-{
+SOA::toWire(OutputBuffer& buffer) const {
     mname_.toWire(buffer);
     rname_.toWire(buffer);
     buffer.writeData(numdata_, sizeof(numdata_));
 }
 
 void
-SOA::toWire(MessageRenderer& renderer) const
-{
+SOA::toWire(MessageRenderer& renderer) const {
     renderer.writeName(mname_);
     renderer.writeName(rname_);
     renderer.writeData(numdata_, sizeof(numdata_));
 }
 
 string
-SOA::toText() const
-{
+SOA::toText() const {
     InputBuffer b(numdata_, sizeof(numdata_));
     uint32_t serial = b.readUint32();
     uint32_t refresh = b.readUint32();
@@ -128,8 +125,7 @@
 }
 
 int
-SOA::compare(const Rdata& other) const
-{
+SOA::compare(const Rdata& other) const {
     const SOA& other_soa = dynamic_cast<const SOA&>(other);
 
     int order = compareNames(mname_, other_soa.mname_);

Modified: branches/trac292/src/lib/dns/rdata/generic/soa_6.h
==============================================================================
--- branches/trac292/src/lib/dns/rdata/generic/soa_6.h (original)
+++ branches/trac292/src/lib/dns/rdata/generic/soa_6.h Mon Oct 18 10:46:07 2010
@@ -33,9 +33,9 @@
     // BEGIN_COMMON_MEMBERS
     // END_COMMON_MEMBERS
 
-    explicit SOA(const Name& mname, const Name& rname, uint32_t serial,
-                 uint32_t refresh, uint32_t retry, uint32_t expire,
-                 uint32_t minimum);
+    SOA(const Name& mname, const Name& rname, uint32_t serial,
+        uint32_t refresh, uint32_t retry, uint32_t expire,
+        uint32_t minimum);
 private:
     /// Note: this is a prototype version; we may reconsider
     /// this representation later.

Modified: branches/trac292/src/lib/dns/rdata/hs_4/a_1.cc
==============================================================================
--- branches/trac292/src/lib/dns/rdata/hs_4/a_1.cc (original)
+++ branches/trac292/src/lib/dns/rdata/hs_4/a_1.cc Mon Oct 18 10:46:07 2010
@@ -30,43 +30,36 @@
 // BEGIN_ISC_NAMESPACE
 // BEGIN_RDATA_NAMESPACE
 
-A::A(const string& addrstr UNUSED_PARAM)
-{
+A::A(const string& addrstr UNUSED_PARAM) {
     // TBD
 }
 
-A::A(InputBuffer& buffer UNUSED_PARAM, size_t rdata_len UNUSED_PARAM)
-{
+A::A(InputBuffer& buffer UNUSED_PARAM, size_t rdata_len UNUSED_PARAM) {
     // TBD
 }
 
-A::A(const A& source UNUSED_PARAM) : Rdata()
-{
+A::A(const A& source UNUSED_PARAM) : Rdata() {
     // TBD
 }
 
 void
-A::toWire(OutputBuffer& buffer UNUSED_PARAM) const
-{
+A::toWire(OutputBuffer& buffer UNUSED_PARAM) const {
     // TBD
 }
 
 void
-A::toWire(MessageRenderer& renderer UNUSED_PARAM) const
-{
+A::toWire(MessageRenderer& renderer UNUSED_PARAM) const {
     // TBD
 }
 
 string
-A::toText() const
-{
+A::toText() const {
     // TBD
     isc_throw(InvalidRdataText, "Not implemented yet");
 }
 
 int
-A::compare(const Rdata& other UNUSED_PARAM) const
-{
+A::compare(const Rdata& other UNUSED_PARAM) const {
     return (0);                 // dummy.  TBD
 }
 

Modified: branches/trac292/src/lib/dns/rdata/template.cc
==============================================================================
--- branches/trac292/src/lib/dns/rdata/template.cc (original)
+++ branches/trac292/src/lib/dns/rdata/template.cc Mon Oct 18 10:46:07 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/trac292/src/lib/dns/rrclass-placeholder.h
==============================================================================
--- branches/trac292/src/lib/dns/rrclass-placeholder.h (original)
+++ branches/trac292/src/lib/dns/rrclass-placeholder.h Mon Oct 18 10:46:07 2010
@@ -211,7 +211,7 @@
     /// \brief Same as \c equals().
     bool operator==(const RRClass& other) const { return (equals(other)); }
 
-    /// \brief Return true iff two RRClasses are equal.
+    /// \brief Return true iff two RRClasses are not equal.
     ///
     /// This method never throws an exception.
     ///
@@ -260,16 +260,14 @@
 // END_WELL_KNOWN_CLASS_DEFINITIONS
 
 inline const RRClass&
-RRClass::NONE()
-{
+RRClass::NONE() {
     static RRClass rrclass(RRCLASS_NONE);
 
     return (rrclass);
 }
 
 inline const RRClass&
-RRClass::ANY()
-{
+RRClass::ANY() {
     static RRClass rrclass(RRCLASS_ANY);
 
     return (rrclass);

Modified: branches/trac292/src/lib/dns/rrclass.cc
==============================================================================
--- branches/trac292/src/lib/dns/rrclass.cc (original)
+++ branches/trac292/src/lib/dns/rrclass.cc Mon Oct 18 10:46:07 2010
@@ -31,13 +31,11 @@
 namespace isc {
 namespace dns {
 
-RRClass::RRClass(const string& classstr)
-{
+RRClass::RRClass(const string& classstr) {
     classcode_ = RRParamRegistry::getRegistry().textToClassCode(classstr);
 }
 
-RRClass::RRClass(InputBuffer& buffer)
-{
+RRClass::RRClass(InputBuffer& buffer) {
     if (buffer.getLength() - buffer.getPosition() < sizeof(uint16_t)) {
         isc_throw(IncompleteRRClass, "incomplete wire-format RR class");
     }
@@ -45,26 +43,22 @@
 }
 
 const string
-RRClass::toText() const
-{
+RRClass::toText() const {
     return (RRParamRegistry::getRegistry().codeToClassText(classcode_));
 }
 
 void
-RRClass::toWire(OutputBuffer& buffer) const
-{
+RRClass::toWire(OutputBuffer& buffer) const {
     buffer.writeUint16(classcode_);
 }
 
 void
-RRClass::toWire(MessageRenderer& renderer) const
-{
+RRClass::toWire(MessageRenderer& renderer) const {
     renderer.writeUint16(classcode_);
 }
 
 ostream&
-operator<<(ostream& os, const RRClass& rrclass)
-{
+operator<<(ostream& os, const RRClass& rrclass) {
     os << rrclass.toText();
     return (os);
 }

Modified: branches/trac292/src/lib/dns/rrparamregistry-placeholder.cc
==============================================================================
--- branches/trac292/src/lib/dns/rrparamregistry-placeholder.cc (original)
+++ branches/trac292/src/lib/dns/rrparamregistry-placeholder.cc Mon Oct 18 10:46:07 2010
@@ -49,8 +49,7 @@
 /// containers below.
 ///
 bool
-CICharLess(char c1, char c2)
-{
+CICharLess(char c1, char c2) {
     return (tolower(static_cast<unsigned char>(c1)) <
             tolower(static_cast<unsigned char>(c2)));
 }
@@ -84,29 +83,25 @@
 typedef map<uint16_t, RRTypeParamPtr> CodeRRTypeMap;
 
 inline const string&
-RRTypeParam::UNKNOWN_PREFIX()
-{
+RRTypeParam::UNKNOWN_PREFIX() {
     static const string p("TYPE");
     return (p);
 }
 
 inline size_t
-RRTypeParam::UNKNOWN_PREFIXLEN()
-{
+RRTypeParam::UNKNOWN_PREFIXLEN() {
     static size_t plen = UNKNOWN_PREFIX().size();
     return (plen);
 }
 
 inline const string&
-RRTypeParam::UNKNOWN_MAX()
-{
+RRTypeParam::UNKNOWN_MAX() {
     static const string p("TYPE65535");
     return (p);
 }
 
 inline size_t
-RRTypeParam::UNKNOWN_MAXLEN()
-{
+RRTypeParam::UNKNOWN_MAXLEN() {
     static size_t plen = UNKNOWN_MAX().size();
     return (plen);
 }
@@ -130,29 +125,25 @@
 typedef map<uint16_t, RRClassParamPtr> CodeRRClassMap;
 
 inline const string&
-RRClassParam::UNKNOWN_PREFIX()
-{
+RRClassParam::UNKNOWN_PREFIX() {
     static const string p("CLASS");
     return (p);
 }
 
 inline size_t
-RRClassParam::UNKNOWN_PREFIXLEN()
-{
+RRClassParam::UNKNOWN_PREFIXLEN() {
     static size_t plen = UNKNOWN_PREFIX().size();
     return (plen);
 }
 
 inline const string&
-RRClassParam::UNKNOWN_MAX()
-{
+RRClassParam::UNKNOWN_MAX() {
     static const string p("CLASS65535");
     return (p);
 }
 
 inline size_t
-RRClassParam::UNKNOWN_MAXLEN()
-{
+RRClassParam::UNKNOWN_MAXLEN() {
     static size_t plen = UNKNOWN_MAX().size();
     return (plen);
 }
@@ -209,8 +200,7 @@
     GenericRdataFactoryMap genericrdata_factories;
 };
 
-RRParamRegistry::RRParamRegistry()
-{
+RRParamRegistry::RRParamRegistry() {
     impl_ = new RRParamRegistryImpl;
 
     // set up parameters for well-known RRs
@@ -223,14 +213,12 @@
     }
 }
 
-RRParamRegistry::~RRParamRegistry()
-{
+RRParamRegistry::~RRParamRegistry() {
     delete impl_;
 }
 
 RRParamRegistry&
-RRParamRegistry::getRegistry()
-{
+RRParamRegistry::getRegistry() {
     static RRParamRegistry registry;
 
     return (registry);
@@ -301,8 +289,7 @@
 }
 
 bool
-RRParamRegistry::removeRdataFactory(const RRType& rrtype)
-{
+RRParamRegistry::removeRdataFactory(const RRType& rrtype) {
     GenericRdataFactoryMap::iterator found =
         impl_->genericrdata_factories.find(rrtype);
     if (found != impl_->genericrdata_factories.end()) {
@@ -320,15 +307,13 @@
 /// included in <cstring>.  To be as much as portable within the C++ standard
 /// we take the "in house" approach here.
 /// 
-bool CICharEqual(char c1, char c2)
-{
+bool CICharEqual(char c1, char c2) {
     return (tolower(static_cast<unsigned char>(c1)) ==
             tolower(static_cast<unsigned char>(c2)));
 }
 
 bool
-caseStringEqual(const string& s1, const string& s2, size_t n)
-{
+caseStringEqual(const string& s1, const string& s2, size_t n) {
     assert(s1.size() >= n && s2.size() >= n);
 
     return (mismatch(s1.begin(), s1.begin() + n, s2.begin(), CICharEqual).first
@@ -378,8 +363,7 @@
 
 template <typename MC, typename MS>
 inline bool
-removeParam(uint16_t code, MC& codemap, MS& stringmap)
-{
+removeParam(uint16_t code, MC& codemap, MS& stringmap) {
     typename MC::iterator found = codemap.find(code);
 
     if (found != codemap.end()) {
@@ -397,8 +381,7 @@
 
 template <typename PT, typename MS, typename ET>
 inline uint16_t
-textToCode(const string& code_str, MS& stringmap)
-{
+textToCode(const string& code_str, MS& stringmap) {
     typename MS::const_iterator found;
 
     found = stringmap.find(code_str);
@@ -424,8 +407,7 @@
 
 template <typename PT, typename MC>
 inline string
-codeToText(uint16_t code, MC& codemap)
-{
+codeToText(uint16_t code, MC& codemap) {
     typename MC::const_iterator found;
 
     found = codemap.find(code);
@@ -440,57 +422,49 @@
 }
 
 bool
-RRParamRegistry::addType(const string& type_string, uint16_t code)
-{
+RRParamRegistry::addType(const string& type_string, uint16_t code) {
     return (addParam<RRTypeParam, CodeRRTypeMap, StrRRTypeMap, RRTypeExists>
             (type_string, code, impl_->code2typemap, impl_->str2typemap));
 }
 
 bool
-RRParamRegistry::removeType(uint16_t code)
-{
+RRParamRegistry::removeType(uint16_t code) {
     return (removeParam<CodeRRTypeMap, StrRRTypeMap>(code, impl_->code2typemap,
                                                      impl_->str2typemap));
 }
 
 uint16_t
-RRParamRegistry::textToTypeCode(const string& type_string) const
-{
+RRParamRegistry::textToTypeCode(const string& type_string) const {
     return (textToCode<RRTypeParam, StrRRTypeMap,
             InvalidRRType>(type_string, impl_->str2typemap));
 }
 
 string
-RRParamRegistry::codeToTypeText(uint16_t code) const
-{
+RRParamRegistry::codeToTypeText(uint16_t code) const {
     return (codeToText<RRTypeParam, CodeRRTypeMap>(code, impl_->code2typemap));
 }
 
 bool
-RRParamRegistry::addClass(const string& class_string, uint16_t code)
-{
+RRParamRegistry::addClass(const string& class_string, uint16_t code) {
     return (addParam<RRClassParam, CodeRRClassMap, StrRRClassMap, RRClassExists>
             (class_string, code, impl_->code2classmap, impl_->str2classmap));
 }
 
 bool
-RRParamRegistry::removeClass(uint16_t code)
-{
+RRParamRegistry::removeClass(uint16_t code) {
     return (removeParam<CodeRRClassMap, StrRRClassMap>(code,
                                                        impl_->code2classmap,
                                                        impl_->str2classmap));
 }
 
 uint16_t
-RRParamRegistry::textToClassCode(const string& class_string) const
-{
+RRParamRegistry::textToClassCode(const string& class_string) const {
     return (textToCode<RRClassParam, StrRRClassMap,
             InvalidRRClass>(class_string, impl_->str2classmap));
 }
 
 string
-RRParamRegistry::codeToClassText(uint16_t code) const
-{
+RRParamRegistry::codeToClassText(uint16_t code) const {
     return (codeToText<RRClassParam, CodeRRClassMap>(code,
                                                      impl_->code2classmap));
 }

Modified: branches/trac292/src/lib/dns/rrset.cc
==============================================================================
--- branches/trac292/src/lib/dns/rrset.cc (original)
+++ branches/trac292/src/lib/dns/rrset.cc Mon Oct 18 10:46:07 2010
@@ -35,14 +35,12 @@
 namespace isc {
 namespace dns {
 void
-AbstractRRset::addRdata(const Rdata& rdata)
-{
+AbstractRRset::addRdata(const Rdata& rdata) {
     addRdata(createRdata(getType(), getClass(), rdata));
 }
 
 string
-AbstractRRset::toText() const
-{
+AbstractRRset::toText() const {
     string s;
     RdataIteratorPtr it = getRdataIterator();
 
@@ -64,8 +62,7 @@
 namespace {
 template <typename T>
 inline unsigned int
-rrsetToWire(const AbstractRRset& rrset, T& output, const size_t limit)
-{
+rrsetToWire(const AbstractRRset& rrset, T& output, const size_t limit) {
     unsigned int n = 0;
     RdataIteratorPtr it = rrset.getRdataIterator();
 
@@ -105,14 +102,12 @@
 }
 
 unsigned int
-AbstractRRset::toWire(OutputBuffer& buffer) const
-{
+AbstractRRset::toWire(OutputBuffer& buffer) const {
     return (rrsetToWire<OutputBuffer>(*this, buffer, 0));
 }
 
 unsigned int
-AbstractRRset::toWire(MessageRenderer& renderer) const
-{
+AbstractRRset::toWire(MessageRenderer& renderer) const {
     const unsigned int rrs_written = rrsetToWire<MessageRenderer>(
         *this, renderer, renderer.getLengthLimit());
     if (getRdataCount() > rrs_written) {
@@ -122,8 +117,7 @@
 }
 
 ostream&
-operator<<(ostream& os, const AbstractRRset& rrset)
-{
+operator<<(ostream& os, const AbstractRRset& rrset) {
     os << rrset.toText();
     return (os);
 }
@@ -151,80 +145,67 @@
     impl_ = new BasicRRsetImpl(name, rrclass, rrtype, ttl);
 }
 
-BasicRRset::~BasicRRset()
-{
+BasicRRset::~BasicRRset() {
     delete impl_;
 }
 
 void
-BasicRRset::addRdata(ConstRdataPtr rdata)
-{
+BasicRRset::addRdata(ConstRdataPtr rdata) {
     impl_->rdatalist_.push_back(rdata);
 }
 
 void
-BasicRRset::addRdata(const Rdata& rdata)
-{
+BasicRRset::addRdata(const Rdata& rdata) {
     AbstractRRset::addRdata(rdata);
 }
 
 unsigned int
-BasicRRset::getRdataCount() const
-{
+BasicRRset::getRdataCount() const {
     return (impl_->rdatalist_.size());
 }
 
 const Name&
-BasicRRset::getName() const
-{
+BasicRRset::getName() const {
     return (impl_->name_);
 }
 
 const RRClass&
-BasicRRset::getClass() const
-{
+BasicRRset::getClass() const {
     return (impl_->rrclass_);
 }
 
 const RRType&
-BasicRRset::getType() const
-{
+BasicRRset::getType() const {
     return (impl_->rrtype_);
 }
 
 const RRTTL&
-BasicRRset::getTTL() const
-{
+BasicRRset::getTTL() const {
     return (impl_->ttl_);
 }
 
 void
-BasicRRset::setName(const Name& name)
-{
+BasicRRset::setName(const Name& name) {
     impl_->name_ = name;
 }
 
 void
-BasicRRset::setTTL(const RRTTL& ttl)
-{
+BasicRRset::setTTL(const RRTTL& ttl) {
     impl_->ttl_ = ttl;
 }
 
 string
-BasicRRset::toText() const
-{
+BasicRRset::toText() const {
     return (AbstractRRset::toText());
 }
 
 unsigned int
-BasicRRset::toWire(OutputBuffer& buffer) const
-{
+BasicRRset::toWire(OutputBuffer& buffer) const {
     return (AbstractRRset::toWire(buffer));
 }
 
 unsigned int
-BasicRRset::toWire(MessageRenderer& renderer) const
-{
+BasicRRset::toWire(MessageRenderer& renderer) const {
     return (AbstractRRset::toWire(renderer));
 }
 
@@ -256,8 +237,7 @@
 }
 
 RdataIteratorPtr
-BasicRRset::getRdataIterator() const
-{
+BasicRRset::getRdataIterator() const {
     return (RdataIteratorPtr(new BasicRdataIterator(impl_->rdatalist_)));
 }
 }

Modified: branches/trac292/src/lib/dns/rrset.h
==============================================================================
--- branches/trac292/src/lib/dns/rrset.h (original)
+++ branches/trac292/src/lib/dns/rrset.h Mon Oct 18 10:46:07 2010
@@ -530,8 +530,8 @@
     /// \param rrclass The RR class of the RRset.
     /// \param rrtype The RR type of the RRset.
     /// \param ttl The TTL of the RRset.
-    explicit BasicRRset(const Name& name, const RRClass& rrclass,
-                        const RRType& rrtype, const RRTTL& ttl);
+    BasicRRset(const Name& name, const RRClass& rrclass,
+               const RRType& rrtype, const RRTTL& ttl);
     /// \brief The destructor.
     virtual ~BasicRRset();
     //@}
@@ -668,7 +668,7 @@
 /// QNAME/QTYPE/QCLASS as a single object.
 class RRset : public BasicRRset {
 public:
-    explicit RRset(const Name& name, const RRClass& rrclass,
+    RRset(const Name& name, const RRClass& rrclass,
           const RRType& rrtype, const RRTTL& ttl);
 
     virtual ~RRset();
@@ -692,8 +692,8 @@
     /// \brief Adds an RRSIG RR to this RRset's signatures
     virtual void addRRsig(const rdata::RdataPtr rdata) {
         if (!rrsig_) {
-            rrsig_ = RRsetPtr(new RRset(this->getName(), this->getClass(),
-                                        RRType::RRSIG(), this->getTTL()));
+            rrsig_ = RRsetPtr(new RRset(getName(), getClass(),
+                                        RRType::RRSIG(), getTTL()));
         }
         rrsig_->addRdata(rdata);
     }
@@ -703,8 +703,8 @@
         RdataIteratorPtr it = sigs.getRdataIterator();
 
         if (!rrsig_) {
-            rrsig_ = RRsetPtr(new RRset(this->getName(), this->getClass(),
-                                        RRType::RRSIG(), this->getTTL()));
+            rrsig_ = RRsetPtr(new RRset(getName(), getClass(),
+                                        RRType::RRSIG(), getTTL()));
         }
 
         for (it->first(); !it->isLast(); it->next()) {

Modified: branches/trac292/src/lib/dns/rrsetlist.cc
==============================================================================
--- branches/trac292/src/lib/dns/rrsetlist.cc (original)
+++ branches/trac292/src/lib/dns/rrsetlist.cc Mon Oct 18 10:46:07 2010
@@ -41,8 +41,7 @@
 }
 
 void
-RRsetList::append(RRsetList& source)
-{
+RRsetList::append(RRsetList& source) {
     BOOST_FOREACH(RRsetPtr rrset, source) {
         addRRset(rrset);
     }

Modified: branches/trac292/src/lib/dns/rrttl.cc
==============================================================================
--- branches/trac292/src/lib/dns/rrttl.cc (original)
+++ branches/trac292/src/lib/dns/rrttl.cc Mon Oct 18 10:46:07 2010
@@ -29,8 +29,7 @@
 namespace isc {
 namespace dns {
 
-RRTTL::RRTTL(const string& ttlstr)
-{
+RRTTL::RRTTL(const string& ttlstr) {
     // Some systems (at least gcc-4.4) flow negative values over into
     // unsigned integer, where older systems failed to parse. We want
     // that failure here, so we extract into int64 and check the value
@@ -45,8 +44,7 @@
     }
 }
 
-RRTTL::RRTTL(InputBuffer& buffer)
-{
+RRTTL::RRTTL(InputBuffer& buffer) {
     if (buffer.getLength() - buffer.getPosition() < sizeof(uint32_t)) {
         isc_throw(IncompleteRRTTL, "incomplete wire-format TTL value");
     }
@@ -54,28 +52,24 @@
 }
 
 const string
-RRTTL::toText() const
-{
+RRTTL::toText() const {
     ostringstream oss;
     oss << ttlval_;
     return (oss.str());
 }
 
 void
-RRTTL::toWire(OutputBuffer& buffer) const
-{
+RRTTL::toWire(OutputBuffer& buffer) const {
     buffer.writeUint32(ttlval_);
 }
 
 void
-RRTTL::toWire(MessageRenderer& renderer) const
-{
+RRTTL::toWire(MessageRenderer& renderer) const {
     renderer.writeUint32(ttlval_);
 }
 
 ostream&
-operator<<(ostream& os, const RRTTL& rrttl)
-{
+operator<<(ostream& os, const RRTTL& rrttl) {
     os << rrttl.toText();
     return (os);
 }

Modified: branches/trac292/src/lib/dns/rrtype-placeholder.h
==============================================================================
--- branches/trac292/src/lib/dns/rrtype-placeholder.h (original)
+++ branches/trac292/src/lib/dns/rrtype-placeholder.h Mon Oct 18 10:46:07 2010
@@ -223,7 +223,7 @@
     /// \brief Same as \c equals().
     bool operator==(const RRType& other) const { return (equals(other)); }
 
-    /// \brief Return true iff two RRTypes are equal.
+    /// \brief Return true iff two RRTypes are not equal.
     ///
     /// This method never throws an exception.
     ///
@@ -276,22 +276,19 @@
 // END_WELL_KNOWN_TYPE_DEFINITIONS
 
 inline const RRType&
-RRType::IXFR()
-{
+RRType::IXFR() {
     static RRType rrtype(RRTYPE_IXFR);
     return (rrtype);
 }
 
 inline const RRType&
-RRType::AXFR()
-{
+RRType::AXFR() {
     static RRType rrtype(RRTYPE_AXFR);
     return (rrtype);
 }
 
 inline const RRType&
-RRType::ANY()
-{
+RRType::ANY() {
     static RRType rrtype(RRTYPE_ANY);
     return (rrtype);
 }

Modified: branches/trac292/src/lib/dns/rrtype.cc
==============================================================================
--- branches/trac292/src/lib/dns/rrtype.cc (original)
+++ branches/trac292/src/lib/dns/rrtype.cc Mon Oct 18 10:46:07 2010
@@ -33,13 +33,11 @@
 namespace isc {
 namespace dns {
 
-RRType::RRType(const string& typestr)
-{
+RRType::RRType(const string& typestr) {
     typecode_ = RRParamRegistry::getRegistry().textToTypeCode(typestr);
 }
 
-RRType::RRType(InputBuffer& buffer)
-{
+RRType::RRType(InputBuffer& buffer) {
     if (buffer.getLength() - buffer.getPosition() < sizeof(uint16_t)) {
         isc_throw(IncompleteRRType, "incomplete wire-format RR type");
     }
@@ -47,26 +45,22 @@
 }
 
 const string
-RRType::toText() const
-{
+RRType::toText() const {
     return (RRParamRegistry::getRegistry().codeToTypeText(typecode_));
 }
 
 void
-RRType::toWire(OutputBuffer& buffer) const
-{
+RRType::toWire(OutputBuffer& buffer) const {
     buffer.writeUint16(typecode_);
 }
 
 void
-RRType::toWire(MessageRenderer& renderer) const
-{
+RRType::toWire(MessageRenderer& renderer) const {
     renderer.writeUint16(typecode_);
 }
 
 ostream&
-operator<<(ostream& os, const RRType& rrtype)
-{
+operator<<(ostream& os, const RRType& rrtype) {
     os << rrtype.toText();
     return (os);
 }

Modified: branches/trac292/src/lib/dns/tests/Makefile.am
==============================================================================
--- branches/trac292/src/lib/dns/tests/Makefile.am (original)
+++ branches/trac292/src/lib/dns/tests/Makefile.am Mon Oct 18 10:46:07 2010
@@ -1,6 +1,9 @@
+SUBDIRS = testdata .
+
 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_DIR=\"$(srcdir)/testdata\"
+AM_CPPFLAGS += -DTEST_DATA_SRCDIR=\"$(srcdir)/testdata\"
+AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/lib/dns/tests/testdata\"
 AM_CXXFLAGS = $(B10_CXXFLAGS)
 
 if USE_STATIC_LINK
@@ -14,10 +17,13 @@
 TESTS += run_unittests
 run_unittests_SOURCES = unittest_util.h unittest_util.cc
 run_unittests_SOURCES += buffer_unittest.cc name_unittest.cc
+run_unittests_SOURCES += edns_unittest.cc
 run_unittests_SOURCES += messagerenderer_unittest.cc
 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
@@ -49,99 +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/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/trac292/src/lib/dns/tests/buffer_unittest.cc
==============================================================================
--- branches/trac292/src/lib/dns/tests/buffer_unittest.cc (original)
+++ branches/trac292/src/lib/dns/tests/buffer_unittest.cc Mon Oct 18 10:46:07 2010
@@ -48,8 +48,7 @@
 
 const uint8_t BufferTest::testdata[5] = {1, 2, 3, 4, 5};
 
-TEST_F(BufferTest, inputBufferRead)
-{
+TEST_F(BufferTest, inputBufferRead) {
     EXPECT_EQ(5, ibuffer.getLength());
     EXPECT_EQ(1, ibuffer.readUint8());
     EXPECT_EQ(1, ibuffer.getPosition());
@@ -66,8 +65,7 @@
     EXPECT_EQ(0, memcmp(vdata, testdata, sizeof(testdata)));
 }
 
-TEST_F(BufferTest, inputBufferException)
-{
+TEST_F(BufferTest, inputBufferException) {
     EXPECT_THROW(ibuffer.setPosition(6), isc::dns::InvalidBufferPosition);
 
     ibuffer.setPosition(sizeof(testdata));
@@ -84,8 +82,7 @@
                  isc::dns::InvalidBufferPosition);
 }
 
-TEST_F(BufferTest, outputBufferExtend)
-{
+TEST_F(BufferTest, outputBufferExtend) {
     EXPECT_EQ(0, obuffer.getCapacity());
     EXPECT_EQ(0, obuffer.getLength());
     obuffer.writeUint8(10);
@@ -93,8 +90,7 @@
     EXPECT_EQ(1, obuffer.getLength());
 }
 
-TEST_F(BufferTest, outputBufferWrite)
-{
+TEST_F(BufferTest, outputBufferWrite) {
     const uint8_t* cp;
 
     obuffer.writeUint8(1);
@@ -126,8 +122,7 @@
     EXPECT_EQ(0, memcmp(cp + 7, testdata, sizeof(testdata)));
 }
 
-TEST_F(BufferTest, outputBufferWriteat)
-{
+TEST_F(BufferTest, outputBufferWriteat) {
     obuffer.writeUint32(data32);
     expected_size += sizeof(data32);
 
@@ -153,8 +148,7 @@
                  isc::dns::InvalidBufferPosition);
 }
 
-TEST_F(BufferTest, outputBufferSkip)
-{
+TEST_F(BufferTest, outputBufferSkip) {
     obuffer.skip(4);
     EXPECT_EQ(4, obuffer.getLength());
 
@@ -162,8 +156,7 @@
     EXPECT_EQ(6, obuffer.getLength());
 }
 
-TEST_F(BufferTest, outputBufferTrim)
-{
+TEST_F(BufferTest, outputBufferTrim) {
     obuffer.writeData(testdata, sizeof(testdata));
     EXPECT_EQ(5, obuffer.getLength());
 
@@ -176,8 +169,7 @@
     EXPECT_THROW(obuffer.trim(3), OutOfRange);
 }
 
-TEST_F(BufferTest, outputBufferReadat)
-{
+TEST_F(BufferTest, outputBufferReadat) {
     obuffer.writeData(testdata, sizeof(testdata));
     for (int i = 0; i < sizeof(testdata); i ++) {
         EXPECT_EQ(testdata[i], obuffer[i]);
@@ -185,8 +177,7 @@
     EXPECT_THROW(obuffer[sizeof(testdata)], isc::dns::InvalidBufferPosition);
 }
 
-TEST_F(BufferTest, outputBufferClear)
-{
+TEST_F(BufferTest, outputBufferClear) {
     obuffer.writeData(testdata, sizeof(testdata));
     obuffer.clear();
     EXPECT_EQ(0, obuffer.getLength());

Modified: branches/trac292/src/lib/dns/tests/message_unittest.cc
==============================================================================
--- branches/trac292/src/lib/dns/tests/message_unittest.cc (original)
+++ branches/trac292/src/lib/dns/tests/message_unittest.cc Mon Oct 18 10:46:07 2010
@@ -17,10 +17,13 @@
 #include <exceptions/exceptions.h>
 
 #include <dns/buffer.h>
+#include <dns/edns.h>
 #include <dns/exceptions.h>
 #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>
@@ -76,23 +79,25 @@
     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.wire");
+    EXPECT_TRUE(message_parse.getEDNS());
+    EXPECT_EQ(0, message_parse.getEDNS()->getVersion());
+    EXPECT_EQ(4096, message_parse.getEDNS()->getUDPSize());
+    EXPECT_TRUE(message_parse.getEDNS()->getDNSSECAwareness());
+}
+
+TEST_F(MessageTest, setEDNS) {
+    // setEDNS() isn't allowed in the parse mode
+    EXPECT_THROW(message_parse.setEDNS(EDNSPtr(new EDNS())),
+                 InvalidMessageOperation);
+
+    EDNSPtr edns = EDNSPtr(new EDNS());
+    message_render.setEDNS(edns);
+    EXPECT_EQ(edns, message_render.getEDNS());
+}
 
 TEST_F(MessageTest, fromWire) {
     factoryFromFile(message_parse, "message_fromWire1");
@@ -127,89 +132,14 @@
     EXPECT_TRUE(it->isLast());
 }
 
-TEST_F(MessageTest, GetEDNS0DOBit) {
-    // Without EDNS0, DNSSEC is considered to be unsupported.
-    factoryFromFile(message_parse, "message_fromWire1");
-    EXPECT_FALSE(message_parse.isDNSSECSupported());
-
-    // If DO bit is on, DNSSEC is considered to be supported.
-    message_parse.clear(Message::PARSE);
-    factoryFromFile(message_parse, "message_fromWire2");
-    EXPECT_TRUE(message_parse.isDNSSECSupported());
-
-    // If DO bit is off, DNSSEC is considered to be unsupported.
-    message_parse.clear(Message::PARSE);
-    factoryFromFile(message_parse, "message_fromWire3");
-    EXPECT_FALSE(message_parse.isDNSSECSupported());
-}
-
-TEST_F(MessageTest, SetEDNS0DOBit) {
-    // By default, it's false, and we can enable/disable it.
-    EXPECT_FALSE(message_render.isDNSSECSupported());
-    message_render.setDNSSECSupported(true);
-    EXPECT_TRUE(message_render.isDNSSECSupported());
-    message_render.setDNSSECSupported(false);
-    EXPECT_FALSE(message_render.isDNSSECSupported());
-
-    // A message in the parse mode doesn't allow this flag to be set.
-    EXPECT_THROW(message_parse.setDNSSECSupported(true),
-                 InvalidMessageOperation);
-    // Once converted to the render mode, it works as above
-    message_parse.makeResponse();
-    EXPECT_FALSE(message_parse.isDNSSECSupported());
-    message_parse.setDNSSECSupported(true);
-    EXPECT_TRUE(message_parse.isDNSSECSupported());
-    message_parse.setDNSSECSupported(false);
-    EXPECT_FALSE(message_parse.isDNSSECSupported());
-}
-
-TEST_F(MessageTest, GetEDNS0UDPSize) {
-    // Without EDNS0, the default max UDP size is used.
-    factoryFromFile(message_parse, "message_fromWire1");
-    EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message_parse.getUDPSize());
-
-    // If the size specified in EDNS0 > default max, use it.
-    message_parse.clear(Message::PARSE);
-    factoryFromFile(message_parse, "message_fromWire2");
-    EXPECT_EQ(4096, message_parse.getUDPSize());
-
-    // If the size specified in EDNS0 < default max, keep using the default.
-    message_parse.clear(Message::PARSE);
-    factoryFromFile(message_parse, "message_fromWire8");
-    EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message_parse.getUDPSize());
-}
-
-TEST_F(MessageTest, SetEDNS0UDPSize) {
-    // The default size if unspecified
-    EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message_render.getUDPSize());
-    // A common buffer size with EDNS, should succeed
-    message_render.setUDPSize(4096);
-    EXPECT_EQ(4096, message_render.getUDPSize());
-    // Unusual large value, but accepted
-    message_render.setUDPSize(0xffff);
-    EXPECT_EQ(0xffff, message_render.getUDPSize());
-    // Too small is value is rejected
-    EXPECT_THROW(message_render.setUDPSize(511), InvalidMessageUDPSize);
-
-    // A message in the parse mode doesn't allow the set operation.
-    EXPECT_THROW(message_parse.setUDPSize(4096), InvalidMessageOperation);
-    // Once converted to the render mode, it works as above.
-    message_parse.makeResponse();
-    message_parse.setUDPSize(4096);
-    EXPECT_EQ(4096, message_parse.getUDPSize());
-    message_parse.setUDPSize(0xffff);
-    EXPECT_EQ(0xffff, message_parse.getUDPSize());
-    EXPECT_THROW(message_parse.setUDPSize(511), InvalidMessageUDPSize);
-}
-
-TEST_F(MessageTest, EDNS0ExtCode) {
+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());
 }
 
@@ -221,19 +151,6 @@
     message_parse.clear(Message::PARSE);
     EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire5"),
                  DNSMessageFORMERR);
-    // OPT RR of a non root name
-    message_parse.clear(Message::PARSE);
-    EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire6"),
-                 DNSMessageFORMERR);
-    // Compressed owner name of OPT RR points to a root name.
-    // Not necessarily bogus, but very unusual and mostly pathological.
-    // We accept it, but is it okay?
-    message_parse.clear(Message::PARSE);
-    EXPECT_NO_THROW(factoryFromFile(message_parse, "message_fromWire7"));
-    // Unsupported Version
-    message_parse.clear(Message::PARSE);
-    EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire9"),
-                 DNSMessageBADVERS);
 }
 
 TEST_F(MessageTest, toWire) {
@@ -262,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/trac292/src/lib/dns/tests/messagerenderer_unittest.cc
==============================================================================
--- branches/trac292/src/lib/dns/tests/messagerenderer_unittest.cc (original)
+++ branches/trac292/src/lib/dns/tests/messagerenderer_unittest.cc Mon Oct 18 10:46:07 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/trac292/src/lib/dns/tests/name_unittest.cc
==============================================================================
--- branches/trac292/src/lib/dns/tests/name_unittest.cc (original)
+++ branches/trac292/src/lib/dns/tests/name_unittest.cc Mon Oct 18 10:46:07 2010
@@ -84,8 +84,7 @@
 }
 
 Name
-NameTest::nameFactoryLowerCase()
-{
+NameTest::nameFactoryLowerCase() {
     string lowercase_namestr;
     lowercase_namestr.reserve(Name::MAX_WIRE);
 
@@ -124,8 +123,7 @@
                         buffer_expected.getData(), buffer_expected.getLength());
 }
 
-TEST_F(NameTest, nonlocalObject)
-{
+TEST_F(NameTest, nonlocalObject) {
     // A previous version of code relied on a non local static object for
     // name construction, so a non local static Name object defined outside
     // the name module might not be initialized correctly.  This test detects
@@ -133,8 +131,7 @@
     EXPECT_EQ("\\255.example.com.", downcased_global.toText());
 }
 
-TEST_F(NameTest, fromText)
-{
+TEST_F(NameTest, fromText) {
     vector<string> strnames;
     strnames.push_back("www.example.com");
     strnames.push_back("www.example.com."); // with a trailing dot
@@ -216,8 +213,7 @@
     EXPECT_EQ(Name::MAX_LABELS, maxlabels.getLabelCount());
 }
 
-TEST_F(NameTest, fromWire)
-{
+TEST_F(NameTest, fromWire) {
     //
     // test cases derived from BIND9 tests.
     //
@@ -271,8 +267,7 @@
     EXPECT_EQ(3, nameFactoryFromWire("name_fromWire1", 25).getLabelCount());
 }
 
-TEST_F(NameTest, copyConstruct)
-{
+TEST_F(NameTest, copyConstruct) {
     Name copy(example_name);
     EXPECT_EQ(copy, example_name);
 
@@ -283,8 +278,7 @@
     EXPECT_EQ(copy3, example_name);
 }
 
-TEST_F(NameTest, assignment)
-{
+TEST_F(NameTest, assignment) {
     Name copy(".");
     copy = example_name;
     EXPECT_EQ(copy, example_name);
@@ -301,8 +295,7 @@
     EXPECT_EQ(copy, example_name);
 }
 
-TEST_F(NameTest, toText)
-{
+TEST_F(NameTest, toText) {
     // tests derived from BIND9
     EXPECT_EQ("a.b.c.d", Name("a.b.c.d").toText(true));
     EXPECT_EQ("a.\\\\[[.c.d", Name("a.\\\\[\\[.c.d").toText(true));
@@ -349,8 +342,7 @@
               nameFactoryFromWire("name_fromWire14", 0).toText());
 }
 
-TEST_F(NameTest, toWireBuffer)
-{
+TEST_F(NameTest, toWireBuffer) {
     vector<unsigned char> data;
     OutputBuffer buffer(0);
 
@@ -364,8 +356,7 @@
 // We test various corner cases in Renderer tests, but add this test case
 // to fill the code coverage gap.
 //
-TEST_F(NameTest, toWireRenderer)
-{
+TEST_F(NameTest, toWireRenderer) {
     vector<unsigned char> data;
     OutputBuffer buffer(0);
     MessageRenderer renderer(buffer);

Modified: branches/trac292/src/lib/dns/tests/question_unittest.cc
==============================================================================
--- branches/trac292/src/lib/dns/tests/question_unittest.cc (original)
+++ branches/trac292/src/lib/dns/tests/question_unittest.cc Mon Oct 18 10:46:07 2010
@@ -56,8 +56,7 @@
 };
 
 Question
-questionFromWire(const char* datafile, size_t position = 0)
-{
+questionFromWire(const char* datafile, size_t position = 0) {
     vector<unsigned char> data;
     UnitTestUtil::readWireData(datafile, data);
 
@@ -67,8 +66,7 @@
     return (Question(buffer));
 }
 
-TEST_F(QuestionTest, fromWire)
-{
+TEST_F(QuestionTest, fromWire) {
     Question q = questionFromWire("question_fromWire");
 
     EXPECT_EQ(example_name1, q.getName());
@@ -88,14 +86,12 @@
     EXPECT_THROW(questionFromWire("question_fromWire", 36), IncompleteRRClass);
 }
 
-TEST_F(QuestionTest, toText)
-{
+TEST_F(QuestionTest, toText) {
     EXPECT_EQ("foo.example.com. IN NS\n", test_question1.toText());
     EXPECT_EQ("bar.example.com. CH A\n", test_question2.toText());
 }
 
-TEST_F(QuestionTest, toWireBuffer)
-{
+TEST_F(QuestionTest, toWireBuffer) {
     test_question1.toWire(obuffer);
     test_question2.toWire(obuffer);
     UnitTestUtil::readWireData("question_toWire1", wiredata);
@@ -103,8 +99,7 @@
                         obuffer.getLength(), &wiredata[0], wiredata.size());
 }
 
-TEST_F(QuestionTest, toWireRenderer)
-{
+TEST_F(QuestionTest, toWireRenderer) {
     test_question1.toWire(renderer);
     test_question2.toWire(renderer);
     UnitTestUtil::readWireData("question_toWire2", wiredata);
@@ -113,15 +108,13 @@
 }
 
 // test operator<<.  We simply confirm it appends the result of toText().
-TEST_F(QuestionTest, LeftShiftOperator)
-{
+TEST_F(QuestionTest, LeftShiftOperator) {
     ostringstream oss;
     oss << test_question1;
     EXPECT_EQ(test_question1.toText(), oss.str());
 }
 
-TEST_F(QuestionTest, comparison)
-{
+TEST_F(QuestionTest, comparison) {
     const Name a("a"), b("b");
     const RRClass in(RRClass::IN()), ch(RRClass::CH());
     const RRType ns(RRType::NS()), aaaa(RRType::AAAA());

Modified: branches/trac292/src/lib/dns/tests/rdata_cname_unittest.cc
==============================================================================
--- branches/trac292/src/lib/dns/tests/rdata_cname_unittest.cc (original)
+++ branches/trac292/src/lib/dns/tests/rdata_cname_unittest.cc Mon Oct 18 10:46:07 2010
@@ -50,8 +50,7 @@
     // compressed.
     0x03, 0x63, 0x6e, 0x32, 0xc0, 0x03 };
 
-TEST_F(Rdata_CNAME_Test, createFromText)
-{
+TEST_F(Rdata_CNAME_Test, createFromText) {
     EXPECT_EQ(0, rdata_cname.compare(generic::CNAME("cn.example.com")));
     // explicitly add a trailing dot.  should be the same RDATA.
     EXPECT_EQ(0, rdata_cname.compare(generic::CNAME("cn.example.com.")));
@@ -64,8 +63,7 @@
                                                   "cn.example.com")));
 }
 
-TEST_F(Rdata_CNAME_Test, createFromWire)
-{
+TEST_F(Rdata_CNAME_Test, createFromWire) {
     EXPECT_EQ(0, rdata_cname.compare(
                   *rdataFactoryFromFile(RRType("CNAME"), RRClass("IN"),
                                         "rdata_cname_fromWire")));
@@ -90,16 +88,14 @@
                  InvalidRdataLength);
 }
 
-TEST_F(Rdata_CNAME_Test, toWireBuffer)
-{
+TEST_F(Rdata_CNAME_Test, toWireBuffer) {
     rdata_cname.toWire(obuffer);
     EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                         obuffer.getData(), obuffer.getLength(),
                         wiredata_cname, sizeof(wiredata_cname));
 }
 
-TEST_F(Rdata_CNAME_Test, toWireRenderer)
-{
+TEST_F(Rdata_CNAME_Test, toWireRenderer) {
     rdata_cname.toWire(renderer);
     EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                         obuffer.getData(), obuffer.getLength(),
@@ -110,13 +106,11 @@
                         wiredata_cname2, sizeof(wiredata_cname2));
 }
 
-TEST_F(Rdata_CNAME_Test, toText)
-{
+TEST_F(Rdata_CNAME_Test, toText) {
     EXPECT_EQ("cn.example.com.", rdata_cname.toText());
 }
 
-TEST_F(Rdata_CNAME_Test, getCname)
-{
+TEST_F(Rdata_CNAME_Test, getCname) {
     EXPECT_EQ(Name("cn.example.com."), rdata_cname.getCname());
 }
 }

Modified: branches/trac292/src/lib/dns/tests/rdata_dname_unittest.cc
==============================================================================
--- branches/trac292/src/lib/dns/tests/rdata_dname_unittest.cc (original)
+++ branches/trac292/src/lib/dns/tests/rdata_dname_unittest.cc Mon Oct 18 10:46:07 2010
@@ -50,8 +50,7 @@
     // compressed.
     0x03, 0x64, 0x6e, 0x32, 0xc0, 0x03 };
 
-TEST_F(Rdata_DNAME_Test, createFromText)
-{
+TEST_F(Rdata_DNAME_Test, createFromText) {
     EXPECT_EQ(0, rdata_dname.compare(generic::DNAME("dn.example.com")));
     // explicitly add a trailing dot.  should be the same RDATA.
     EXPECT_EQ(0, rdata_dname.compare(generic::DNAME("dn.example.com.")));
@@ -64,8 +63,7 @@
                                                   "dn.example.com")));
 }
 
-TEST_F(Rdata_DNAME_Test, createFromWire)
-{
+TEST_F(Rdata_DNAME_Test, createFromWire) {
     EXPECT_EQ(0, rdata_dname.compare(
                   *rdataFactoryFromFile(RRType("DNAME"), RRClass("IN"),
                                         "rdata_dname_fromWire")));
@@ -90,16 +88,14 @@
                  InvalidRdataLength);
 }
 
-TEST_F(Rdata_DNAME_Test, toWireBuffer)
-{
+TEST_F(Rdata_DNAME_Test, toWireBuffer) {
     rdata_dname.toWire(obuffer);
     EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                         obuffer.getData(), obuffer.getLength(),
                         wiredata_dname, sizeof(wiredata_dname));
 }
 
-TEST_F(Rdata_DNAME_Test, toWireRenderer)
-{
+TEST_F(Rdata_DNAME_Test, toWireRenderer) {
     rdata_dname.toWire(renderer);
     EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                         obuffer.getData(), obuffer.getLength(),
@@ -110,13 +106,11 @@
                         wiredata_dname2, sizeof(wiredata_dname2));
 }
 
-TEST_F(Rdata_DNAME_Test, toText)
-{
+TEST_F(Rdata_DNAME_Test, toText) {
     EXPECT_EQ("dn.example.com.", rdata_dname.toText());
 }
 
-TEST_F(Rdata_DNAME_Test, getDname)
-{
+TEST_F(Rdata_DNAME_Test, getDname) {
     EXPECT_EQ(Name("dn.example.com."), rdata_dname.getDname());
 }
 }

Modified: branches/trac292/src/lib/dns/tests/rdata_ns_unittest.cc
==============================================================================
--- branches/trac292/src/lib/dns/tests/rdata_ns_unittest.cc (original)
+++ branches/trac292/src/lib/dns/tests/rdata_ns_unittest.cc Mon Oct 18 10:46:07 2010
@@ -50,8 +50,7 @@
     // compressed.
     0x03, 0x6e, 0x73, 0x32, 0xc0, 0x03 };
 
-TEST_F(Rdata_NS_Test, createFromText)
-{
+TEST_F(Rdata_NS_Test, createFromText) {
     EXPECT_EQ(0, rdata_ns.compare(generic::NS("ns.example.com")));
     // explicitly add a trailing dot.  should be the same RDATA.
     EXPECT_EQ(0, rdata_ns.compare(generic::NS("ns.example.com.")));
@@ -63,8 +62,7 @@
                                                "ns.example.com")));
 }
 
-TEST_F(Rdata_NS_Test, createFromWire)
-{
+TEST_F(Rdata_NS_Test, createFromWire) {
     EXPECT_EQ(0, rdata_ns.compare(
                   *rdataFactoryFromFile(RRType("NS"), RRClass("IN"),
                                         "rdata_ns_fromWire")));
@@ -89,16 +87,14 @@
                  InvalidRdataLength);
 }
 
-TEST_F(Rdata_NS_Test, toWireBuffer)
-{
+TEST_F(Rdata_NS_Test, toWireBuffer) {
     rdata_ns.toWire(obuffer);
     EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                         obuffer.getData(), obuffer.getLength(),
                         wiredata_ns, sizeof(wiredata_ns));
 }
 
-TEST_F(Rdata_NS_Test, toWireRenderer)
-{
+TEST_F(Rdata_NS_Test, toWireRenderer) {
     rdata_ns.toWire(renderer);
     EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                         obuffer.getData(), obuffer.getLength(),
@@ -109,21 +105,18 @@
                         wiredata_ns2, sizeof(wiredata_ns2));
 }
 
-TEST_F(Rdata_NS_Test, toText)
-{
+TEST_F(Rdata_NS_Test, toText) {
     EXPECT_EQ("ns.example.com.", rdata_ns.toText());
 }
 
-TEST_F(Rdata_NS_Test, compare)
-{
+TEST_F(Rdata_NS_Test, compare) {
     generic::NS small("a.example");
     generic::NS large("example");
     EXPECT_EQ(true, Name("a.example") > Name("example"));
     EXPECT_GT(0, small.compare(large));
 }
 
-TEST_F(Rdata_NS_Test, getNSName)
-{
+TEST_F(Rdata_NS_Test, getNSName) {
     EXPECT_EQ(Name("ns.example.com"), rdata_ns.getNSName());
 }
 }

Modified: branches/trac292/src/lib/dns/tests/rdata_nsec_unittest.cc
==============================================================================
--- branches/trac292/src/lib/dns/tests/rdata_nsec_unittest.cc (original)
+++ branches/trac292/src/lib/dns/tests/rdata_nsec_unittest.cc Mon Oct 18 10:46:07 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/trac292/src/lib/dns/tests/rdata_opt_unittest.cc
==============================================================================
--- branches/trac292/src/lib/dns/tests/rdata_opt_unittest.cc (original)
+++ branches/trac292/src/lib/dns/tests/rdata_opt_unittest.cc Mon Oct 18 10:46:07 2010
@@ -38,14 +38,12 @@
 
 const generic::OPT rdata_opt;
 
-TEST_F(Rdata_OPT_Test, createFromText)
-{
+TEST_F(Rdata_OPT_Test, createFromText) {
     // OPT RR cannot be created from text.
     EXPECT_THROW(generic::OPT("this does not matter"), InvalidRdataText);
 }
 
-TEST_F(Rdata_OPT_Test, createFromWire)
-{
+TEST_F(Rdata_OPT_Test, createFromWire) {
     // Valid cases: in the simple implementation with no supported options,
     // we can only check these don't throw.
     EXPECT_NO_THROW(rdataFactoryFromFile(RRType::OPT(), RRClass("CLASS4096"),
@@ -59,25 +57,21 @@
                  InvalidRdataLength);
 }
 
-TEST_F(Rdata_OPT_Test, toWireBuffer)
-{
+TEST_F(Rdata_OPT_Test, toWireBuffer) {
     rdata_opt.toWire(obuffer);
     EXPECT_EQ(0, obuffer.getLength());
 }
 
-TEST_F(Rdata_OPT_Test, toWireRenderer)
-{
+TEST_F(Rdata_OPT_Test, toWireRenderer) {
     rdata_opt.toWire(renderer);
     EXPECT_EQ(0, obuffer.getLength());
 }
 
-TEST_F(Rdata_OPT_Test, toText)
-{
+TEST_F(Rdata_OPT_Test, toText) {
     EXPECT_EQ("", rdata_opt.toText());
 }
 
-TEST_F(Rdata_OPT_Test, compare)
-{
+TEST_F(Rdata_OPT_Test, compare) {
     // This simple implementation always returns "true"
     EXPECT_EQ(0, rdata_opt.compare(
                   *rdataFactoryFromFile(RRType::OPT(), RRClass::CH(),

Modified: branches/trac292/src/lib/dns/tests/rdata_ptr_unittest.cc
==============================================================================
--- branches/trac292/src/lib/dns/tests/rdata_ptr_unittest.cc (original)
+++ branches/trac292/src/lib/dns/tests/rdata_ptr_unittest.cc Mon Oct 18 10:46:07 2010
@@ -54,8 +54,7 @@
     // compressed.
     0x03, 0x6e, 0x73, 0x32, 0xc0, 0x03 };
 
-TEST_F(Rdata_PTR_Test, createFromText)
-{
+TEST_F(Rdata_PTR_Test, createFromText) {
     EXPECT_EQ(0, rdata_ptr.compare(generic::PTR("ns.example.com")));
     // explicitly add a trailing dot.  should be the same RDATA.
     EXPECT_EQ(0, rdata_ptr.compare(generic::PTR("ns.example.com.")));
@@ -67,8 +66,7 @@
                                                "ns.example.com")));
 }
 
-TEST_F(Rdata_PTR_Test, createFromWire)
-{
+TEST_F(Rdata_PTR_Test, createFromWire) {
     EXPECT_EQ(0, rdata_ptr.compare(
                   *rdataFactoryFromFile(RRType("PTR"), RRClass("IN"),
                                         "rdata_ns_fromWire")));
@@ -93,16 +91,14 @@
                  InvalidRdataLength);
 }
 
-TEST_F(Rdata_PTR_Test, toWireBuffer)
-{
+TEST_F(Rdata_PTR_Test, toWireBuffer) {
     rdata_ptr.toWire(obuffer);
     EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                         obuffer.getData(), obuffer.getLength(),
                         wiredata_ptr, sizeof(wiredata_ptr));
 }
 
-TEST_F(Rdata_PTR_Test, toWireRenderer)
-{
+TEST_F(Rdata_PTR_Test, toWireRenderer) {
     rdata_ptr.toWire(renderer);
     EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                         obuffer.getData(), obuffer.getLength(),
@@ -113,21 +109,18 @@
                         wiredata_ptr2, sizeof(wiredata_ptr2));
 }
 
-TEST_F(Rdata_PTR_Test, toText)
-{
+TEST_F(Rdata_PTR_Test, toText) {
     EXPECT_EQ("ns.example.com.", rdata_ptr.toText());
 }
 
-TEST_F(Rdata_PTR_Test, compare)
-{
+TEST_F(Rdata_PTR_Test, compare) {
     generic::PTR small("a.example");
     generic::PTR large("example");
     EXPECT_EQ(true, Name("a.example") > Name("example"));
     EXPECT_GT(0, small.compare(large));
 }
 
-TEST_F(Rdata_PTR_Test, getPTRName)
-{
+TEST_F(Rdata_PTR_Test, getPTRName) {
     EXPECT_EQ(Name("ns.example.com"), rdata_ptr.getPTRName());
 }
 }

Modified: branches/trac292/src/lib/dns/tests/rdata_rrsig_unittest.cc
==============================================================================
--- branches/trac292/src/lib/dns/tests/rdata_rrsig_unittest.cc (original)
+++ branches/trac292/src/lib/dns/tests/rdata_rrsig_unittest.cc Mon Oct 18 10:46:07 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/trac292/src/lib/dns/tests/rdata_soa_unittest.cc
==============================================================================
--- branches/trac292/src/lib/dns/tests/rdata_soa_unittest.cc (original)
+++ branches/trac292/src/lib/dns/tests/rdata_soa_unittest.cc Mon Oct 18 10:46:07 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/trac292/src/lib/dns/tests/rdata_txt_unittest.cc
==============================================================================
--- branches/trac292/src/lib/dns/tests/rdata_txt_unittest.cc (original)
+++ branches/trac292/src/lib/dns/tests/rdata_txt_unittest.cc Mon Oct 18 10:46:07 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/trac292/src/lib/dns/tests/rdata_unittest.cc
==============================================================================
--- branches/trac292/src/lib/dns/tests/rdata_unittest.cc (original)
+++ branches/trac292/src/lib/dns/tests/rdata_unittest.cc Mon Oct 18 10:46:07 2010
@@ -68,8 +68,7 @@
 };
 
 string
-Rdata_Unknown_Test::getLongestRdataTxt()
-{
+Rdata_Unknown_Test::getLongestRdataTxt() {
     ostringstream oss;
 
     oss << "\\# " << MAX_RDLENGTH << " ";
@@ -83,8 +82,7 @@
 }
 
 void
-Rdata_Unknown_Test::getLongestRdataWire(vector<uint8_t>& v)
-{
+Rdata_Unknown_Test::getLongestRdataWire(vector<uint8_t>& v) {
     unsigned char ch = 0;
     for (int i = 0; i < MAX_RDLENGTH; ++i, ++ch) {
         v.push_back(ch);
@@ -102,8 +100,7 @@
 // renumber it.
 const RRType unknown_rrtype = RRType(65000);
 
-TEST_F(Rdata_Unknown_Test, createFromText)
-{
+TEST_F(Rdata_Unknown_Test, createFromText) {
     // valid construction.  This also tests a normal case of "FromWire".
     EXPECT_EQ(0, generic::Generic("\\# 4 a1b2c30d").compare(
                   *rdataFactoryFromFile(unknown_rrtype, RRClass::IN(),
@@ -148,8 +145,7 @@
     EXPECT_THROW(generic::Generic("\\# 1ff"), InvalidRdataText);
 }
 
-TEST_F(Rdata_Unknown_Test, createFromWire)
-{
+TEST_F(Rdata_Unknown_Test, createFromWire) {
     // normal case (including 0-length data) is covered in createFromText.
 
     // buffer too short.  the error should be detected in buffer read
@@ -167,8 +163,7 @@
 
 // The following 3 sets of tests check the behavior of createRdata() variants
 // with the "unknown" RRtype.  The result should be RRclass independent.
-TEST_F(Rdata_Unknown_Test, createRdataFromString)
-{
+TEST_F(Rdata_Unknown_Test, createRdataFromString) {
     EXPECT_EQ(0, rdata_unknown.compare(
                   *createRdata(unknown_rrtype, RRClass::IN(),
                                rdata_unknowntxt)));
@@ -180,8 +175,7 @@
                                rdata_unknowntxt)));
 }
 
-TEST_F(Rdata_Unknown_Test, createRdataFromWire)
-{
+TEST_F(Rdata_Unknown_Test, createRdataFromWire) {
     InputBuffer ibuffer(wiredata_unknown, sizeof(wiredata_unknown));
     EXPECT_EQ(0, rdata_unknown.compare(
                   *createRdata(unknown_rrtype, RRClass::IN(),
@@ -198,8 +192,7 @@
                                ibuffer3, sizeof(wiredata_unknown))));
 }
 
-TEST_F(Rdata_Unknown_Test, createRdataByCopy)
-{
+TEST_F(Rdata_Unknown_Test, createRdataByCopy) {
     EXPECT_EQ(0, rdata_unknown.compare(
                   *createRdata(unknown_rrtype, RRClass::IN(), rdata_unknown)));
     EXPECT_EQ(0, rdata_unknown.compare(
@@ -209,8 +202,7 @@
                                rdata_unknown)));
 }
 
-TEST_F(Rdata_Unknown_Test, copyConstruct)
-{
+TEST_F(Rdata_Unknown_Test, copyConstruct) {
     generic::Generic copy(rdata_unknown);
     EXPECT_EQ(0, copy.compare(rdata_unknown));
 
@@ -221,8 +213,7 @@
     EXPECT_EQ(0, copy3.compare(rdata_unknown));
 }
 
-TEST_F(Rdata_Unknown_Test, assignment)
-{
+TEST_F(Rdata_Unknown_Test, assignment) {
     generic::Generic copy("\\# 1 10");
     copy = rdata_unknown;
     EXPECT_EQ(0, copy.compare(rdata_unknown));
@@ -239,31 +230,27 @@
     EXPECT_EQ(0, copy.compare(rdata_unknown));
 }
 
-TEST_F(Rdata_Unknown_Test, toText)
-{
+TEST_F(Rdata_Unknown_Test, toText) {
     EXPECT_EQ(rdata_unknowntxt, rdata_unknown.toText());
     EXPECT_EQ(getLongestRdataTxt(),
               generic::Generic(getLongestRdataTxt()).toText());
 }
 
-TEST_F(Rdata_Unknown_Test, toWireBuffer)
-{
+TEST_F(Rdata_Unknown_Test, toWireBuffer) {
     rdata_unknown.toWire(obuffer);
     EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                         obuffer.getData(), obuffer.getLength(),
                         wiredata_unknown, sizeof(wiredata_unknown));
 }
 
-TEST_F(Rdata_Unknown_Test, toWireRenderer)
-{
+TEST_F(Rdata_Unknown_Test, toWireRenderer) {
     rdata_unknown.toWire(renderer);
     EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                         obuffer.getData(), obuffer.getLength(),
                         wiredata_unknown, sizeof(wiredata_unknown));
 }
 
-TEST_F(Rdata_Unknown_Test, compare)
-{
+TEST_F(Rdata_Unknown_Test, compare) {
     // comparison as left-justified unsigned octet sequences:
     EXPECT_EQ(0, rdata_unknown.compare(rdata_unknown));
 
@@ -281,8 +268,7 @@
     EXPECT_LT(0, rdata_unknown.compare(rdata_unknown_short));
 }
 
-TEST_F(Rdata_Unknown_Test, LeftShiftOperator)
-{
+TEST_F(Rdata_Unknown_Test, LeftShiftOperator) {
     ostringstream oss;
     oss << rdata_unknown;
     EXPECT_EQ(rdata_unknown.toText(), oss.str());
@@ -291,8 +277,7 @@
 //
 // Tests for global utility functions
 //
-TEST_F(RdataTest, compareNames)
-{
+TEST_F(RdataTest, compareNames) {
     Name small("a.example");
     Name large("example");
 

Modified: branches/trac292/src/lib/dns/tests/rrclass_unittest.cc
==============================================================================
--- branches/trac292/src/lib/dns/tests/rrclass_unittest.cc (original)
+++ branches/trac292/src/lib/dns/tests/rrclass_unittest.cc Mon Oct 18 10:46:07 2010
@@ -51,8 +51,7 @@
                                           0x00, 0x80, 0x00, 0xff, 0xff };
 
 RRClass
-RRClassTest::rrclassFactoryFromWire(const char* datafile)
-{
+RRClassTest::rrclassFactoryFromWire(const char* datafile) {
     std::vector<unsigned char> data;
     UnitTestUtil::readWireData(datafile, data);
 
@@ -61,8 +60,7 @@
     return (RRClass(buffer));
 }
 
-TEST_F(RRClassTest, fromText)
-{
+TEST_F(RRClassTest, fromText) {
     EXPECT_EQ("IN", RRClass("IN").toText());
     EXPECT_EQ("CH", RRClass("CH").toText());
 
@@ -81,29 +79,25 @@
     EXPECT_THROW(RRClass("CLASS65000 "), InvalidRRClass);
 }
 
-TEST_F(RRClassTest, fromWire)
-{
+TEST_F(RRClassTest, fromWire) {
     EXPECT_EQ(0x1234,
               rrclassFactoryFromWire("rrcode16_fromWire1").getCode());
     EXPECT_THROW(rrclassFactoryFromWire("rrcode16_fromWire2"),
                  IncompleteRRClass);
 }
 
-TEST_F(RRClassTest, caseConstruct)
-{
+TEST_F(RRClassTest, caseConstruct) {
     EXPECT_EQ("IN", RRClass("in").toText());
     EXPECT_EQ("CH", RRClass("ch").toText());
     EXPECT_EQ("CLASS65535", RRClass("class65535").toText());
 }
 
-TEST_F(RRClassTest, toText)
-{
+TEST_F(RRClassTest, toText) {
     EXPECT_EQ("IN", RRClass(1).toText());
     EXPECT_EQ("CLASS65000", RRClass(65000).toText());
 }
 
-TEST_F(RRClassTest, toWireBuffer)
-{
+TEST_F(RRClassTest, toWireBuffer) {
     rrclass_1.toWire(obuffer);
     rrclass_0x80.toWire(obuffer);
     rrclass_0x800.toWire(obuffer);
@@ -115,8 +109,7 @@
                         wiredata, sizeof(wiredata));
 }
 
-TEST_F(RRClassTest, toWireRenderer)
-{
+TEST_F(RRClassTest, toWireRenderer) {
     rrclass_1.toWire(renderer);
     rrclass_0x80.toWire(renderer);
     rrclass_0x800.toWire(renderer);
@@ -128,14 +121,12 @@
                         wiredata, sizeof(wiredata));
 }
 
-TEST_F(RRClassTest, wellKnownClasss)
-{
+TEST_F(RRClassTest, wellKnownClasss) {
     EXPECT_EQ(1, RRClass::IN().getCode());
     EXPECT_EQ("IN", RRClass::IN().toText());
 }
 
-TEST_F(RRClassTest, compare)
-{
+TEST_F(RRClassTest, compare) {
     EXPECT_TRUE(RRClass(1) == RRClass("IN"));
     EXPECT_TRUE(RRClass(1).equals(RRClass("IN")));
     EXPECT_TRUE(RRClass(0).nequals(RRClass("IN")));
@@ -145,8 +136,7 @@
 }
 
 // test operator<<.  We simply confirm it appends the result of toText().
-TEST_F(RRClassTest, LeftShiftOperator)
-{
+TEST_F(RRClassTest, LeftShiftOperator) {
     ostringstream oss;
     oss << RRClass::IN();
     EXPECT_EQ(RRClass::IN().toText(), oss.str());

Modified: branches/trac292/src/lib/dns/tests/rrparamregistry_unittest.cc
==============================================================================
--- branches/trac292/src/lib/dns/tests/rrparamregistry_unittest.cc (original)
+++ branches/trac292/src/lib/dns/tests/rrparamregistry_unittest.cc Mon Oct 18 10:46:07 2010
@@ -70,8 +70,7 @@
 const string RRParamRegistryTest::test_class_str("TESTCLASS");
 const string RRParamRegistryTest::test_type_str("TESTTYPE");
 
-TEST_F(RRParamRegistryTest, addRemove)
-{
+TEST_F(RRParamRegistryTest, addRemove) {
     RRParamRegistry::getRegistry().addType(test_type_str, test_type_code);
     RRParamRegistry::getRegistry().addClass(test_class_str, test_class_code);
     EXPECT_EQ(65533, RRClass("TESTCLASS").getCode());
@@ -90,8 +89,7 @@
     EXPECT_FALSE(RRParamRegistry::getRegistry().removeClass(test_class_code));
 }
 
-TEST_F(RRParamRegistryTest, addError)
-{
+TEST_F(RRParamRegistryTest, addError) {
     // An attempt to override a pre-registered class should fail with an
     // exception, and the pre-registered one should remain in the registry.
     EXPECT_THROW(RRParamRegistry::getRegistry().addClass(test_class_str, 1),
@@ -114,8 +112,7 @@
     { return (RdataPtr(new in::A(dynamic_cast<const in::A&>(source)))); }
 };
 
-TEST_F(RRParamRegistryTest, addRemoveFactory)
-{
+TEST_F(RRParamRegistryTest, addRemoveFactory) {
     // By default, the test type/code pair should be considered "unknown",
     // so the following should trigger an exception.
     EXPECT_THROW(createRdata(RRType(test_type_code), RRClass(test_class_code),

Modified: branches/trac292/src/lib/dns/tests/rrset_unittest.cc
==============================================================================
--- branches/trac292/src/lib/dns/tests/rrset_unittest.cc (original)
+++ branches/trac292/src/lib/dns/tests/rrset_unittest.cc Mon Oct 18 10:46:07 2010
@@ -72,57 +72,49 @@
     static const int MAX_RDATA_COUNT = 100;
 };
 
-TEST_F(RRsetTest, getRdataCount)
-{
+TEST_F(RRsetTest, getRdataCount) {
     for (int i = 0; i < MAX_RDATA_COUNT; ++i) {
         EXPECT_EQ(i, rrset_a_empty.getRdataCount());
         rrset_a_empty.addRdata(in::A("192.0.2.1"));
     }
 }
 
-TEST_F(RRsetTest, getName)
-{
+TEST_F(RRsetTest, getName) {
     EXPECT_EQ(test_name, rrset_a.getName());
     EXPECT_EQ(test_domain, rrset_ns.getName());
 }
 
-TEST_F(RRsetTest, getClass)
-{
+TEST_F(RRsetTest, getClass) {
     EXPECT_EQ(RRClass("IN"), rrset_a.getClass());
     EXPECT_EQ(RRClass("CH"), rrset_ch_txt.getClass());
 }
 
-TEST_F(RRsetTest, getType)
-{
+TEST_F(RRsetTest, getType) {
     EXPECT_EQ(RRType("A"), rrset_a.getType());
     EXPECT_EQ(RRType("NS"), rrset_ns.getType());
     EXPECT_EQ(RRType("TXT"), rrset_ch_txt.getType());
 }
 
-TEST_F(RRsetTest, getTTL)
-{
+TEST_F(RRsetTest, getTTL) {
     EXPECT_EQ(RRTTL(3600), rrset_a.getTTL());
     EXPECT_EQ(RRTTL(86400), rrset_ns.getTTL());
     EXPECT_EQ(RRTTL(0), rrset_ch_txt.getTTL());
 }
 
-TEST_F(RRsetTest, setTTL)
-{
+TEST_F(RRsetTest, setTTL) {
     rrset_a.setTTL(RRTTL(86400));
     EXPECT_EQ(RRTTL(86400), rrset_a.getTTL());
     rrset_a.setTTL(RRTTL(0));
     EXPECT_EQ(RRTTL(0), rrset_a.getTTL());
 }
 
-TEST_F(RRsetTest, setName)
-{
+TEST_F(RRsetTest, setName) {
     rrset_a.setName(test_nsname);
     EXPECT_EQ(test_nsname, rrset_a.getName());
 }
 
 void
-addRdataTestCommon(const RRset& rrset)
-{
+addRdataTestCommon(const RRset& rrset) {
     EXPECT_EQ(2, rrset.getRdataCount());
 
     RdataIteratorPtr it = rrset.getRdataIterator();
@@ -136,8 +128,7 @@
     EXPECT_TRUE(it->isLast());
 }
 
-TEST_F(RRsetTest, addRdata)
-{
+TEST_F(RRsetTest, addRdata) {
     addRdataTestCommon(rrset_a);
 
     // Reference version of addRdata() doesn't allow to add a different
@@ -145,8 +136,7 @@
     EXPECT_THROW(rrset_a.addRdata(generic::NS(test_nsname)), std::bad_cast);
 }
 
-TEST_F(RRsetTest, addRdataPtr)
-{
+TEST_F(RRsetTest, addRdataPtr) {
     rrset_a_empty.addRdata(createRdata(rrset_a_empty.getType(),
                                        rrset_a_empty.getClass(),
                                        "192.0.2.1"));
@@ -163,8 +153,7 @@
     EXPECT_EQ(3, rrset_a_empty.getRdataCount());
 }
 
-TEST_F(RRsetTest, iterator)
-{
+TEST_F(RRsetTest, iterator) {
     // Iterator for an empty RRset.
     RdataIteratorPtr it = rrset_a_empty.getRdataIterator();
     it->first();
@@ -187,8 +176,7 @@
     }
 }
 
-TEST_F(RRsetTest, toText)
-{
+TEST_F(RRsetTest, toText) {
     EXPECT_EQ("test.example.com. 3600 IN A 192.0.2.1\n"
               "test.example.com. 3600 IN A 192.0.2.2\n",
               rrset_a.toText());
@@ -197,8 +185,7 @@
     EXPECT_THROW(rrset_a_empty.toText(), EmptyRRset);
 }
 
-TEST_F(RRsetTest, toWireBuffer)
-{
+TEST_F(RRsetTest, toWireBuffer) {
     rrset_a.toWire(buffer);
 
     UnitTestUtil::readWireData("rrset_toWire1", wiredata);
@@ -210,8 +197,7 @@
     EXPECT_THROW(rrset_a_empty.toWire(buffer), EmptyRRset);
 }
 
-TEST_F(RRsetTest, toWireRenderer)
-{
+TEST_F(RRsetTest, toWireRenderer) {
     rrset_ns.addRdata(generic::NS(test_nsname));
 
     rrset_a.toWire(renderer);
@@ -227,8 +213,7 @@
 }
 
 // test operator<<.  We simply confirm it appends the result of toText().
-TEST_F(RRsetTest, LeftShiftOperator)
-{
+TEST_F(RRsetTest, LeftShiftOperator) {
     ostringstream oss;
     oss << rrset_a;
     EXPECT_EQ(rrset_a.toText(), oss.str());

Modified: branches/trac292/src/lib/dns/tests/rrttl_unittest.cc
==============================================================================
--- branches/trac292/src/lib/dns/tests/rrttl_unittest.cc (original)
+++ branches/trac292/src/lib/dns/tests/rrttl_unittest.cc Mon Oct 18 10:46:07 2010
@@ -57,8 +57,7 @@
                                            0xff, 0xff, 0xff, 0xff };
 
 RRTTL
-RRTTLTest::rrttlFactoryFromWire(const char* datafile)
-{
+RRTTLTest::rrttlFactoryFromWire(const char* datafile) {
     std::vector<unsigned char> data;
     UnitTestUtil::readWireData(datafile, data);
 
@@ -67,8 +66,7 @@
     return (RRTTL(buffer));
 }
 
-TEST_F(RRTTLTest, fromText)
-{
+TEST_F(RRTTLTest, fromText) {
     EXPECT_EQ(0, ttl_0.getValue());
     EXPECT_EQ(3600, ttl_1h.getValue());
     EXPECT_EQ(86400, ttl_1d.getValue());
@@ -82,16 +80,14 @@
     EXPECT_THROW(RRTTL("4294967296"), InvalidRRTTL); // must be 32-bit
 }
 
-TEST_F(RRTTLTest, fromWire)
-{
+TEST_F(RRTTLTest, fromWire) {
     EXPECT_EQ(0x12345678,
               rrttlFactoryFromWire("rrcode32_fromWire1").getValue());
     EXPECT_THROW(rrttlFactoryFromWire("rrcode32_fromWire2"),
                  IncompleteRRTTL);
 }
 
-TEST_F(RRTTLTest, toText)
-{
+TEST_F(RRTTLTest, toText) {
     EXPECT_EQ("0", ttl_0.toText());
     EXPECT_EQ("3600", ttl_1h.toText());
     EXPECT_EQ("86400", ttl_1d.toText());
@@ -99,8 +95,7 @@
     EXPECT_EQ("4294967295", ttl_max.toText());
 }
 
-TEST_F(RRTTLTest, toWireBuffer)
-{
+TEST_F(RRTTLTest, toWireBuffer) {
     ttl_0.toWire(obuffer);
     ttl_1h.toWire(obuffer);
     ttl_1d.toWire(obuffer);
@@ -112,8 +107,7 @@
                         wiredata, sizeof(wiredata));
 }
 
-TEST_F(RRTTLTest, toWireRenderer)
-{
+TEST_F(RRTTLTest, toWireRenderer) {
     ttl_0.toWire(renderer);
     ttl_1h.toWire(renderer);
     ttl_1d.toWire(renderer);
@@ -125,8 +119,7 @@
                         wiredata, sizeof(wiredata));
 }
 
-TEST_F(RRTTLTest, equal)
-{
+TEST_F(RRTTLTest, equal) {
     EXPECT_TRUE(RRTTL("3600") == ttl_1h);
     EXPECT_TRUE(RRTTL("86400").equals(ttl_1d));
 
@@ -139,8 +132,7 @@
 // The test logic is simple, and all tests are just straightforward variations
 // of the first one.
 //
-TEST_F(RRTTLTest, leq)
-{
+TEST_F(RRTTLTest, leq) {
     // small <= large is true
     EXPECT_TRUE(ttl_small.leq(ttl_large));
     EXPECT_TRUE(ttl_small <= ttl_large);
@@ -154,8 +146,7 @@
     EXPECT_FALSE(ttl_large <= ttl_small);
 }
 
-TEST_F(RRTTLTest, geq)
-{
+TEST_F(RRTTLTest, geq) {
     EXPECT_TRUE(ttl_large.geq(ttl_small));
     EXPECT_TRUE(ttl_large >= ttl_small);
 
@@ -166,8 +157,7 @@
     EXPECT_FALSE(ttl_small >= ttl_large);
 }
 
-TEST_F(RRTTLTest, lthan)
-{
+TEST_F(RRTTLTest, lthan) {
     EXPECT_TRUE(ttl_small.lthan(ttl_large));
     EXPECT_TRUE(ttl_small < ttl_large);
 
@@ -178,8 +168,7 @@
     EXPECT_FALSE(ttl_large < ttl_small);
 }
 
-TEST_F(RRTTLTest, gthan)
-{
+TEST_F(RRTTLTest, gthan) {
     EXPECT_TRUE(ttl_large.gthan(ttl_small));
     EXPECT_TRUE(ttl_large > ttl_small);
 
@@ -191,8 +180,7 @@
 }
 
 // test operator<<.  We simply confirm it appends the result of toText().
-TEST_F(RRTTLTest, LeftShiftOperator)
-{
+TEST_F(RRTTLTest, LeftShiftOperator) {
     ostringstream oss;
     oss << ttl_1h;
     EXPECT_EQ(ttl_1h.toText(), oss.str());

Modified: branches/trac292/src/lib/dns/tests/rrtype_unittest.cc
==============================================================================
--- branches/trac292/src/lib/dns/tests/rrtype_unittest.cc (original)
+++ branches/trac292/src/lib/dns/tests/rrtype_unittest.cc Mon Oct 18 10:46:07 2010
@@ -51,8 +51,7 @@
                                          0x00, 0x80, 0x00, 0xff, 0xff };
 
 RRType
-RRTypeTest::rrtypeFactoryFromWire(const char* datafile)
-{
+RRTypeTest::rrtypeFactoryFromWire(const char* datafile) {
     std::vector<unsigned char> data;
     UnitTestUtil::readWireData(datafile, data);
 
@@ -61,8 +60,7 @@
     return (RRType(buffer));
 }
 
-TEST_F(RRTypeTest, fromText)
-{
+TEST_F(RRTypeTest, fromText) {
     EXPECT_EQ("A", RRType("A").toText());
     EXPECT_EQ("NS", RRType("NS").toText());
 
@@ -85,29 +83,25 @@
     EXPECT_THROW(RRType("TYPE65000 "), InvalidRRType);
 }
 
-TEST_F(RRTypeTest, fromWire)
-{
+TEST_F(RRTypeTest, fromWire) {
     EXPECT_EQ(0x1234,
               rrtypeFactoryFromWire("rrcode16_fromWire1").getCode());
     EXPECT_THROW(rrtypeFactoryFromWire("rrcode16_fromWire2"), IncompleteRRType);
 }
 
 // from string, lower case
-TEST_F(RRTypeTest, caseConstruct)
-{
+TEST_F(RRTypeTest, caseConstruct) {
     EXPECT_EQ("A", RRType("a").toText());
     EXPECT_EQ("NS", RRType("ns").toText());
     EXPECT_EQ("TYPE65535", RRType("type65535").toText());
 }
 
-TEST_F(RRTypeTest, toText)
-{
+TEST_F(RRTypeTest, toText) {
     EXPECT_EQ("A", RRType(1).toText());
     EXPECT_EQ("TYPE65000", RRType(65000).toText());
 }
 
-TEST_F(RRTypeTest, toWireBuffer)
-{
+TEST_F(RRTypeTest, toWireBuffer) {
     rrtype_1.toWire(obuffer);
     rrtype_0x80.toWire(obuffer);
     rrtype_0x800.toWire(obuffer);
@@ -119,8 +113,7 @@
                         wiredata, sizeof(wiredata));
 }
 
-TEST_F(RRTypeTest, toWireRenderer)
-{
+TEST_F(RRTypeTest, toWireRenderer) {
     rrtype_1.toWire(renderer);
     rrtype_0x80.toWire(renderer);
     rrtype_0x800.toWire(renderer);
@@ -132,14 +125,12 @@
                         wiredata, sizeof(wiredata));
 }
 
-TEST_F(RRTypeTest, wellKnownTypes)
-{
+TEST_F(RRTypeTest, wellKnownTypes) {
     EXPECT_EQ(1, RRType::A().getCode());
     EXPECT_EQ("A", RRType::A().toText());
 }
 
-TEST_F(RRTypeTest, compare)
-{
+TEST_F(RRTypeTest, compare) {
     EXPECT_TRUE(RRType(1) == RRType("A"));
     EXPECT_TRUE(RRType(1).equals(RRType("A")));
     EXPECT_TRUE(RRType(0) != RRType("A"));
@@ -150,8 +141,7 @@
 }
 
 // test operator<<.  We simply confirm it appends the result of toText().
-TEST_F(RRTypeTest, LeftShiftOperator)
-{
+TEST_F(RRTypeTest, LeftShiftOperator) {
     ostringstream oss;
     oss << RRType::A();
     EXPECT_EQ(RRType::A().toText(), oss.str());

Modified: branches/trac292/src/lib/dns/tests/run_unittests.cc
==============================================================================
--- branches/trac292/src/lib/dns/tests/run_unittests.cc (original)
+++ branches/trac292/src/lib/dns/tests/run_unittests.cc Mon Oct 18 10:46:07 2010
@@ -21,7 +21,8 @@
 int
 main(int argc, char* argv[]) {
     ::testing::InitGoogleTest(&argc, argv);
-    isc::UnitTestUtil::addDataPath(TEST_DATA_DIR);
+    isc::UnitTestUtil::addDataPath(TEST_DATA_SRCDIR);
+    isc::UnitTestUtil::addDataPath(TEST_DATA_BUILDDIR);
 
     return (RUN_ALL_TESTS());
 }

Modified: branches/trac292/src/lib/dns/tests/testdata/gen-wiredata.py.in
==============================================================================
--- branches/trac292/src/lib/dns/tests/testdata/gen-wiredata.py.in (original)
+++ branches/trac292/src/lib/dns/tests/testdata/gen-wiredata.py.in Mon Oct 18 10:46:07 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/trac292/src/lib/dns/util/sha1.cc
==============================================================================
--- branches/trac292/src/lib/dns/util/sha1.cc (original)
+++ branches/trac292/src/lib/dns/util/sha1.cc Mon Oct 18 10:46:07 2010
@@ -312,8 +312,7 @@
  *   sha Error Code.
  *
  */
-static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte)
-{
+static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte) {
     int i;
     SHA1PadMessage(context, Pad_Byte);
     /* message may be sensitive, clear it out */
@@ -350,8 +349,7 @@
  *      Nothing.
  *
  */
-static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte)
-{
+static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte) {
     /*
      * Check to see if the current message block is too small to hold
      * the initial padding bits and length. If so, we will pad the

Modified: branches/trac292/src/lib/exceptions/exceptions.cc
==============================================================================
--- branches/trac292/src/lib/exceptions/exceptions.cc (original)
+++ branches/trac292/src/lib/exceptions/exceptions.cc Mon Oct 18 10:46:07 2010
@@ -23,8 +23,7 @@
 namespace isc {
 
 const char*
-Exception::what() const throw()
-{
+Exception::what() const throw() {
     const char* whatstr = "isc::Exception";
 
     // XXX: even though it's very unlikely that c_str() throws an exception,

Modified: branches/trac292/src/lib/exceptions/exceptions.h
==============================================================================
--- branches/trac292/src/lib/exceptions/exceptions.h (original)
+++ branches/trac292/src/lib/exceptions/exceptions.h Mon Oct 18 10:46:07 2010
@@ -103,20 +103,25 @@
     const std::string what_;
 };
 
-///
 /// \brief A generic exception that is thrown if a parameter given
 /// to a method would refer to or modify out-of-range data.
-///
 class OutOfRange : public Exception {
 public:
     OutOfRange(const char* file, size_t line, const char* what) :
         isc::Exception(file, line, what) {}
 };
 
-///
+/// \brief A generic exception that is thrown if a parameter given
+/// to a method or function is considered invalid and no other specific
+/// exceptions are suitable to describe the error.
+class InvalidParameter : public Exception {
+public:
+    InvalidParameter(const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) {}
+};
+
 /// \brief A generic exception that is thrown if a parameter given
 /// to a method is considered invalid in that context.
-///
 class BadValue : public Exception {
 public:
     BadValue(const char* file, size_t line, const char* what) :

Modified: branches/trac292/src/lib/exceptions/tests/run_unittests.cc
==============================================================================
--- branches/trac292/src/lib/exceptions/tests/run_unittests.cc (original)
+++ branches/trac292/src/lib/exceptions/tests/run_unittests.cc Mon Oct 18 10:46:07 2010
@@ -17,8 +17,7 @@
 #include <gtest/gtest.h>
 
 int
-main(int argc, char* argv[])
-{
+main(int argc, char* argv[]) {
     ::testing::InitGoogleTest(&argc, argv);
     return (RUN_ALL_TESTS());
 }

Modified: branches/trac292/src/lib/python/isc/Makefile.am
==============================================================================
--- branches/trac292/src/lib/python/isc/Makefile.am (original)
+++ branches/trac292/src/lib/python/isc/Makefile.am Mon Oct 18 10:46:07 2010
@@ -1,4 +1,4 @@
-SUBDIRS = datasrc cc config log notify # Util
+SUBDIRS = datasrc cc config log net notify utils # Util
 
 python_PYTHON = __init__.py
 

Modified: branches/trac292/src/lib/python/isc/cc/Makefile.am
==============================================================================
--- branches/trac292/src/lib/python/isc/cc/Makefile.am (original)
+++ branches/trac292/src/lib/python/isc/cc/Makefile.am Mon Oct 18 10:46:07 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 python_PYTHON =	__init__.py data.py session.py message.py
 

Modified: branches/trac292/src/lib/python/isc/cc/session.py
==============================================================================
--- branches/trac292/src/lib/python/isc/cc/session.py (original)
+++ branches/trac292/src/lib/python/isc/cc/session.py Mon Oct 18 10:46:07 2010
@@ -16,6 +16,7 @@
 import sys
 import socket
 import struct
+import errno
 import os
 import threading
 import bind10_config
@@ -25,21 +26,21 @@
 class ProtocolError(Exception): pass
 class NetworkError(Exception): pass
 class SessionError(Exception): pass
+class SessionTimeout(Exception): pass
 
 class Session:
+    MSGQ_DEFAULT_TIMEOUT = 4000
+    
     def __init__(self, socket_file=None):
         self._socket = None
-        # store the current timeout value in seconds (the way
-        # settimeout() wants them, our API takes milliseconds
-        # so that it is consistent with the C++ version)
-        self._socket_timeout = 4;
         self._lname = None
-        self._recvbuffer = bytearray()
-        self._recvlength = 0
         self._sequence = 1
         self._closed = False
         self._queue = []
         self._lock = threading.RLock()
+        self.set_timeout(self.MSGQ_DEFAULT_TIMEOUT);
+        self._recv_len_size = 0
+        self._recv_size = 0
 
         if socket_file is None:
             if "BIND10_MSGQ_SOCKET_FILE" in os.environ:
@@ -121,6 +122,43 @@
                     return isc.cc.message.from_wire(data[2:header_length+2]), None
             return None, None
 
+    def _receive_bytes(self, size):
+        """Try to get size bytes of data from the socket.
+           Raises a ProtocolError if the size is 0.
+           Raises any error from recv().
+           Returns whatever data was available (if >0 bytes).
+           """
+        data = self._socket.recv(size)
+        if len(data) == 0: # server closed connection
+            raise ProtocolError("Read of 0 bytes: connection closed")
+        return data
+        
+    def _receive_len_data(self):
+        """Reads self._recv_len_size bytes of data from the socket into
+           self._recv_len_data
+           This is done through class variables so in the case of
+           an EAGAIN we can continue on a subsequent call.
+           Raises a ProtocolError, a socket.error (which may be
+           timeout or eagain), or reads until we have all data we need.
+           """
+        while self._recv_len_size > 0:
+            new_data = self._receive_bytes(self._recv_len_size)
+            self._recv_len_data += new_data
+            self._recv_len_size -= len(new_data)
+
+    def _receive_data(self):
+        """Reads self._recv_size bytes of data from the socket into
+           self._recv_data.
+           This is done through class variables so in the case of
+           an EAGAIN we can continue on a subsequent call.
+           Raises a ProtocolError, a socket.error (which may be
+           timeout or eagain), or reads until we have all data we need.
+        """
+        while self._recv_size > 0:
+            new_data = self._receive_bytes(self._recv_size)
+            self._recv_data += new_data
+            self._recv_size -= len(new_data)
+
     def _receive_full_buffer(self, nonblock):
         if nonblock:
             self._socket.setblocking(0)
@@ -131,35 +169,47 @@
             else:
                 self._socket.settimeout(self._socket_timeout)
 
-        if self._recvlength == 0:
-            length = 4
-            length -= len(self._recvbuffer)
-            try:
-                data = self._socket.recv(length)
-            except:
+        try:
+            # we might be in a call following an EAGAIN, in which case
+            # we simply continue. In the first case, either
+            # recv_size or recv_len size are not zero
+            # they may never both be non-zero (we are either starting
+            # a full read, or continuing one of the reads
+            assert self._recv_size == 0 or self._recv_len_size == 0
+            
+            if self._recv_size == 0:
+                if self._recv_len_size == 0:
+                    # both zero, start a new full read
+                    self._recv_len_size = 4
+                    self._recv_len_data = bytearray()
+                self._receive_len_data()
+
+                self._recv_size = struct.unpack('>I', self._recv_len_data)[0]
+                self._recv_data = bytearray()
+            self._receive_data()
+
+            # no EAGAIN, so copy data and reset internal counters
+            data = self._recv_data
+
+            self._recv_len_size = 0
+            self._recv_size = 0
+
+            return (data)
+
+        except socket.timeout:
+            raise SessionTimeout("recv() on cc session timed out")
+        except socket.error as se:
+            # Only keep data in case of EAGAIN
+            if se.errno == errno.EAGAIN:
                 return None
-            if data == "": # server closed connection
-                raise ProtocolError("Read of 0 bytes: connection closed")
-            self._recvbuffer += data
-            if len(self._recvbuffer) < 4:
+            # unknown state otherwise, best to drop data
+            self._recv_len_size = 0
+            self._recv_size = 0
+            # ctrl-c can result in EINTR, return None to prevent
+            # stacktrace output
+            if se.errno == errno.EINTR:
                 return None
-            self._recvlength = struct.unpack('>I', self._recvbuffer)[0]
-            self._recvbuffer = bytearray()
-
-        length = self._recvlength - len(self._recvbuffer)
-        while (length > 0):
-            try:
-                data = self._socket.recv(length)
-            except:
-                return None
-            if data == "": # server closed connection
-                raise ProtocolError("Read of 0 bytes: connection closed")
-            self._recvbuffer += data
-            length -= len(data)
-        data = self._recvbuffer
-        self._recvbuffer = bytearray()
-        self._recvlength = 0
-        return (data)
+            raise se
 
     def _next_sequence(self):
         self._sequence += 1

Modified: branches/trac292/src/lib/python/isc/cc/tests/session_test.py
==============================================================================
--- branches/trac292/src/lib/python/isc/cc/tests/session_test.py (original)
+++ branches/trac292/src/lib/python/isc/cc/tests/session_test.py Mon Oct 18 10:46:07 2010
@@ -28,6 +28,7 @@
         self.type = type
         self.recvqueue = bytearray()
         self.sendqueue = bytearray()
+        self._blocking = True
 
     def connect(self, to):
         pass
@@ -36,7 +37,7 @@
         pass
 
     def setblocking(self, val):
-        pass
+        self._blocking = val
 
     def send(self, data):
         self.sendqueue.extend(data);
@@ -67,6 +68,11 @@
         return result
 
     def recv(self, length):
+        if len(self.recvqueue) == 0:
+            if self._blocking:
+                return bytes()
+            else:
+                raise socket.error(errno.EAGAIN, "Resource temporarily unavailable")
         if length > len(self.recvqueue):
             raise Exception("Buffer underrun in test, does the test provide the right data?")
         result = self.recvqueue[:length]
@@ -105,7 +111,8 @@
         self._socket_timeout = 1
         self._lname = None
         self._recvbuffer = bytearray()
-        self._recvlength = 0
+        self._recv_len_size = 0
+        self._recv_size = 0
         self._sequence = 1
         self._closed = False
         self._queue = []
@@ -192,10 +199,10 @@
         # get no message without asking for a specific sequence number reply
         self.assertFalse(sess.has_queued_msgs())
         sess._socket.addrecv({'to': 'someone', 'reply': 1}, {"hello": "a"})
-        env, msg = sess.recvmsg(False)
+        env, msg = sess.recvmsg(True)
         self.assertEqual(None, env)
         self.assertTrue(sess.has_queued_msgs())
-        env, msg = sess.recvmsg(False, 1)
+        env, msg = sess.recvmsg(True, 1)
         self.assertEqual({'to': 'someone', 'reply': 1}, env)
         self.assertEqual({"hello": "a"}, msg)
         self.assertFalse(sess.has_queued_msgs())
@@ -204,11 +211,11 @@
         # then ask for the one that is there
         self.assertFalse(sess.has_queued_msgs())
         sess._socket.addrecv({'to': 'someone', 'reply': 1}, {"hello": "a"})
-        env, msg = sess.recvmsg(False, 2)
+        env, msg = sess.recvmsg(True, 2)
         self.assertEqual(None, env)
         self.assertEqual(None, msg)
         self.assertTrue(sess.has_queued_msgs())
-        env, msg = sess.recvmsg(False, 1)
+        env, msg = sess.recvmsg(True, 1)
         self.assertEqual({'to': 'someone', 'reply': 1}, env)
         self.assertEqual({"hello": "a"}, msg)
         self.assertFalse(sess.has_queued_msgs())
@@ -217,11 +224,11 @@
         # then ask for any message
         self.assertFalse(sess.has_queued_msgs())
         sess._socket.addrecv({'to': 'someone', 'reply': 1}, {"hello": "a"})
-        env, msg = sess.recvmsg(False, 2)
+        env, msg = sess.recvmsg(True, 2)
         self.assertEqual(None, env)
         self.assertEqual(None, msg)
         self.assertTrue(sess.has_queued_msgs())
-        env, msg = sess.recvmsg(False, 1)
+        env, msg = sess.recvmsg(True, 1)
         self.assertEqual({'to': 'someone', 'reply': 1}, env)
         self.assertEqual({"hello": "a"}, msg)
         self.assertFalse(sess.has_queued_msgs())
@@ -233,16 +240,16 @@
         # then ask for any message (get the second)
         self.assertFalse(sess.has_queued_msgs())
         sess._socket.addrecv({'to': 'someone', 'reply': 1}, {'hello': 'a'})
-        env, msg = sess.recvmsg(False, 2)
+        env, msg = sess.recvmsg(True, 2)
         self.assertEqual(None, env)
         self.assertEqual(None, msg)
         self.assertTrue(sess.has_queued_msgs())
         sess._socket.addrecv({'to': 'someone' }, {'hello': 'b'})
-        env, msg = sess.recvmsg(False, 1)
+        env, msg = sess.recvmsg(True, 1)
         self.assertEqual({'to': 'someone', 'reply': 1 }, env)
         self.assertEqual({"hello": "a"}, msg)
         self.assertFalse(sess.has_queued_msgs())
-        env, msg = sess.recvmsg(False)
+        env, msg = sess.recvmsg(True)
         self.assertEqual({'to': 'someone'}, env)
         self.assertEqual({"hello": "b"}, msg)
         self.assertFalse(sess.has_queued_msgs())
@@ -253,11 +260,11 @@
         self.assertFalse(sess.has_queued_msgs())
         sess._socket.addrecv({'to': 'someone' }, {'hello': 'b'})
         sess._socket.addrecv({'to': 'someone', 'reply': 1}, {'hello': 'a'})
-        env, msg = sess.recvmsg(False, 1)
+        env, msg = sess.recvmsg(True, 1)
         self.assertEqual({'to': 'someone', 'reply': 1}, env)
         self.assertEqual({"hello": "a"}, msg)
         self.assertTrue(sess.has_queued_msgs())
-        env, msg = sess.recvmsg(False)
+        env, msg = sess.recvmsg(True)
         self.assertEqual({'to': 'someone'}, env)
         self.assertEqual({"hello": "b"}, msg)
         self.assertFalse(sess.has_queued_msgs())
@@ -353,9 +360,7 @@
             sess = MySession(1, s2)
             # set timeout to 100 msec, so test does not take too long
             sess.set_timeout(100)
-            env, msg = sess.group_recvmsg(False)
-            self.assertEqual(None, env)
-            self.assertEqual(None, msg)
+            self.assertRaises(SessionTimeout, sess.group_recvmsg, False)
         finally:
             os.remove(TEST_SOCKET_FILE)
 

Modified: branches/trac292/src/lib/python/isc/config/Makefile.am
==============================================================================
--- branches/trac292/src/lib/python/isc/config/Makefile.am (original)
+++ branches/trac292/src/lib/python/isc/config/Makefile.am Mon Oct 18 10:46:07 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 python_PYTHON = __init__.py ccsession.py cfgmgr.py config_data.py module_spec.py
 

Modified: branches/trac292/src/lib/python/isc/config/ccsession.py
==============================================================================
--- branches/trac292/src/lib/python/isc/config/ccsession.py (original)
+++ branches/trac292/src/lib/python/isc/config/ccsession.py Mon Oct 18 10:46:07 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,16 +170,28 @@
            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, nonblock = False):
+    def check_command(self, nonblock=True):
         """Check whether there is a command or configuration update on
-           the channel. Calls check_command_without_recvmsg() to parse
-           the received message."""
-        msg, env = self._session.group_recvmsg(nonblock)
+           the channel. This function does a read on the cc session, and
+           returns nothing.
+           It calls check_command_without_recvmsg()
+           to parse the received message.
+           
+           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)
         self.check_command_without_recvmsg(msg, env)
 
     def check_command_without_recvmsg(self, msg, env):
@@ -187,7 +200,7 @@
            functions if present. Responds on the channel if the
            handler returns a message.""" 
         # should we default to an answer? success-by-default? unhandled error?
-        if msg and not 'result' in msg:
+        if msg is not None and not 'result' in msg:
             answer = None
             try:
                 module_name = env['group']
@@ -251,6 +264,8 @@
            also subscribes to the channel of the remote module name
            to receive the relevant updates. It is not possible to
            specify your own handler for this right now.
+           start() must have been called on this CCSession
+           prior to the call to this method.
            Returns the name of the module."""
         module_spec = isc.config.module_spec_from_file(spec_file_name)
         module_cfg = ConfigData(module_spec)
@@ -259,7 +274,13 @@
 
         # Get the current config for that module now
         seq = self._session.group_sendmsg(create_command(COMMAND_GET_CONFIG, { "module_name": module_name }), "ConfigManager")
-        answer, env = self._session.group_recvmsg(False, seq)
+
+        try:
+            answer, env = self._session.group_recvmsg(False, seq)
+        except isc.cc.SessionTimeout:
+            raise ModuleCCSessionError("No answer from ConfigManager when "
+                                       "asking about Remote module " +
+                                       module_name)
         if answer:
             rcode, value = parse_answer(answer)
             if rcode == 0:
@@ -290,25 +311,32 @@
         """Sends the data specification to the configuration manager"""
         msg = create_command(COMMAND_MODULE_SPEC, self.get_module_spec().get_full_spec())
         seq = self._session.group_sendmsg(msg, "ConfigManager")
-        answer, env = self._session.group_recvmsg(False, seq)
+        try:
+            answer, env = self._session.group_recvmsg(False, seq)
+        except isc.cc.SessionTimeout:
+            # TODO: log an error?
+            pass
         
     def __request_config(self):
         """Asks the configuration manager for the current configuration, and call the config handler if set.
            Raises a ModuleCCSessionError if there is no answer from the configuration manager"""
         seq = self._session.group_sendmsg(create_command(COMMAND_GET_CONFIG, { "module_name": self._module_name }), "ConfigManager")
-        answer, env = self._session.group_recvmsg(False, seq)
-        if answer:
-            rcode, value = parse_answer(answer)
-            if rcode == 0:
-                if value != None and self.get_module_spec().validate_config(False, value):
-                    self.set_local_config(value);
-                    if self._config_handler:
-                        self._config_handler(value)
+        try:
+            answer, env = self._session.group_recvmsg(False, seq)
+            if answer:
+                rcode, value = parse_answer(answer)
+                if rcode == 0:
+                    if value != None and self.get_module_spec().validate_config(False, value):
+                        self.set_local_config(value);
+                        if self._config_handler:
+                            self._config_handler(value)
+                else:
+                    # log error
+                    print("[" + self._module_name + "] Error requesting configuration: " + value)
             else:
-                # log error
-                print("[" + self._module_name + "] Error requesting configuration: " + value)
-        else:
-            raise ModuleCCSessionError("No answer from configuration manager")
+                raise ModuleCCSessionError("No answer from configuration manager")
+        except isc.cc.SessionTimeout:
+            raise ModuleCCSessionError("CC Session timeout waiting for configuration manager")
 
 
 class UIModuleCCSession(MultiConfigData):

Modified: branches/trac292/src/lib/python/isc/config/cfgmgr.py
==============================================================================
--- branches/trac292/src/lib/python/isc/config/cfgmgr.py (original)
+++ branches/trac292/src/lib/python/isc/config/cfgmgr.py Mon Oct 18 10:46:07 2010
@@ -283,7 +283,10 @@
             update_cmd = ccsession.create_command(ccsession.COMMAND_CONFIG_UPDATE,
                                                   conf_part)
             seq = self.cc.group_sendmsg(update_cmd, module_name)
-            answer, env = self.cc.group_recvmsg(False, seq)
+            try:
+                answer, env = self.cc.group_recvmsg(False, seq)
+            except isc.cc.SessionTimeout:
+                answer = ccsession.create_answer(1, "Timeout waiting for answer from " + module_name)
         else:
             conf_part = data.set(self.config.data, module_name, {})
             data.merge(conf_part[module_name], cmd[1])
@@ -292,7 +295,10 @@
                                                   conf_part[module_name])
             seq = self.cc.group_sendmsg(update_cmd, module_name)
             # replace 'our' answer with that of the module
-            answer, env = self.cc.group_recvmsg(False, seq)
+            try:
+                answer, env = self.cc.group_recvmsg(False, seq)
+            except isc.cc.SessionTimeout:
+                answer = ccsession.create_answer(1, "Timeout waiting for answer from " + module_name)
         if answer:
             rcode, val = ccsession.parse_answer(answer)
             if rcode == 0:
@@ -313,15 +319,19 @@
                 update_cmd = ccsession.create_command(ccsession.COMMAND_CONFIG_UPDATE,
                                                       self.config.data[module])
                 seq = self.cc.group_sendmsg(update_cmd, module)
-                answer, env = self.cc.group_recvmsg(False, seq)
-                if answer == None:
+                try:
+                    answer, env = self.cc.group_recvmsg(False, seq)
+                    if answer == None:
+                        got_error = True
+                        err_list.append("No answer message from " + module)
+                    else:
+                        rcode, val = ccsession.parse_answer(answer)
+                        if rcode != 0:
+                            got_error = True
+                            err_list.append(val)
+                except isc.cc.SessionTimeout:
                     got_error = True
-                    err_list.append("No answer message from " + module)
-                else:
-                    rcode, val = ccsession.parse_answer(answer)
-                    if rcode != 0:
-                        got_error = True
-                        err_list.append(val)
+                    err_list.append("CC Timeout waiting on answer message from " + module)
         if not got_error:
             self.write_config()
             return ccsession.create_answer(0)
@@ -394,8 +404,13 @@
         """Runs the configuration manager."""
         self.running = True
         while (self.running):
+            # we just wait eternally for any command here, so disable
+            # timeouts for this specific recv
+            self.cc.set_timeout(0)
             msg, env = self.cc.group_recvmsg(False)
-            # ignore 'None' value (current result of timeout)
+            # and set it back to whatever we default to
+            self.cc.set_timeout(isc.cc.Session.MSGQ_DEFAULT_TIMEOUT)
+            # ignore 'None' value (even though they should not occur)
             # and messages that are answers to questions we did
             # not ask
             if msg is not None and not 'result' in msg:

Modified: branches/trac292/src/lib/python/isc/config/module_spec.py
==============================================================================
--- branches/trac292/src/lib/python/isc/config/module_spec.py (original)
+++ branches/trac292/src/lib/python/isc/config/module_spec.py Mon Oct 18 10:46:07 2010
@@ -316,7 +316,9 @@
     item_name = spec['item_name']
     item_optional = spec['item_optional']
 
-    if item_name in data:
+    if not data and item_optional:
+        return True
+    elif item_name in data:
         return _validate_item(spec, full, data[item_name], errors)
     elif full and not item_optional:
         if errors != None:

Modified: branches/trac292/src/lib/python/isc/config/tests/Makefile.am
==============================================================================
--- branches/trac292/src/lib/python/isc/config/tests/Makefile.am (original)
+++ branches/trac292/src/lib/python/isc/config/tests/Makefile.am Mon Oct 18 10:46:07 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/trac292/src/lib/python/isc/config/tests/ccsession_test.py
==============================================================================
--- branches/trac292/src/lib/python/isc/config/tests/ccsession_test.py (original)
+++ branches/trac292/src/lib/python/isc/config/tests/ccsession_test.py Mon Oct 18 10:46:07 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()
-        self.assertEqual(len(fake_session.message_queue), 1)
-        self.assertEqual({'result': [0]},
-                         fake_session.get_message('Spec2', None))
-        
+        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_check_command_without_recvmsg1(self):
         "copied from test_check_command2"
@@ -364,7 +409,7 @@
         self.assertEqual(len(fake_session.message_queue), 1)
         self.assertEqual({'result': [1, 'No config_data specification']},
                          fake_session.get_message('Spec1', None))
-        
+ 
     def test_check_command_without_recvmsg2(self):
         "copied from test_check_command3"
         fake_session = FakeModuleCCSession()
@@ -377,8 +422,8 @@
         mccs.check_command_without_recvmsg(cmd, env)
         self.assertEqual(len(fake_session.message_queue), 1)
         self.assertEqual({'result': [0]},
-                         fake_session.get_message('Spec2', None))
-     
+                          fake_session.get_message('Spec2', None))
+ 
     def test_check_command_without_recvmsg3(self):
         "copied from test_check_command7"
         fake_session = FakeModuleCCSession()
@@ -392,26 +437,21 @@
         self.assertEqual(len(fake_session.message_queue), 1)
         self.assertEqual({'result': [0]},
                          fake_session.get_message('Spec2', None))
-        
+ 
     def test_check_command_without_recvmsg_remote_module(self):
         "copied from test_check_command3"
         fake_session = FakeModuleCCSession()
-        mccs = self.create_session("spec1.spec", None, None, fake_session)
+        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)
         cmd = isc.config.ccsession.create_command(isc.config.ccsession.COMMAND_CONFIG_UPDATE, { 'Spec2': { 'item1': 2 }})
-
-        rmodname = mccs.add_remote_config(self.spec_file("spec2.spec"))
-
-        self.assertEqual({'command': ['get_config', {'module_name': 'Spec2'}]},
-                         fake_session.get_message('ConfigManager', None))
-
         env = { 'group':'Spec2', 'from':None }
         self.assertEqual(len(fake_session.message_queue), 0)
         mccs.check_command_without_recvmsg(cmd, env)
-        self.assertEqual(len(fake_session.message_queue), 0)
-        self.assertEqual(mccs.get_remote_config_value('Spec2', 'Spec2/item1'), (2, False))
-        
+        self.assertEqual(len(fake_session.message_queue), 1)
+        self.assertEqual({'result': [0]},
+                          fake_session.get_message('Spec2', None))
+ 
     def test_remote_module(self):
         fake_session = FakeModuleCCSession()
         mccs = self.create_session("spec1.spec", None, None, fake_session)
@@ -420,6 +460,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)
@@ -433,6 +474,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
@@ -443,6 +485,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/trac292/src/lib/python/isc/config/tests/cfgmgr_test.py
==============================================================================
--- branches/trac292/src/lib/python/isc/config/tests/cfgmgr_test.py (original)
+++ branches/trac292/src/lib/python/isc/config/tests/cfgmgr_test.py Mon Oct 18 10:46:07 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/trac292/src/lib/python/isc/config/tests/unittest_fakesession.py
==============================================================================
--- branches/trac292/src/lib/python/isc/config/tests/unittest_fakesession.py (original)
+++ branches/trac292/src/lib/python/isc/config/tests/unittest_fakesession.py Mon Oct 18 10:46:07 2010
@@ -15,6 +15,15 @@
 
 # $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
 #
@@ -24,6 +33,10 @@
         # each entry is of the form [ channel, instance, message ]
         self.message_queue = []
         self._socket = "ok we just need something not-None here atm"
+        # if self.timeout is set to anything other than 0, and
+        # the message_queue is empty when receive is called, throw
+        # a SessionTimeout
+        self._timeout = 0
 
     def group_subscribe(self, group_name, instance_name = None):
         if not group_name in self.subscriptions:
@@ -58,12 +71,21 @@
         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]}
-        return None, None
+        if self._timeout == 0:
+            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()")
 
     def get_message(self, channel, target = None):
         for qm in self.message_queue:
@@ -75,4 +97,9 @@
     def close(self):
         # need to pass along somehow that this function has been called,
         self._socket = "closed"
-        pass
+
+    def set_timeout(self, timeout):
+        self._timeout = timeout
+
+    def get_timeout(self):
+        return self._timeout

Modified: branches/trac292/src/lib/python/isc/log/Makefile.am
==============================================================================
--- branches/trac292/src/lib/python/isc/log/Makefile.am (original)
+++ branches/trac292/src/lib/python/isc/log/Makefile.am Mon Oct 18 10:46:07 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 python_PYTHON = __init__.py log.py
 

Modified: branches/trac292/src/lib/python/isc/log/log.py
==============================================================================
--- branches/trac292/src/lib/python/isc/log/log.py (original)
+++ branches/trac292/src/lib/python/isc/log/log.py Mon Oct 18 10:46:07 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/trac292/src/lib/python/isc/log/tests/log_test.py
==============================================================================
--- branches/trac292/src/lib/python/isc/log/tests/log_test.py (original)
+++ branches/trac292/src/lib/python/isc/log/tests/log_test.py Mon Oct 18 10:46:07 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()

Modified: branches/trac292/src/lib/python/isc/notify/Makefile.am
==============================================================================
--- branches/trac292/src/lib/python/isc/notify/Makefile.am (original)
+++ branches/trac292/src/lib/python/isc/notify/Makefile.am Mon Oct 18 10:46:07 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 python_PYTHON = __init__.py notify_out.py
 

Modified: branches/trac292/src/lib/xfr/python_xfr.cc
==============================================================================
--- branches/trac292/src/lib/xfr/python_xfr.cc (original)
+++ branches/trac292/src/lib/xfr/python_xfr.cc Mon Oct 18 10:46:07 2010
@@ -28,8 +28,7 @@
 using namespace isc::xfr;
 using namespace boost::python;
 
-BOOST_PYTHON_MODULE(bind10_xfr)
-{
+BOOST_PYTHON_MODULE(bind10_xfr) {
     def("recv_fd", &recv_fd);
     def("send_fd", &send_fd);
 }

Modified: branches/trac292/src/lib/xfr/xfrout_client.cc
==============================================================================
--- branches/trac292/src/lib/xfr/xfrout_client.cc (original)
+++ branches/trac292/src/lib/xfr/xfrout_client.cc Mon Oct 18 10:46:07 2010
@@ -47,8 +47,7 @@
     impl_(new XfroutClientImpl(file))
 {}
 
-XfroutClient::~XfroutClient()
-{
+XfroutClient::~XfroutClient() {
     delete impl_;
 }
 




More information about the bind10-changes mailing list