[svn] commit: r3131 - in /branches/trac301: ./ src/bin/ src/bin/auth/ src/bin/auth/benchmarks/ src/bin/auth/tests/ src/bin/auth/tests/testdata/ src/bin/bind10/ src/bin/bind10/tests/ src/bin/bindctl/ src/bin/cfgmgr/ src/bin/cmdctl/ src/bin/host/ src/bin/loadzone/ src/bin/msgq/ src/bin/tests/ src/bin/usermgr/ src/bin/xfrin/ src/bin/xfrout/ src/bin/zonemgr/ src/lib/bench/ src/lib/bench/tests/ src/lib/cc/tests/ src/lib/config/ src/lib/config/testdata/ src/lib/config/tests/ src/lib/config/tests/testdata/ src/lib/datasrc/ src/lib/datasrc/tests/ src/lib/dns/ src/lib/dns/python/ src/lib/dns/python/tests/ src/lib/dns/tests/ src/lib/dns/tests/testdata/ src/lib/exceptions/ src/lib/python/isc/ src/lib/python/isc/cc/ src/lib/python/isc/config/ src/lib/python/isc/config/tests/ src/lib/python/isc/log/ src/lib/python/isc/notify/ src/lib/python/isc/utils/

BIND 10 source code commits bind10-changes at lists.isc.org
Thu Oct 7 12:32:21 UTC 2010


Author: jinmei
Date: Thu Oct  7 12:32:20 2010
New Revision: 3131

Log:
sync with trunk

Added:
    branches/trac301/src/bin/auth/benchmarks/
      - copied from r3130, trunk/src/bin/auth/benchmarks/
    branches/trac301/src/bin/auth/tests/testdata/Makefile.am
      - copied unchanged from r3130, trunk/src/bin/auth/tests/testdata/Makefile.am
    branches/trac301/src/bin/tests/
      - copied from r3130, trunk/src/bin/tests/
    branches/trac301/src/lib/config/tests/testdata/
      - copied from r3130, trunk/src/lib/config/tests/testdata/
    branches/trac301/src/lib/dns/edns.cc
      - copied unchanged from r3130, trunk/src/lib/dns/edns.cc
    branches/trac301/src/lib/dns/edns.h
      - copied unchanged from r3130, trunk/src/lib/dns/edns.h
    branches/trac301/src/lib/dns/opcode.cc
      - copied unchanged from r3130, trunk/src/lib/dns/opcode.cc
    branches/trac301/src/lib/dns/opcode.h
      - copied unchanged from r3130, trunk/src/lib/dns/opcode.h
    branches/trac301/src/lib/dns/python/edns_python.cc
      - copied unchanged from r3130, trunk/src/lib/dns/python/edns_python.cc
    branches/trac301/src/lib/dns/python/opcode_python.cc
      - copied unchanged from r3130, trunk/src/lib/dns/python/opcode_python.cc
    branches/trac301/src/lib/dns/python/rcode_python.cc
      - copied unchanged from r3130, trunk/src/lib/dns/python/rcode_python.cc
    branches/trac301/src/lib/dns/python/tests/edns_python_test.py
      - copied unchanged from r3130, trunk/src/lib/dns/python/tests/edns_python_test.py
    branches/trac301/src/lib/dns/python/tests/opcode_python_test.py
      - copied unchanged from r3130, trunk/src/lib/dns/python/tests/opcode_python_test.py
    branches/trac301/src/lib/dns/python/tests/rcode_python_test.py
      - copied unchanged from r3130, trunk/src/lib/dns/python/tests/rcode_python_test.py
    branches/trac301/src/lib/dns/python/tests/testutil.py
      - copied unchanged from r3130, trunk/src/lib/dns/python/tests/testutil.py
    branches/trac301/src/lib/dns/rcode.cc
      - copied unchanged from r3130, trunk/src/lib/dns/rcode.cc
    branches/trac301/src/lib/dns/rcode.h
      - copied unchanged from r3130, trunk/src/lib/dns/rcode.h
    branches/trac301/src/lib/dns/tests/edns_unittest.cc
      - copied unchanged from r3130, trunk/src/lib/dns/tests/edns_unittest.cc
    branches/trac301/src/lib/dns/tests/opcode_unittest.cc
      - copied unchanged from r3130, trunk/src/lib/dns/tests/opcode_unittest.cc
    branches/trac301/src/lib/dns/tests/rcode_unittest.cc
      - copied unchanged from r3130, trunk/src/lib/dns/tests/rcode_unittest.cc
    branches/trac301/src/lib/dns/tests/testdata/Makefile.am
      - copied unchanged from r3130, trunk/src/lib/dns/tests/testdata/Makefile.am
    branches/trac301/src/lib/dns/tests/testdata/edns_toWire1.spec
      - copied unchanged from r3130, trunk/src/lib/dns/tests/testdata/edns_toWire1.spec
    branches/trac301/src/lib/dns/tests/testdata/edns_toWire2.spec
      - copied unchanged from r3130, trunk/src/lib/dns/tests/testdata/edns_toWire2.spec
    branches/trac301/src/lib/dns/tests/testdata/edns_toWire3.spec
      - copied unchanged from r3130, trunk/src/lib/dns/tests/testdata/edns_toWire3.spec
    branches/trac301/src/lib/dns/tests/testdata/edns_toWire4.spec
      - copied unchanged from r3130, trunk/src/lib/dns/tests/testdata/edns_toWire4.spec
    branches/trac301/src/lib/python/isc/utils/
      - copied from r3130, trunk/src/lib/python/isc/utils/
Removed:
    branches/trac301/src/bin/auth/tests/testdata/badExampleQuery_fromWire
    branches/trac301/src/bin/auth/tests/testdata/examplequery_fromWire
    branches/trac301/src/bin/auth/tests/testdata/iqueryresponse_fromWire
    branches/trac301/src/bin/auth/tests/testdata/multiquestion_fromWire
    branches/trac301/src/bin/auth/tests/testdata/queryBadEDNS_fromWire
    branches/trac301/src/bin/auth/tests/testdata/shortanswer_fromWire
    branches/trac301/src/bin/auth/tests/testdata/simplequery_fromWire
    branches/trac301/src/bin/auth/tests/testdata/simpleresponse_fromWire
    branches/trac301/src/lib/config/testdata/Makefile.am
    branches/trac301/src/lib/config/testdata/b10-config-bad1.db
    branches/trac301/src/lib/config/testdata/b10-config-bad2.db
    branches/trac301/src/lib/config/testdata/b10-config-bad3.db
    branches/trac301/src/lib/config/testdata/b10-config-bad4.db
    branches/trac301/src/lib/config/testdata/b10-config.db.master
    branches/trac301/src/lib/config/testdata/data22_1.data
    branches/trac301/src/lib/config/testdata/data22_2.data
    branches/trac301/src/lib/config/testdata/data22_3.data
    branches/trac301/src/lib/config/testdata/data22_4.data
    branches/trac301/src/lib/config/testdata/data22_5.data
    branches/trac301/src/lib/config/testdata/data22_6.data
    branches/trac301/src/lib/config/testdata/data22_7.data
    branches/trac301/src/lib/config/testdata/data22_8.data
    branches/trac301/src/lib/config/testdata/spec1.spec
    branches/trac301/src/lib/config/testdata/spec10.spec
    branches/trac301/src/lib/config/testdata/spec11.spec
    branches/trac301/src/lib/config/testdata/spec12.spec
    branches/trac301/src/lib/config/testdata/spec13.spec
    branches/trac301/src/lib/config/testdata/spec14.spec
    branches/trac301/src/lib/config/testdata/spec15.spec
    branches/trac301/src/lib/config/testdata/spec16.spec
    branches/trac301/src/lib/config/testdata/spec17.spec
    branches/trac301/src/lib/config/testdata/spec18.spec
    branches/trac301/src/lib/config/testdata/spec19.spec
    branches/trac301/src/lib/config/testdata/spec2.spec
    branches/trac301/src/lib/config/testdata/spec20.spec
    branches/trac301/src/lib/config/testdata/spec21.spec
    branches/trac301/src/lib/config/testdata/spec22.spec
    branches/trac301/src/lib/config/testdata/spec23.spec
    branches/trac301/src/lib/config/testdata/spec24.spec
    branches/trac301/src/lib/config/testdata/spec25.spec
    branches/trac301/src/lib/config/testdata/spec26.spec
    branches/trac301/src/lib/config/testdata/spec27.spec
    branches/trac301/src/lib/config/testdata/spec28.spec
    branches/trac301/src/lib/config/testdata/spec3.spec
    branches/trac301/src/lib/config/testdata/spec4.spec
    branches/trac301/src/lib/config/testdata/spec5.spec
    branches/trac301/src/lib/config/testdata/spec6.spec
    branches/trac301/src/lib/config/testdata/spec7.spec
    branches/trac301/src/lib/config/testdata/spec8.spec
    branches/trac301/src/lib/config/testdata/spec9.spec
    branches/trac301/src/lib/dns/message_test.py
    branches/trac301/src/lib/dns/tests/testdata/message_fromWire10
    branches/trac301/src/lib/dns/tests/testdata/message_fromWire11
    branches/trac301/src/lib/dns/tests/testdata/name_toWire5
    branches/trac301/src/lib/dns/tests/testdata/name_toWire6
    branches/trac301/src/lib/dns/tests/testdata/rdata_nsec_fromWire10
    branches/trac301/src/lib/dns/tests/testdata/rdata_nsec_fromWire4
    branches/trac301/src/lib/dns/tests/testdata/rdata_nsec_fromWire5
    branches/trac301/src/lib/dns/tests/testdata/rdata_nsec_fromWire6
    branches/trac301/src/lib/dns/tests/testdata/rdata_nsec_fromWire7
    branches/trac301/src/lib/dns/tests/testdata/rdata_nsec_fromWire8
    branches/trac301/src/lib/dns/tests/testdata/rdata_nsec_fromWire9
    branches/trac301/src/lib/dns/tests/testdata/rdata_rrsig_fromWire2
    branches/trac301/src/lib/dns/tests/testdata/rdata_soa_toWireUncompressed
    branches/trac301/src/lib/dns/tests/testdata/rdata_txt_fromWire2
    branches/trac301/src/lib/dns/tests/testdata/rdata_txt_fromWire3
    branches/trac301/src/lib/dns/tests/testdata/rdata_txt_fromWire4
    branches/trac301/src/lib/dns/tests/testdata/rdata_txt_fromWire5
Modified:
    branches/trac301/   (props changed)
    branches/trac301/ChangeLog
    branches/trac301/configure.ac
    branches/trac301/src/bin/Makefile.am
    branches/trac301/src/bin/auth/Makefile.am
    branches/trac301/src/bin/auth/asio_link.cc
    branches/trac301/src/bin/auth/auth_srv.cc
    branches/trac301/src/bin/auth/auth_srv.h
    branches/trac301/src/bin/auth/tests/Makefile.am
    branches/trac301/src/bin/auth/tests/auth_srv_unittest.cc
    branches/trac301/src/bin/auth/tests/run_unittests.cc
    branches/trac301/src/bin/bind10/Makefile.am
    branches/trac301/src/bin/bind10/bind10.8
    branches/trac301/src/bin/bind10/bind10.py.in
    branches/trac301/src/bin/bind10/bind10.xml
    branches/trac301/src/bin/bind10/tests/args_test.py
    branches/trac301/src/bin/bindctl/Makefile.am
    branches/trac301/src/bin/bindctl/bindctl-source.py.in
    branches/trac301/src/bin/cfgmgr/Makefile.am
    branches/trac301/src/bin/cfgmgr/b10-cfgmgr.py.in
    branches/trac301/src/bin/cmdctl/Makefile.am
    branches/trac301/src/bin/cmdctl/cmdctl.py.in
    branches/trac301/src/bin/host/host.cc
    branches/trac301/src/bin/loadzone/Makefile.am
    branches/trac301/src/bin/loadzone/b10-loadzone.py.in
    branches/trac301/src/bin/msgq/Makefile.am
    branches/trac301/src/bin/msgq/msgq.py.in
    branches/trac301/src/bin/usermgr/b10-cmdctl-usermgr.py.in
    branches/trac301/src/bin/xfrin/Makefile.am
    branches/trac301/src/bin/xfrin/TODO
    branches/trac301/src/bin/xfrin/xfrin.py.in
    branches/trac301/src/bin/xfrout/Makefile.am
    branches/trac301/src/bin/xfrout/TODO
    branches/trac301/src/bin/xfrout/xfrout.py.in
    branches/trac301/src/bin/zonemgr/Makefile.am
    branches/trac301/src/bin/zonemgr/TODO
    branches/trac301/src/bin/zonemgr/zonemgr.py.in
    branches/trac301/src/lib/bench/benchmark_util.cc
    branches/trac301/src/lib/bench/tests/loadquery_unittest.cc
    branches/trac301/src/lib/cc/tests/Makefile.am
    branches/trac301/src/lib/config/Makefile.am
    branches/trac301/src/lib/config/tests/Makefile.am
    branches/trac301/src/lib/config/tests/data_def_unittests_config.h.in
    branches/trac301/src/lib/datasrc/data_source.cc
    branches/trac301/src/lib/datasrc/tests/datasrc_unittest.cc
    branches/trac301/src/lib/datasrc/tests/query_unittest.cc
    branches/trac301/src/lib/dns/Makefile.am
    branches/trac301/src/lib/dns/exceptions.cc
    branches/trac301/src/lib/dns/message.cc
    branches/trac301/src/lib/dns/message.h
    branches/trac301/src/lib/dns/python/Makefile.am
    branches/trac301/src/lib/dns/python/message_python.cc
    branches/trac301/src/lib/dns/python/messagerenderer_python.cc
    branches/trac301/src/lib/dns/python/name_python.cc
    branches/trac301/src/lib/dns/python/pydnspp.cc
    branches/trac301/src/lib/dns/python/question_python.cc
    branches/trac301/src/lib/dns/python/rdata_python.cc
    branches/trac301/src/lib/dns/python/rrclass_python.cc
    branches/trac301/src/lib/dns/python/rrset_python.cc
    branches/trac301/src/lib/dns/python/rrttl_python.cc
    branches/trac301/src/lib/dns/python/rrtype_python.cc
    branches/trac301/src/lib/dns/python/tests/Makefile.am
    branches/trac301/src/lib/dns/python/tests/message_python_test.py
    branches/trac301/src/lib/dns/python/tests/messagerenderer_python_test.py
    branches/trac301/src/lib/dns/python/tests/question_python_test.py
    branches/trac301/src/lib/dns/rrclass-placeholder.h
    branches/trac301/src/lib/dns/rrset.h
    branches/trac301/src/lib/dns/rrtype-placeholder.h
    branches/trac301/src/lib/dns/tests/Makefile.am
    branches/trac301/src/lib/dns/tests/message_unittest.cc
    branches/trac301/src/lib/dns/tests/messagerenderer_unittest.cc
    branches/trac301/src/lib/dns/tests/rdata_nsec_unittest.cc
    branches/trac301/src/lib/dns/tests/rdata_rrsig_unittest.cc
    branches/trac301/src/lib/dns/tests/rdata_soa_unittest.cc
    branches/trac301/src/lib/dns/tests/rdata_txt_unittest.cc
    branches/trac301/src/lib/dns/tests/run_unittests.cc
    branches/trac301/src/lib/dns/tests/testdata/gen-wiredata.py.in
    branches/trac301/src/lib/exceptions/exceptions.h
    branches/trac301/src/lib/python/isc/Makefile.am
    branches/trac301/src/lib/python/isc/cc/Makefile.am
    branches/trac301/src/lib/python/isc/config/Makefile.am
    branches/trac301/src/lib/python/isc/config/tests/Makefile.am
    branches/trac301/src/lib/python/isc/log/Makefile.am
    branches/trac301/src/lib/python/isc/notify/Makefile.am

Modified: branches/trac301/ChangeLog
==============================================================================
--- branches/trac301/ChangeLog (original)
+++ branches/trac301/ChangeLog Thu Oct  7 12:32:20 2010
@@ -1,3 +1,39 @@
+  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)
@@ -24,7 +60,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.

Modified: branches/trac301/configure.ac
==============================================================================
--- branches/trac301/configure.ac (original)
+++ branches/trac301/configure.ac Thu Oct  7 12:32:20 2010
@@ -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
@@ -270,14 +295,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 +393,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,10 +434,6 @@
 	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)
 
@@ -423,6 +464,8 @@
                  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
@@ -430,6 +473,7 @@
                  src/bin/zonemgr/Makefile
                  src/bin/zonemgr/tests/Makefile
                  src/bin/usermgr/Makefile
+                 src/bin/tests/Makefile
                  src/lib/Makefile
                  src/lib/bench/Makefile
                  src/lib/bench/example/Makefile
@@ -438,6 +482,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
@@ -449,9 +495,10 @@
                  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
@@ -495,6 +542,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
@@ -543,7 +591,6 @@
 Flags:
   DEFS:          $DEFS
   CPPFLAGS:      $CPPFLAGS
-  CFLAGS:        $CFLAGS
   CXXFLAGS:      $CXXFLAGS
   B10_CXXFLAGS:  $B10_CXXFLAGS
 dnl includes too

Modified: branches/trac301/src/bin/Makefile.am
==============================================================================
--- branches/trac301/src/bin/Makefile.am (original)
+++ branches/trac301/src/bin/Makefile.am Thu Oct  7 12:32:20 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 tests
+
+check-recursive: all-recursive

Modified: branches/trac301/src/bin/auth/Makefile.am
==============================================================================
--- branches/trac301/src/bin/auth/Makefile.am (original)
+++ branches/trac301/src/bin/auth/Makefile.am Thu Oct  7 12:32:20 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/trac301/src/bin/auth/asio_link.cc
==============================================================================
--- branches/trac301/src/bin/auth/asio_link.cc (original)
+++ branches/trac301/src/bin/auth/asio_link.cc Thu Oct  7 12:32:20 2010
@@ -75,7 +75,7 @@
 /// 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
+/// a big deal, but when we receive UDP packets at a high rate, the copy
 /// overhead might be significant.
 class TCPEndpoint : public IOEndpoint {
 public:

Modified: branches/trac301/src/bin/auth/auth_srv.cc
==============================================================================
--- branches/trac301/src/bin/auth/auth_srv.cc (original)
+++ branches/trac301/src/bin/auth/auth_srv.cc Thu Oct  7 12:32:20 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());
     }
@@ -190,6 +192,16 @@
 bool
 AuthSrv::getVerbose() const {
     return (impl_->verbose_mode_);
+}
+
+void
+AuthSrv::setCacheSlots(const size_t slots) {
+    impl_->cache_.setSlots(slots);
+}
+
+size_t
+AuthSrv::getCacheSlots() const {
+    return (impl_->cache_.getSlots());
 }
 
 void
@@ -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/trac301/src/bin/auth/auth_srv.h
==============================================================================
--- branches/trac301/src/bin/auth/auth_srv.h (original)
+++ branches/trac301/src/bin/auth/auth_srv.h Thu Oct  7 12:32:20 2010
@@ -162,6 +162,26 @@
     /// 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.
     ///

Modified: branches/trac301/src/bin/auth/tests/Makefile.am
==============================================================================
--- branches/trac301/src/bin/auth/tests/Makefile.am (original)
+++ branches/trac301/src/bin/auth/tests/Makefile.am Thu Oct  7 12:32:20 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=\"$(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/trac301/src/bin/auth/tests/auth_srv_unittest.cc
==============================================================================
--- branches/trac301/src/bin/auth/tests/auth_srv_unittest.cc (original)
+++ branches/trac301/src/bin/auth/tests/auth_srv_unittest.cc Thu Oct  7 12:32:20 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/trac301/src/bin/auth/tests/run_unittests.cc
==============================================================================
--- branches/trac301/src/bin/auth/tests/run_unittests.cc (original)
+++ branches/trac301/src/bin/auth/tests/run_unittests.cc Thu Oct  7 12:32:20 2010
@@ -23,6 +23,7 @@
 {
     ::testing::InitGoogleTest(&argc, argv);
     isc::UnitTestUtil::addDataPath(TEST_DATA_DIR);
+    isc::UnitTestUtil::addDataPath(TEST_DATA_BUILDDIR);
 
     return (RUN_ALL_TESTS());
 }

Modified: branches/trac301/src/bin/bind10/Makefile.am
==============================================================================
--- branches/trac301/src/bin/bind10/Makefile.am (original)
+++ branches/trac301/src/bin/bind10/Makefile.am Thu Oct  7 12:32:20 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 sbin_SCRIPTS = bind10
 CLEANFILES = bind10 bind10.pyc

Modified: branches/trac301/src/bin/bind10/bind10.8
==============================================================================
--- branches/trac301/src/bin/bind10/bind10.8 (original)
+++ branches/trac301/src/bin/bind10/bind10.8 Thu Oct  7 12:32:20 2010
@@ -1,13 +1,22 @@
 '\" t
 .\"     Title: bind10
 .\"    Author: [see the "AUTHORS" section]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\" Generator: DocBook XSL Stylesheets v1.76.0 <http://docbook.sf.net/>
 .\"      Date: July 29, 2010
 .\"    Manual: BIND10
 .\"    Source: BIND10
 .\"  Language: English
 .\"
 .TH "BIND10" "8" "July 29, 2010" "BIND10" "BIND10"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
@@ -22,7 +31,7 @@
 bind10 \- BIND 10 boss process
 .SH "SYNOPSIS"
 .HP \w'\fBbind10\fR\ 'u
-\fBbind10\fR [\fB\-a\ \fR\fB\fIaddress\fR\fR] [\fB\-m\ \fR\fB\fIfile\fR\fR] [\fB\-n\fR] [\fB\-p\ \fR\fB\fInumber\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-\-address\ \fR\fB\fIaddress\fR\fR] [\fB\-\-msgq\-socket\-file\ \fR\fB\fIfile\fR\fR] [\fB\-\-no\-cache\fR] [\fB\-\-port\ \fR\fB\fInumber\fR\fR] [\fB\-\-user\ \fR\fB\fIuser\fR\fR] [\fB\-\-verbose\fR]
+\fBbind10\fR [\fB\-a\ \fR\fB\fIaddress\fR\fR] [\fB\-m\ \fR\fB\fIfile\fR\fR] [\fB\-n\fR] [\fB\-p\ \fR\fB\fInumber\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-\-address\ \fR\fB\fIaddress\fR\fR] [\fB\-\-msgq\-socket\-file\ \fR\fB\fIfile\fR\fR] [\fB\-\-no\-cache\fR] [\fB\-\-port\ \fR\fB\fInumber\fR\fR] [\fB\-\-user\ \fR\fB\fIuser\fR\fR] [\fB\-\-pretty\-name\ \fR\fB\fIname\fR\fR] [\fB\-\-verbose\fR]
 .SH "DESCRIPTION"
 .PP
 The
@@ -86,6 +95,15 @@
 must be initially ran as the root user to use this option\&. The default is to run as the current user\&.
 .RE
 .PP
+\fB\-\-pretty\-name \fR\fB\fIname\fR\fR
+.RS 4
+The name this process should have in tools like
+\fBps\fR
+or
+\fBtop\fR\&. This is handy if you have multiple versions/installations of
+\fBbind10\fR\&.
+.RE
+.PP
 \fB\-v\fR, \fB\-\-verbose\fR
 .RS 4
 Display more about what is going on for

Modified: branches/trac301/src/bin/bind10/bind10.py.in
==============================================================================
--- branches/trac301/src/bin/bind10/bind10.py.in (original)
+++ branches/trac301/src/bin/bind10/bind10.py.in Thu Oct  7 12:32:20 2010
@@ -63,6 +63,10 @@
 import posix
 
 import isc.cc
+import isc.utils.process
+
+# Assign this process some longer name
+isc.utils.process.rename(sys.argv[0])
 
 # This is the version that gets displayed to the user.
 # The VERSION string consists of the module name, the module version
@@ -620,7 +624,11 @@
         parser.values.address = value
     else:
         raise OptionValueError("Unknown option " + opt_str)
-  
+
+def process_rename(option, opt_str, value, parser):
+    """Function that renames the process if it is requested by a option."""
+    isc.utils.process.rename(value)
+
 def main():
     global options
     global boss_of_bind
@@ -646,6 +654,9 @@
                       help="Change user after startup (must run as root)")
     parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
                       help="display more about what is going on")
+    parser.add_option("--pretty-name", type="string", action="callback",
+                      callback=process_rename,
+                      help="Set the process name (displayed in ps, top, ...)")
     (options, args) = parser.parse_args()
     if args:
         parser.print_help()

Modified: branches/trac301/src/bin/bind10/bind10.xml
==============================================================================
--- branches/trac301/src/bin/bind10/bind10.xml (original)
+++ branches/trac301/src/bin/bind10/bind10.xml Thu Oct  7 12:32:20 2010
@@ -56,6 +56,7 @@
       <arg><option>--no-cache</option></arg>
       <arg><option>--port <replaceable>number</replaceable></option></arg>
       <arg><option>--user <replaceable>user</replaceable></option></arg>
+      <arg><option>--pretty-name <replaceable>name</replaceable></option></arg>
       <arg><option>--verbose</option></arg>
     </cmdsynopsis>
   </refsynopsisdiv>
@@ -149,6 +150,17 @@
       </varlistentry>
 
       <varlistentry>
+        <term><option>--pretty-name <replaceable>name</replaceable></option></term>
+
+        <listitem>
+          <para>The name this process should have in tools like
+          <command>ps</command> or <command>top</command>. This
+          is handy if you have multiple versions/installations
+          of <command>bind10</command>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><option>-v</option>, <option>--verbose</option></term>
         <listitem>
 	  <para>Display more about what is going on for

Modified: branches/trac301/src/bin/bind10/tests/args_test.py
==============================================================================
--- branches/trac301/src/bin/bind10/tests/args_test.py (original)
+++ branches/trac301/src/bin/bind10/tests/args_test.py Thu Oct  7 12:32:20 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/trac301/src/bin/bindctl/Makefile.am
==============================================================================
--- branches/trac301/src/bin/bindctl/Makefile.am (original)
+++ branches/trac301/src/bin/bindctl/Makefile.am Thu Oct  7 12:32:20 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 bin_SCRIPTS = bindctl
 man_MANS = bindctl.1

Modified: branches/trac301/src/bin/bindctl/bindctl-source.py.in
==============================================================================
--- branches/trac301/src/bin/bindctl/bindctl-source.py.in (original)
+++ branches/trac301/src/bin/bindctl/bindctl-source.py.in Thu Oct  7 12:32:20 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/trac301/src/bin/cfgmgr/Makefile.am
==============================================================================
--- branches/trac301/src/bin/cfgmgr/Makefile.am (original)
+++ branches/trac301/src/bin/cfgmgr/Makefile.am Thu Oct  7 12:32:20 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 pkglibexecdir = $(libexecdir)/@PACKAGE@
 

Modified: branches/trac301/src/bin/cfgmgr/b10-cfgmgr.py.in
==============================================================================
--- branches/trac301/src/bin/cfgmgr/b10-cfgmgr.py.in (original)
+++ branches/trac301/src/bin/cfgmgr/b10-cfgmgr.py.in Thu Oct  7 12:32:20 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/trac301/src/bin/cmdctl/Makefile.am
==============================================================================
--- branches/trac301/src/bin/cmdctl/Makefile.am (original)
+++ branches/trac301/src/bin/cmdctl/Makefile.am Thu Oct  7 12:32:20 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 pkglibexecdir = $(libexecdir)/@PACKAGE@
 

Modified: branches/trac301/src/bin/cmdctl/cmdctl.py.in
==============================================================================
--- branches/trac301/src/bin/cmdctl/cmdctl.py.in (original)
+++ branches/trac301/src/bin/cmdctl/cmdctl.py.in Thu Oct  7 12:32:20 2010
@@ -42,12 +42,15 @@
 import time
 import signal
 from isc.config import ccsession
+import isc.utils.process
 from optparse import OptionParser, OptionValueError
 from hashlib import sha1
 try:
     import threading
 except ImportError:
     import dummy_threading as threading
+
+isc.utils.process.rename()
 
 __version__ = 'BIND10'
 URL_PATTERN = re.compile('/([\w]+)(?:/([\w]+))?/?')

Modified: branches/trac301/src/bin/host/host.cc
==============================================================================
--- branches/trac301/src/bin/host/host.cc (original)
+++ branches/trac301/src/bin/host/host.cc Thu Oct  7 12:32:20 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/trac301/src/bin/loadzone/Makefile.am
==============================================================================
--- branches/trac301/src/bin/loadzone/Makefile.am (original)
+++ branches/trac301/src/bin/loadzone/Makefile.am Thu Oct  7 12:32:20 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/trac301/src/bin/loadzone/b10-loadzone.py.in
==============================================================================
--- branches/trac301/src/bin/loadzone/b10-loadzone.py.in (original)
+++ branches/trac301/src/bin/loadzone/b10-loadzone.py.in Thu Oct  7 12:32:20 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/trac301/src/bin/msgq/Makefile.am
==============================================================================
--- branches/trac301/src/bin/msgq/Makefile.am (original)
+++ branches/trac301/src/bin/msgq/Makefile.am Thu Oct  7 12:32:20 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 pkglibexecdir = $(libexecdir)/@PACKAGE@
  

Modified: branches/trac301/src/bin/msgq/msgq.py.in
==============================================================================
--- branches/trac301/src/bin/msgq/msgq.py.in (original)
+++ branches/trac301/src/bin/msgq/msgq.py.in Thu Oct  7 12:32:20 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/trac301/src/bin/usermgr/b10-cmdctl-usermgr.py.in
==============================================================================
--- branches/trac301/src/bin/usermgr/b10-cmdctl-usermgr.py.in (original)
+++ branches/trac301/src/bin/usermgr/b10-cmdctl-usermgr.py.in Thu Oct  7 12:32:20 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/trac301/src/bin/xfrin/Makefile.am
==============================================================================
--- branches/trac301/src/bin/xfrin/Makefile.am (original)
+++ branches/trac301/src/bin/xfrin/Makefile.am Thu Oct  7 12:32:20 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 pkglibexecdir = $(libexecdir)/@PACKAGE@
 

Modified: branches/trac301/src/bin/xfrin/TODO
==============================================================================
--- branches/trac301/src/bin/xfrin/TODO (original)
+++ branches/trac301/src/bin/xfrin/TODO Thu Oct  7 12:32:20 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/trac301/src/bin/xfrin/xfrin.py.in
==============================================================================
--- branches/trac301/src/bin/xfrin/xfrin.py.in (original)
+++ branches/trac301/src/bin/xfrin/xfrin.py.in Thu Oct  7 12:32:20 2010
@@ -29,12 +29,15 @@
 from optparse import OptionParser, OptionValueError
 from isc.config.ccsession import *
 from isc.notify import notify_out
+import isc.utils.process
 try:
     from pydnspp import *
 except ImportError as e:
     # C++ loadable module may not be installed; even so the xfrin process
     # must keep running, so we warn about it and move forward.
     sys.stderr.write('[b10-xfrin] failed to import DNS module: %s\n' % str(e))
+
+isc.utils.process.rename()
 
 # If B10_FROM_BUILD is set in the environment, we use data files
 # from a directory relative to that, otherwise we use the ones

Modified: branches/trac301/src/bin/xfrout/Makefile.am
==============================================================================
--- branches/trac301/src/bin/xfrout/Makefile.am (original)
+++ branches/trac301/src/bin/xfrout/Makefile.am Thu Oct  7 12:32:20 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 pkglibexecdir = $(libexecdir)/@PACKAGE@
 

Modified: branches/trac301/src/bin/xfrout/TODO
==============================================================================
--- branches/trac301/src/bin/xfrout/TODO (original)
+++ branches/trac301/src/bin/xfrout/TODO Thu Oct  7 12:32:20 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/trac301/src/bin/xfrout/xfrout.py.in
==============================================================================
--- branches/trac301/src/bin/xfrout/xfrout.py.in (original)
+++ branches/trac301/src/bin/xfrout/xfrout.py.in Thu Oct  7 12:32:20 2010
@@ -29,6 +29,7 @@
 from isc.log.log import *
 from isc.cc import SessionError, SessionTimeout
 from isc.notify import notify_out
+import isc.utils.process
 import socket
 import select
 import errno
@@ -40,6 +41,8 @@
     # C++ loadable module may not be installed; even so the xfrout process
     # must keep running, so we warn about it and move forward.
     sys.stderr.write('[b10-xfrout] failed to import DNS or XFR module: %s\n' % str(e))
+
+isc.utils.process.rename()
 
 if "B10_FROM_BUILD" in os.environ:
     SPECFILE_PATH = os.environ["B10_FROM_BUILD"] + "/src/bin/xfrout"

Modified: branches/trac301/src/bin/zonemgr/Makefile.am
==============================================================================
--- branches/trac301/src/bin/zonemgr/Makefile.am (original)
+++ branches/trac301/src/bin/zonemgr/Makefile.am Thu Oct  7 12:32:20 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 pkglibexecdir = $(libexecdir)/@PACKAGE@
 

Modified: branches/trac301/src/bin/zonemgr/TODO
==============================================================================
--- branches/trac301/src/bin/zonemgr/TODO (original)
+++ branches/trac301/src/bin/zonemgr/TODO Thu Oct  7 12:32:20 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/trac301/src/bin/zonemgr/zonemgr.py.in
==============================================================================
--- branches/trac301/src/bin/zonemgr/zonemgr.py.in (original)
+++ branches/trac301/src/bin/zonemgr/zonemgr.py.in Thu Oct  7 12:32:20 2010
@@ -36,6 +36,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
@@ -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

Modified: branches/trac301/src/lib/bench/benchmark_util.cc
==============================================================================
--- branches/trac301/src/lib/bench/benchmark_util.cc (original)
+++ branches/trac301/src/lib/bench/benchmark_util.cc Thu Oct  7 12:32:20 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/trac301/src/lib/bench/tests/loadquery_unittest.cc
==============================================================================
--- branches/trac301/src/lib/bench/tests/loadquery_unittest.cc (original)
+++ branches/trac301/src/lib/bench/tests/loadquery_unittest.cc Thu Oct  7 12:32:20 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/trac301/src/lib/cc/tests/Makefile.am
==============================================================================
--- branches/trac301/src/lib/cc/tests/Makefile.am (original)
+++ branches/trac301/src/lib/cc/tests/Makefile.am Thu Oct  7 12:32:20 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/trac301/src/lib/config/Makefile.am
==============================================================================
--- branches/trac301/src/lib/config/Makefile.am (original)
+++ branches/trac301/src/lib/config/Makefile.am Thu Oct  7 12:32:20 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/trac301/src/lib/config/tests/Makefile.am
==============================================================================
--- branches/trac301/src/lib/config/tests/Makefile.am (original)
+++ branches/trac301/src/lib/config/tests/Makefile.am Thu Oct  7 12:32:20 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/trac301/src/lib/config/tests/data_def_unittests_config.h.in
==============================================================================
--- branches/trac301/src/lib/config/tests/data_def_unittests_config.h.in (original)
+++ branches/trac301/src/lib/config/tests/data_def_unittests_config.h.in Thu Oct  7 12:32:20 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/trac301/src/lib/datasrc/data_source.cc
==============================================================================
--- branches/trac301/src/lib/datasrc/data_source.cc (original)
+++ branches/trac301/src/lib/datasrc/data_source.cc Thu Oct  7 12:32:20 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/trac301/src/lib/datasrc/tests/datasrc_unittest.cc
==============================================================================
--- branches/trac301/src/lib/datasrc/tests/datasrc_unittest.cc (original)
+++ branches/trac301/src/lib/datasrc/tests/datasrc_unittest.cc Thu Oct  7 12:32:20 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/trac301/src/lib/datasrc/tests/query_unittest.cc
==============================================================================
--- branches/trac301/src/lib/datasrc/tests/query_unittest.cc (original)
+++ branches/trac301/src/lib/datasrc/tests/query_unittest.cc Thu Oct  7 12:32:20 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/trac301/src/lib/dns/Makefile.am
==============================================================================
--- branches/trac301/src/lib/dns/Makefile.am (original)
+++ branches/trac301/src/lib/dns/Makefile.am Thu Oct  7 12:32:20 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/trac301/src/lib/dns/exceptions.cc
==============================================================================
--- branches/trac301/src/lib/dns/exceptions.cc (original)
+++ branches/trac301/src/lib/dns/exceptions.cc Thu Oct  7 12:32:20 2010
@@ -15,7 +15,7 @@
 // $Id$
 
 #include <dns/exceptions.h>
-#include <dns/message.h>
+#include <dns/rcode.h>
 
 namespace isc {
 namespace dns {

Modified: branches/trac301/src/lib/dns/message.cc
==============================================================================
--- branches/trac301/src/lib/dns/message.cc (original)
+++ branches/trac301/src/lib/dns/message.cc Thu Oct  7 12:32:20 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()) {
@@ -860,11 +724,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 +865,6 @@
 }
 
 ostream&
-operator<<(ostream& os, const Opcode& opcode) {
-    return (os << opcode.toText());
-}
-
-ostream&
-operator<<(ostream& os, const Rcode& rcode) {
-    return (os << rcode.toText());
-}
-
-ostream&
 operator<<(ostream& os, const Message& message) {
     return (os << message.toText());
 }

Modified: branches/trac301/src/lib/dns/message.h
==============================================================================
--- branches/trac301/src/lib/dns/message.h (original)
+++ branches/trac301/src/lib/dns/message.h Thu Oct  7 12:32:20 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;
@@ -159,310 +162,6 @@
     return (f);
 }
 
-/// \brief The \c Opcode class objects represent standard OPCODEs
-/// of the header section of DNS messages.
-///
-/// Note: since there are only 15 possible values, it may make more sense to
-/// simply define an enum type to represent these values.
-///
-/// Constant objects are defined for standard flags.
-class Opcode {
-public:
-    uint16_t getCode() const { return (code_); }
-    bool operator==(const Opcode& other) const
-    { return (code_ == other.code_); }
-    bool operator!=(const Opcode& other) const
-    { return (code_ != other.code_); }
-    std::string toText() const;
-    static const Opcode& QUERY();
-    static const Opcode& IQUERY();
-    static const Opcode& STATUS();
-    static const Opcode& RESERVED3();
-    static const Opcode& NOTIFY();
-    static const Opcode& UPDATE();
-    static const Opcode& RESERVED6();
-    static const Opcode& RESERVED7();
-    static const Opcode& RESERVED8();
-    static const Opcode& RESERVED9();
-    static const Opcode& RESERVED10();
-    static const Opcode& RESERVED11();
-    static const Opcode& RESERVED12();
-    static const Opcode& RESERVED13();
-    static const Opcode& RESERVED14();
-    static const Opcode& RESERVED15();
-private:
-    Opcode(uint16_t code) : code_(code) {}
-    uint16_t code_;
-};
-
-inline const Opcode&
-Opcode::QUERY()
-{
-    static Opcode c(0);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::IQUERY()
-{
-    static Opcode c(1);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::STATUS()
-{
-    static Opcode c(2);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED3()
-{
-    static Opcode c(3);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::NOTIFY()
-{
-    static Opcode c(4);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::UPDATE()
-{
-    static Opcode c(5);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED6()
-{
-    static Opcode c(6);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED7()
-{
-    static Opcode c(7);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED8()
-{
-    static Opcode c(8);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED9()
-{
-    static Opcode c(9);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED10()
-{
-    static Opcode c(10);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED11()
-{
-    static Opcode c(11);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED12()
-{
-    static Opcode c(12);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED13()
-{
-    static Opcode c(13);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED14()
-{
-    static Opcode c(14);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED15()
-{
-    static Opcode c(15);
-    return (c);
-}
-
-/// \brief The \c Rcode class objects represent standard Response Codes
-/// (RCODEs) of the header section of DNS messages, and extended response
-/// codes as defined in the EDNS specification.
-///
-/// Constant objects are defined for standard flags.
-class Rcode {
-public:
-    Rcode(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
 /// as the header, question, or answer.
 ///
@@ -627,45 +326,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 +340,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 +456,19 @@
     void makeResponse();
 
     /// \brief Convert the Message to a string.
+    ///
+    /// At least \c Opcode and \c Rcode must be validly set in the \c Message
+    /// (as a result of parse in the \c PARSE mode or by explicitly setting
+    /// in the \c RENDER mode);  otherwise, an exception of
+    /// class \c InvalidMessageOperation will be thrown.
     std::string toText() const;
 
     /// \brief Render the message in wire formant into a \c MessageRenderer
     /// object.
+    ///
+    /// This \c Message must be in the \c RENDER mode and both \c Opcode and
+    /// \c Rcode must have been set beforehand; otherwise, an exception of
+    /// class \c InvalidMessageOperation will be thrown.
     void toWire(MessageRenderer& renderer);
 
     /// \brief Parse the header section of the \c Message.
@@ -798,8 +495,6 @@
     MessageImpl* impl_;
 };
 
-std::ostream& operator<<(std::ostream& os, const Opcode& opcode);
-std::ostream& operator<<(std::ostream& os, const Rcode& rcode);
 std::ostream& operator<<(std::ostream& os, const Message& message);
 }
 }

Modified: branches/trac301/src/lib/dns/python/Makefile.am
==============================================================================
--- branches/trac301/src/lib/dns/python/Makefile.am (original)
+++ branches/trac301/src/lib/dns/python/Makefile.am Thu Oct  7 12:32:20 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/trac301/src/lib/dns/python/message_python.cc
==============================================================================
--- branches/trac301/src/lib/dns/python/message_python.cc (original)
+++ branches/trac301/src/lib/dns/python/message_python.cc Thu Oct  7 12:32:20 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/trac301/src/lib/dns/python/messagerenderer_python.cc
==============================================================================
--- branches/trac301/src/lib/dns/python/messagerenderer_python.cc (original)
+++ branches/trac301/src/lib/dns/python/messagerenderer_python.cc Thu Oct  7 12:32:20 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/trac301/src/lib/dns/python/name_python.cc
==============================================================================
--- branches/trac301/src/lib/dns/python/name_python.cc (original)
+++ branches/trac301/src/lib/dns/python/name_python.cc Thu Oct  7 12:32:20 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/trac301/src/lib/dns/python/pydnspp.cc
==============================================================================
--- branches/trac301/src/lib/dns/python/pydnspp.cc (original)
+++ branches/trac301/src/lib/dns/python/pydnspp.cc Thu Oct  7 12:32:20 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/trac301/src/lib/dns/python/question_python.cc
==============================================================================
--- branches/trac301/src/lib/dns/python/question_python.cc (original)
+++ branches/trac301/src/lib/dns/python/question_python.cc Thu Oct  7 12:32:20 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/trac301/src/lib/dns/python/rdata_python.cc
==============================================================================
--- branches/trac301/src/lib/dns/python/rdata_python.cc (original)
+++ branches/trac301/src/lib/dns/python/rdata_python.cc Thu Oct  7 12:32:20 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/trac301/src/lib/dns/python/rrclass_python.cc
==============================================================================
--- branches/trac301/src/lib/dns/python/rrclass_python.cc (original)
+++ branches/trac301/src/lib/dns/python/rrclass_python.cc Thu Oct  7 12:32:20 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/trac301/src/lib/dns/python/rrset_python.cc
==============================================================================
--- branches/trac301/src/lib/dns/python/rrset_python.cc (original)
+++ branches/trac301/src/lib/dns/python/rrset_python.cc Thu Oct  7 12:32:20 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/trac301/src/lib/dns/python/rrttl_python.cc
==============================================================================
--- branches/trac301/src/lib/dns/python/rrttl_python.cc (original)
+++ branches/trac301/src/lib/dns/python/rrttl_python.cc Thu Oct  7 12:32:20 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/trac301/src/lib/dns/python/rrtype_python.cc
==============================================================================
--- branches/trac301/src/lib/dns/python/rrtype_python.cc (original)
+++ branches/trac301/src/lib/dns/python/rrtype_python.cc Thu Oct  7 12:32:20 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/trac301/src/lib/dns/python/tests/Makefile.am
==============================================================================
--- branches/trac301/src/lib/dns/python/tests/Makefile.am (original)
+++ branches/trac301/src/lib/dns/python/tests/Makefile.am Thu Oct  7 12:32:20 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/trac301/src/lib/dns/python/tests/message_python_test.py
==============================================================================
--- branches/trac301/src/lib/dns/python/tests/message_python_test.py (original)
+++ branches/trac301/src/lib/dns/python/tests/message_python_test.py Thu Oct  7 12:32:20 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/trac301/src/lib/dns/python/tests/messagerenderer_python_test.py
==============================================================================
--- branches/trac301/src/lib/dns/python/tests/messagerenderer_python_test.py (original)
+++ branches/trac301/src/lib/dns/python/tests/messagerenderer_python_test.py Thu Oct  7 12:32:20 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/trac301/src/lib/dns/python/tests/question_python_test.py
==============================================================================
--- branches/trac301/src/lib/dns/python/tests/question_python_test.py (original)
+++ branches/trac301/src/lib/dns/python/tests/question_python_test.py Thu Oct  7 12:32:20 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/trac301/src/lib/dns/rrclass-placeholder.h
==============================================================================
--- branches/trac301/src/lib/dns/rrclass-placeholder.h (original)
+++ branches/trac301/src/lib/dns/rrclass-placeholder.h Thu Oct  7 12:32:20 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.
     ///

Modified: branches/trac301/src/lib/dns/rrset.h
==============================================================================
--- branches/trac301/src/lib/dns/rrset.h (original)
+++ branches/trac301/src/lib/dns/rrset.h Thu Oct  7 12:32:20 2010
@@ -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/trac301/src/lib/dns/rrtype-placeholder.h
==============================================================================
--- branches/trac301/src/lib/dns/rrtype-placeholder.h (original)
+++ branches/trac301/src/lib/dns/rrtype-placeholder.h Thu Oct  7 12:32:20 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.
     ///

Modified: branches/trac301/src/lib/dns/tests/Makefile.am
==============================================================================
--- branches/trac301/src/lib/dns/tests/Makefile.am (original)
+++ branches/trac301/src/lib/dns/tests/Makefile.am Thu Oct  7 12:32:20 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=\"$(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/trac301/src/lib/dns/tests/message_unittest.cc
==============================================================================
--- branches/trac301/src/lib/dns/tests/message_unittest.cc (original)
+++ branches/trac301/src/lib/dns/tests/message_unittest.cc Thu Oct  7 12:32:20 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/trac301/src/lib/dns/tests/messagerenderer_unittest.cc
==============================================================================
--- branches/trac301/src/lib/dns/tests/messagerenderer_unittest.cc (original)
+++ branches/trac301/src/lib/dns/tests/messagerenderer_unittest.cc Thu Oct  7 12:32:20 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/trac301/src/lib/dns/tests/rdata_nsec_unittest.cc
==============================================================================
--- branches/trac301/src/lib/dns/tests/rdata_nsec_unittest.cc (original)
+++ branches/trac301/src/lib/dns/tests/rdata_nsec_unittest.cc Thu Oct  7 12:32:20 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/trac301/src/lib/dns/tests/rdata_rrsig_unittest.cc
==============================================================================
--- branches/trac301/src/lib/dns/tests/rdata_rrsig_unittest.cc (original)
+++ branches/trac301/src/lib/dns/tests/rdata_rrsig_unittest.cc Thu Oct  7 12:32:20 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/trac301/src/lib/dns/tests/rdata_soa_unittest.cc
==============================================================================
--- branches/trac301/src/lib/dns/tests/rdata_soa_unittest.cc (original)
+++ branches/trac301/src/lib/dns/tests/rdata_soa_unittest.cc Thu Oct  7 12:32:20 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/trac301/src/lib/dns/tests/rdata_txt_unittest.cc
==============================================================================
--- branches/trac301/src/lib/dns/tests/rdata_txt_unittest.cc (original)
+++ branches/trac301/src/lib/dns/tests/rdata_txt_unittest.cc Thu Oct  7 12:32:20 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/trac301/src/lib/dns/tests/run_unittests.cc
==============================================================================
--- branches/trac301/src/lib/dns/tests/run_unittests.cc (original)
+++ branches/trac301/src/lib/dns/tests/run_unittests.cc Thu Oct  7 12:32:20 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/trac301/src/lib/dns/tests/testdata/gen-wiredata.py.in
==============================================================================
--- branches/trac301/src/lib/dns/tests/testdata/gen-wiredata.py.in (original)
+++ branches/trac301/src/lib/dns/tests/testdata/gen-wiredata.py.in Thu Oct  7 12:32:20 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/trac301/src/lib/exceptions/exceptions.h
==============================================================================
--- branches/trac301/src/lib/exceptions/exceptions.h (original)
+++ branches/trac301/src/lib/exceptions/exceptions.h Thu Oct  7 12:32:20 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/trac301/src/lib/python/isc/Makefile.am
==============================================================================
--- branches/trac301/src/lib/python/isc/Makefile.am (original)
+++ branches/trac301/src/lib/python/isc/Makefile.am Thu Oct  7 12:32:20 2010
@@ -1,4 +1,4 @@
-SUBDIRS = datasrc cc config log notify # Util
+SUBDIRS = datasrc cc config log notify utils # Util
 
 python_PYTHON = __init__.py
 

Modified: branches/trac301/src/lib/python/isc/cc/Makefile.am
==============================================================================
--- branches/trac301/src/lib/python/isc/cc/Makefile.am (original)
+++ branches/trac301/src/lib/python/isc/cc/Makefile.am Thu Oct  7 12:32:20 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 python_PYTHON =	__init__.py data.py session.py message.py
 

Modified: branches/trac301/src/lib/python/isc/config/Makefile.am
==============================================================================
--- branches/trac301/src/lib/python/isc/config/Makefile.am (original)
+++ branches/trac301/src/lib/python/isc/config/Makefile.am Thu Oct  7 12:32:20 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/trac301/src/lib/python/isc/config/tests/Makefile.am
==============================================================================
--- branches/trac301/src/lib/python/isc/config/tests/Makefile.am (original)
+++ branches/trac301/src/lib/python/isc/config/tests/Makefile.am Thu Oct  7 12:32:20 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/trac301/src/lib/python/isc/log/Makefile.am
==============================================================================
--- branches/trac301/src/lib/python/isc/log/Makefile.am (original)
+++ branches/trac301/src/lib/python/isc/log/Makefile.am Thu Oct  7 12:32:20 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 python_PYTHON = __init__.py log.py
 

Modified: branches/trac301/src/lib/python/isc/notify/Makefile.am
==============================================================================
--- branches/trac301/src/lib/python/isc/notify/Makefile.am (original)
+++ branches/trac301/src/lib/python/isc/notify/Makefile.am Thu Oct  7 12:32:20 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 python_PYTHON = __init__.py notify_out.py
 




More information about the bind10-changes mailing list