[svn] commit: r3885 - in /branches/trac397focused: ./ doc/ doc/guide/ src/bin/ src/bin/auth/ src/bin/auth/benchmarks/ src/bin/auth/tests/ src/bin/bind10/ src/bin/bind10/tests/ src/bin/bindctl/ src/bin/cfgmgr/ src/bin/cmdctl/ src/bin/host/ src/bin/loadzone/ src/bin/msgq/ src/bin/recurse/ src/bin/stats/ src/bin/stats/tests/isc/ src/bin/stats/tests/isc/util/ src/bin/tests/ src/bin/usermgr/ src/bin/xfrin/ src/bin/xfrin/tests/ src/bin/xfrout/ src/bin/xfrout/tests/ src/bin/zonemgr/ src/lib/ src/lib/bench/ src/lib/bench/example/ src/lib/bench/tests/ src/lib/cc/ src/lib/cc/tests/ src/lib/config/ src/lib/config/tests/ src/lib/datasrc/ src/lib/datasrc/tests/ src/lib/dns/ src/lib/dns/python/ src/lib/dns/python/tests/ src/lib/dns/rdata/any_255/ src/lib/dns/rdata/ch_3/ src/lib/dns/rdata/generic/ src/lib/dns/rdata/hs_4/ src/lib/dns/tests/ src/lib/dns/tests/testdata/ src/lib/exceptions/ src/lib/nsas/ src/lib/python/isc/ src/lib/python/isc/Util/ src/lib/python/isc/cc/ src/lib/python/isc/cc/tests/ src/lib/python/isc/config/ src/lib/python/isc/config/tests/ src/lib/python/isc/datasrc/ src/lib/python/isc/datasrc/tests/ src/lib/python/isc/notify/ src/lib/python/isc/notify/tests/ src/lib/python/isc/util/ src/lib/python/isc/utils/ src/lib/python/isc/utils/tests/ src/lib/xfr/

BIND 10 source code commits bind10-changes at lists.isc.org
Mon Dec 20 08:19:36 UTC 2010


Author: hanfeng
Date: Mon Dec 20 08:19:35 2010
New Revision: 3885

Log:
merge with trunk r3884

Added:
    branches/trac397focused/src/bin/auth/query.cc
      - copied unchanged from r3884, trunk/src/bin/auth/query.cc
    branches/trac397focused/src/bin/auth/query.h
      - copied unchanged from r3884, trunk/src/bin/auth/query.h
    branches/trac397focused/src/bin/auth/tests/query_unittest.cc
      - copied unchanged from r3884, trunk/src/bin/auth/tests/query_unittest.cc
    branches/trac397focused/src/bin/recurse/
      - copied from r3884, trunk/src/bin/recurse/
    branches/trac397focused/src/bin/stats/tests/isc/util/
      - copied from r3884, trunk/src/bin/stats/tests/isc/util/
    branches/trac397focused/src/lib/datasrc/memory_datasrc.cc
      - copied unchanged from r3884, trunk/src/lib/datasrc/memory_datasrc.cc
    branches/trac397focused/src/lib/datasrc/memory_datasrc.h
      - copied unchanged from r3884, trunk/src/lib/datasrc/memory_datasrc.h
    branches/trac397focused/src/lib/datasrc/tests/memory_datasrc_unittest.cc
      - copied unchanged from r3884, trunk/src/lib/datasrc/tests/memory_datasrc_unittest.cc
    branches/trac397focused/src/lib/datasrc/tests/zonetable_unittest.cc
      - copied unchanged from r3884, trunk/src/lib/datasrc/tests/zonetable_unittest.cc
    branches/trac397focused/src/lib/datasrc/zonetable.cc
      - copied unchanged from r3884, trunk/src/lib/datasrc/zonetable.cc
    branches/trac397focused/src/lib/datasrc/zonetable.h
      - copied unchanged from r3884, trunk/src/lib/datasrc/zonetable.h
    branches/trac397focused/src/lib/dns/masterload.cc
      - copied unchanged from r3884, trunk/src/lib/dns/masterload.cc
    branches/trac397focused/src/lib/dns/masterload.h
      - copied unchanged from r3884, trunk/src/lib/dns/masterload.h
    branches/trac397focused/src/lib/dns/python/tests/tsigkey_python_test.py
      - copied unchanged from r3884, trunk/src/lib/dns/python/tests/tsigkey_python_test.py
    branches/trac397focused/src/lib/dns/python/tsigkey_python.cc
      - copied unchanged from r3884, trunk/src/lib/dns/python/tsigkey_python.cc
    branches/trac397focused/src/lib/dns/rdata/any_255/
      - copied from r3884, trunk/src/lib/dns/rdata/any_255/
    branches/trac397focused/src/lib/dns/tests/masterload_unittest.cc
      - copied unchanged from r3884, trunk/src/lib/dns/tests/masterload_unittest.cc
    branches/trac397focused/src/lib/dns/tests/rdata_tsig_unittest.cc
      - copied unchanged from r3884, trunk/src/lib/dns/tests/rdata_tsig_unittest.cc
    branches/trac397focused/src/lib/dns/tests/testdata/masterload.txt
      - copied unchanged from r3884, trunk/src/lib/dns/tests/testdata/masterload.txt
    branches/trac397focused/src/lib/dns/tests/testdata/rdata_tsig_fromWire1.spec
      - copied unchanged from r3884, trunk/src/lib/dns/tests/testdata/rdata_tsig_fromWire1.spec
    branches/trac397focused/src/lib/dns/tests/testdata/rdata_tsig_fromWire2.spec
      - copied unchanged from r3884, trunk/src/lib/dns/tests/testdata/rdata_tsig_fromWire2.spec
    branches/trac397focused/src/lib/dns/tests/testdata/rdata_tsig_fromWire3.spec
      - copied unchanged from r3884, trunk/src/lib/dns/tests/testdata/rdata_tsig_fromWire3.spec
    branches/trac397focused/src/lib/dns/tests/testdata/rdata_tsig_fromWire4.spec
      - copied unchanged from r3884, trunk/src/lib/dns/tests/testdata/rdata_tsig_fromWire4.spec
    branches/trac397focused/src/lib/dns/tests/testdata/rdata_tsig_fromWire5.spec
      - copied unchanged from r3884, trunk/src/lib/dns/tests/testdata/rdata_tsig_fromWire5.spec
    branches/trac397focused/src/lib/dns/tests/testdata/rdata_tsig_fromWire6.spec
      - copied unchanged from r3884, trunk/src/lib/dns/tests/testdata/rdata_tsig_fromWire6.spec
    branches/trac397focused/src/lib/dns/tests/testdata/rdata_tsig_fromWire7.spec
      - copied unchanged from r3884, trunk/src/lib/dns/tests/testdata/rdata_tsig_fromWire7.spec
    branches/trac397focused/src/lib/dns/tests/testdata/rdata_tsig_fromWire8.spec
      - copied unchanged from r3884, trunk/src/lib/dns/tests/testdata/rdata_tsig_fromWire8.spec
    branches/trac397focused/src/lib/dns/tests/testdata/rdata_tsig_fromWire9.spec
      - copied unchanged from r3884, trunk/src/lib/dns/tests/testdata/rdata_tsig_fromWire9.spec
    branches/trac397focused/src/lib/dns/tests/testdata/rdata_tsig_toWire1.spec
      - copied unchanged from r3884, trunk/src/lib/dns/tests/testdata/rdata_tsig_toWire1.spec
    branches/trac397focused/src/lib/dns/tests/testdata/rdata_tsig_toWire2.spec
      - copied unchanged from r3884, trunk/src/lib/dns/tests/testdata/rdata_tsig_toWire2.spec
    branches/trac397focused/src/lib/dns/tests/testdata/rdata_tsig_toWire3.spec
      - copied unchanged from r3884, trunk/src/lib/dns/tests/testdata/rdata_tsig_toWire3.spec
    branches/trac397focused/src/lib/dns/tests/testdata/rdata_tsig_toWire4.spec
      - copied unchanged from r3884, trunk/src/lib/dns/tests/testdata/rdata_tsig_toWire4.spec
    branches/trac397focused/src/lib/dns/tests/testdata/rdata_tsig_toWire5.spec
      - copied unchanged from r3884, trunk/src/lib/dns/tests/testdata/rdata_tsig_toWire5.spec
    branches/trac397focused/src/lib/dns/tests/tsigkey_unittest.cc
      - copied unchanged from r3884, trunk/src/lib/dns/tests/tsigkey_unittest.cc
    branches/trac397focused/src/lib/dns/tsigkey.cc
      - copied unchanged from r3884, trunk/src/lib/dns/tsigkey.cc
    branches/trac397focused/src/lib/dns/tsigkey.h
      - copied unchanged from r3884, trunk/src/lib/dns/tsigkey.h
    branches/trac397focused/src/lib/nsas/
      - copied from r3884, trunk/src/lib/nsas/
    branches/trac397focused/src/lib/python/isc/datasrc/tests/
      - copied from r3884, trunk/src/lib/python/isc/datasrc/tests/
    branches/trac397focused/src/lib/python/isc/util/
      - copied from r3884, trunk/src/lib/python/isc/util/
Removed:
    branches/trac397focused/src/lib/dns/tests/tsig_unittest.cc
    branches/trac397focused/src/lib/dns/tsig.cc
    branches/trac397focused/src/lib/dns/tsig.h
    branches/trac397focused/src/lib/python/isc/Util/
    branches/trac397focused/src/lib/python/isc/utils/socketserver_mixin.py
    branches/trac397focused/src/lib/python/isc/utils/tests/socketserver_mixin_test.py
Modified:
    branches/trac397focused/   (props changed)
    branches/trac397focused/ChangeLog
    branches/trac397focused/Makefile.am
    branches/trac397focused/README
    branches/trac397focused/configure.ac
    branches/trac397focused/doc/Doxyfile
    branches/trac397focused/doc/guide/bind10-guide.html
    branches/trac397focused/doc/guide/bind10-guide.xml
    branches/trac397focused/src/bin/Makefile.am
    branches/trac397focused/src/bin/auth/Makefile.am
    branches/trac397focused/src/bin/auth/asio_link.cc
    branches/trac397focused/src/bin/auth/asio_link.h
    branches/trac397focused/src/bin/auth/auth_srv.cc
    branches/trac397focused/src/bin/auth/auth_srv.h
    branches/trac397focused/src/bin/auth/benchmarks/Makefile.am
    branches/trac397focused/src/bin/auth/tests/Makefile.am
    branches/trac397focused/src/bin/auth/tests/auth_srv_unittest.cc
    branches/trac397focused/src/bin/bind10/bind10.py.in   (contents, props changed)
    branches/trac397focused/src/bin/bind10/bob.spec
    branches/trac397focused/src/bin/bind10/run_bind10.sh.in
    branches/trac397focused/src/bin/bind10/tests/bind10_test.py
    branches/trac397focused/src/bin/bindctl/bindcmd.py
    branches/trac397focused/src/bin/bindctl/bindctl-source.py.in
    branches/trac397focused/src/bin/cfgmgr/b10-cfgmgr.py.in
    branches/trac397focused/src/bin/cmdctl/cmdctl.py.in
    branches/trac397focused/src/bin/host/Makefile.am
    branches/trac397focused/src/bin/host/host.cc
    branches/trac397focused/src/bin/loadzone/b10-loadzone.py.in
    branches/trac397focused/src/bin/msgq/msgq.py.in
    branches/trac397focused/src/bin/stats/stats.py.in
    branches/trac397focused/src/bin/stats/stats_stub.py.in
    branches/trac397focused/src/bin/stats/tests/isc/Makefile.am
    branches/trac397focused/src/bin/tests/process_rename_test.py.in
    branches/trac397focused/src/bin/usermgr/b10-cmdctl-usermgr.py.in
    branches/trac397focused/src/bin/xfrin/b10-xfrin.xml
    branches/trac397focused/src/bin/xfrin/tests/xfrin_test.py
    branches/trac397focused/src/bin/xfrin/xfrin.py.in
    branches/trac397focused/src/bin/xfrout/b10-xfrout.8
    branches/trac397focused/src/bin/xfrout/b10-xfrout.xml
    branches/trac397focused/src/bin/xfrout/tests/xfrout_test.py
    branches/trac397focused/src/bin/xfrout/xfrout.py.in
    branches/trac397focused/src/bin/xfrout/xfrout.spec.pre.in
    branches/trac397focused/src/bin/zonemgr/zonemgr.py.in
    branches/trac397focused/src/lib/Makefile.am
    branches/trac397focused/src/lib/bench/Makefile.am
    branches/trac397focused/src/lib/bench/benchmark.h
    branches/trac397focused/src/lib/bench/example/search_bench.cc
    branches/trac397focused/src/lib/bench/tests/Makefile.am
    branches/trac397focused/src/lib/bench/tests/loadquery_unittest.cc
    branches/trac397focused/src/lib/cc/Makefile.am
    branches/trac397focused/src/lib/cc/data.cc
    branches/trac397focused/src/lib/cc/tests/Makefile.am
    branches/trac397focused/src/lib/cc/tests/data_unittests.cc
    branches/trac397focused/src/lib/cc/tests/session_unittests.cc
    branches/trac397focused/src/lib/config/Makefile.am
    branches/trac397focused/src/lib/config/config_data.cc
    branches/trac397focused/src/lib/config/tests/Makefile.am
    branches/trac397focused/src/lib/config/tests/ccsession_unittests.cc
    branches/trac397focused/src/lib/config/tests/config_data_unittests.cc
    branches/trac397focused/src/lib/config/tests/fake_session.cc
    branches/trac397focused/src/lib/config/tests/fake_session.h
    branches/trac397focused/src/lib/datasrc/Makefile.am
    branches/trac397focused/src/lib/datasrc/cache.h
    branches/trac397focused/src/lib/datasrc/data_source.cc
    branches/trac397focused/src/lib/datasrc/query.cc
    branches/trac397focused/src/lib/datasrc/query.h
    branches/trac397focused/src/lib/datasrc/static_datasrc.cc
    branches/trac397focused/src/lib/datasrc/tests/Makefile.am
    branches/trac397focused/src/lib/datasrc/tests/datasrc_unittest.cc
    branches/trac397focused/src/lib/datasrc/tests/query_unittest.cc
    branches/trac397focused/src/lib/datasrc/tests/sqlite3_unittest.cc
    branches/trac397focused/src/lib/datasrc/tests/static_unittest.cc
    branches/trac397focused/src/lib/datasrc/tests/test_datasrc.cc
    branches/trac397focused/src/lib/dns/Makefile.am
    branches/trac397focused/src/lib/dns/edns.cc
    branches/trac397focused/src/lib/dns/message.cc
    branches/trac397focused/src/lib/dns/message.h
    branches/trac397focused/src/lib/dns/python/Makefile.am
    branches/trac397focused/src/lib/dns/python/message_python.cc
    branches/trac397focused/src/lib/dns/python/name_python.cc
    branches/trac397focused/src/lib/dns/python/opcode_python.cc
    branches/trac397focused/src/lib/dns/python/pydnspp.cc
    branches/trac397focused/src/lib/dns/python/rcode_python.cc
    branches/trac397focused/src/lib/dns/python/rrclass_python.cc
    branches/trac397focused/src/lib/dns/python/rrset_python.cc
    branches/trac397focused/src/lib/dns/python/rrtype_python.cc
    branches/trac397focused/src/lib/dns/python/tests/Makefile.am
    branches/trac397focused/src/lib/dns/python/tests/message_python_test.py
    branches/trac397focused/src/lib/dns/python/tests/messagerenderer_python_test.py
    branches/trac397focused/src/lib/dns/rdata/ch_3/a_1.cc
    branches/trac397focused/src/lib/dns/rdata/generic/cname_5.cc
    branches/trac397focused/src/lib/dns/rdata/generic/dname_39.cc
    branches/trac397focused/src/lib/dns/rdata/generic/mx_15.cc
    branches/trac397focused/src/lib/dns/rdata/generic/ns_2.cc
    branches/trac397focused/src/lib/dns/rdata/generic/opt_41.cc
    branches/trac397focused/src/lib/dns/rdata/generic/ptr_12.cc
    branches/trac397focused/src/lib/dns/rdata/generic/soa_6.cc
    branches/trac397focused/src/lib/dns/rdata/hs_4/a_1.cc
    branches/trac397focused/src/lib/dns/rrclass-placeholder.h
    branches/trac397focused/src/lib/dns/rrset.cc
    branches/trac397focused/src/lib/dns/rrset.h
    branches/trac397focused/src/lib/dns/tests/Makefile.am
    branches/trac397focused/src/lib/dns/tests/message_unittest.cc
    branches/trac397focused/src/lib/dns/tests/name_unittest.cc
    branches/trac397focused/src/lib/dns/tests/rdata_ns_unittest.cc
    branches/trac397focused/src/lib/dns/tests/rdata_ptr_unittest.cc
    branches/trac397focused/src/lib/dns/tests/rdata_unittest.cc
    branches/trac397focused/src/lib/dns/tests/rrset_unittest.cc
    branches/trac397focused/src/lib/dns/tests/rrsetlist_unittest.cc
    branches/trac397focused/src/lib/dns/tests/testdata/Makefile.am
    branches/trac397focused/src/lib/dns/tests/testdata/edns_toWire4.spec
    branches/trac397focused/src/lib/dns/tests/testdata/gen-wiredata.py.in
    branches/trac397focused/src/lib/dns/tests/unittest_util.cc
    branches/trac397focused/src/lib/exceptions/exceptions.h
    branches/trac397focused/src/lib/python/isc/Makefile.am
    branches/trac397focused/src/lib/python/isc/cc/data.py
    branches/trac397focused/src/lib/python/isc/cc/session.py
    branches/trac397focused/src/lib/python/isc/cc/tests/data_test.py
    branches/trac397focused/src/lib/python/isc/cc/tests/session_test.py
    branches/trac397focused/src/lib/python/isc/config/ccsession.py
    branches/trac397focused/src/lib/python/isc/config/config_data.py
    branches/trac397focused/src/lib/python/isc/config/tests/ccsession_test.py
    branches/trac397focused/src/lib/python/isc/config/tests/config_data_test.py
    branches/trac397focused/src/lib/python/isc/datasrc/Makefile.am
    branches/trac397focused/src/lib/python/isc/datasrc/master.py
    branches/trac397focused/src/lib/python/isc/notify/notify_out.py
    branches/trac397focused/src/lib/python/isc/notify/tests/notify_out_test.py
    branches/trac397focused/src/lib/python/isc/utils/Makefile.am
    branches/trac397focused/src/lib/python/isc/utils/__init__.py
    branches/trac397focused/src/lib/python/isc/utils/tests/Makefile.am
    branches/trac397focused/src/lib/xfr/Makefile.am
    branches/trac397focused/src/lib/xfr/fd_share.cc
    branches/trac397focused/src/lib/xfr/fd_share.h
    branches/trac397focused/src/lib/xfr/fdshare_python.cc
    branches/trac397focused/src/lib/xfr/xfrout_client.cc

Modified: branches/trac397focused/ChangeLog
==============================================================================
--- branches/trac397focused/ChangeLog (original)
+++ branches/trac397focused/ChangeLog Mon Dec 20 08:19:35 2010
@@ -1,16 +1,132 @@
+	131.  [func]    feng
+	src/lib/datasrc: Introduced two template classes RBTree and RBNode
+	to provide the generic map with domain name as key and anything as
+	the value. Because of some unresolved design issue, the new classes
+	are only intended to be used by memory zone and zone table.
+	(Trac #397, svn r3885)
+
+  130.	[func]		jerry
+    src/lib/datasrc: Introduced a new class MemoryDataSrc to provide
+	the general interface for memory data source.  For the initial
+	implementation, we don't make it a derived class of AbstractDataSrc
+	because the interface is so different(we'll eventually consider this
+	as part of the generalization work).
+	(Trac #422, svn r3866)
+
+  129.	[func]		jinmei
+	src/lib/dns: Added new functions masterLoad() for loading master
+	zone files.  The initial implementation can only parse a limited
+	form of master files, but BIND 9's named-compilezone can convert
+	any valid zone file into the acceptable form.
+	(Trac #423, svn r3857)
+
+  128.  [build]     vorner
+	Test for query name = '.', type = DS to authoritative nameserver
+	for root zone was added.
+	(Trac #85, svn r3836)
+
+  127.  [bug]       stephen
+	During normal operation process termination and resurrection messages
+	are now output regardless of the state of the verbose flag.
+	(Trac #229, svn r3828)
+
+  126.  [func]      stephen, vorner, ocean
+	The Nameserver Address Store (NSAS) component has been added. It takes
+	care of choosing an IP address of a nameserver when a zone needs to be
+	contacted.
+	(Trac #356, Trac #408, svn r3823)
+
+bind10-devel-20101201 released on December 01, 2010
+
+  125.  [func]		jelte
+	Added support for addressing individual list items in bindctl
+	configuration commands; If you have an element that is a list, you
+	can use foo[X] to address a specific item, where X is an integer
+	(starting at 0)
+	(Trac #405, svn r3739)
+
+  124.  [bug]		jreed
+	Fix some wrong version reporting. Now also show the version
+	for the component and BIND 10 suite. (Trac #302, svn r3696)
+
+  123.  [bug]		jelte
+	src/bin/bindctl printed values had the form of python literals
+	(e.g. 'True'), while the input requires valid JSON (e.g. 'true').
+	Output changed to JSON format for consistency. (svn r3694)
+
+  122.  [func]		stephen
+	src/bin/bind10: Added configuration options to Boss to determine
+	whether to start the authoritative server, recursive server (or
+	both). A dummy recursor has been provided for test purposes.
+	(Trac #412, svn r3676)
+
+  121.  [func]		jinmei
+	src/lib/dns: Added support for TSIG RDATA.  At this moment this is
+	not much of real use, however, because no protocol support was
+	added yet.  It will soon be added. (Trac #372, svn r3649)
+
+  120.  [func]		jinmei
+	src/lib/dns: introduced two new classes, TSIGKey and TSIGKeyRing,
+	to manage TSIG keys. (Trac #381, svn r3622)
+
+  119.	[bug]		jinmei
+	The master file parser of the python datasrc module incorrectly
+	regarded a domain name beginning with a decimal number as a TTL
+	specification.  This confused b10-loadzone and had it reject to
+	load a zone file that contains such a name.
+	Note: this fix is incomplete and the loadzone would still be
+	confused if the owner name is a syntactically indistinguishable
+	from a TTL specification.  This is part of a more general issue
+	and will be addressed in Trac #413. (Trac #411, svn r3599)
+
+  118.	[func]		jinmei
+	src/lib/dns: changed the interface of
+	AbstractRRset::getRdataIterator() so that the internal
+	cursor would point to the first RDATA automatically.  This
+	will be a more intuitive and less error prone behavior.
+	This is a backward compatible change. (Trac #410, r3595)
+
+  117.  [func]		jinmei
+	src/lib/datasrc: added new zone and zone table classes for the
+	support of in memory data source.  This is an intermediate step to
+	the bigger feature, and is not yet actually usable in practice.
+	(Trac #399, svn r3590)
+
+  116.	[bug]		jerry
+	src/bin/xfrout: Xfrout and Auth will communicate by long tcp
+	connection, Auth needs to make a new connection only on the first
+	time or if an error occurred.
+	(Trac #299, svn r3482)
+
+  115.	[func]*		jinmei
+	src/lib/dns: Changed DNS message flags and section names from
+	separate classes to simpler enums, considering the balance between
+	type safety and usability.  API has been changed accordingly.
+	More documentation and tests were provided with these changes.
+	(Trac #358, r3439)
+
+  114.	[build]		jinmei
+	Supported clang++.  Note: Boost >= 1.44 is required.
+	(Trac #365, svn r3383)
+
+  113.	[func]*		zhanglikun
+	Folder name 'utils'(the folder in /src/lib/python/isc/) has been
+	renamed	to 'util'. Programs that used 'import isc.utils.process'
+	now need to use 'import isc.util.process'. The folder
+	/src/lib/python/isc/Util is removed since it isn't used by any
+	program. (Trac #364, r3382)
+
   112.	[func]		zhang likun
 	Add one mixin class to override the naive serve_forever() provided
 	in python library socketserver. Instead of polling for shutdwon
 	every poll_interval seconds, one socketpair is used to wake up
-	the waiting server.(Trac #352, svn r3366)
+	the waiting server. (Trac #352, svn r3366)
 
   111.	[bug]*   zhanglikun, Michal Vaner
-	Make sure process xfrin/xfrout/zonemgr/cmdctl can be stoped
+	Make sure process xfrin/xfrout/zonemgr/cmdctl can be stopped
 	properly when user enter "ctrl+c" or 'Boss shutdown' command
-	through	bindctl.
-
-	The ZonemgrRefresh.run_timer and NotifyOut.dispatcher spawn
-	a thread themselves.
+	through bindctl.  The ZonemgrRefresh.run_timer and
+	NotifyOut.dispatcher spawn a thread themselves.
 	(Trac #335, svn r3273)
 
   110.  [func]      Michal Vaner
@@ -22,7 +138,7 @@
   109.  [func]		naokikambe
 	Added the initial version of the stats module for the statistics
 	feature of BIND 10, which supports the restricted features and
-	items and reports via bindctl command (Trac #191, r3218)
+	items and reports via bindctl command. (Trac #191, r3218)
 	Added the document of the stats module, which is about how stats
 	module collects the data (Trac #170, [wiki:StatsModule])
 
@@ -49,11 +165,11 @@
   104.	[bug]		jerry
 	bin/zonemgr: zonemgr should be attempting to refresh expired zones.
 	(Trac #336, r3139)
-				   
+ 
   103.	[bug]		jerry
 	lib/python/isc/log: Fixed an issue with python logging,
-	python log shouldn't die with OSError.(Trac #267, r3137)
-				   
+	python log shouldn't die with OSError. (Trac #267, r3137)
+ 
   102.	[build]		jinmei
 	Disable threads in ASIO to minimize build time dependency.
 	(Trac #345, r3100)
@@ -106,7 +222,7 @@
   93.	[bug]		jinmei
 	lib/datasrc: A DS query could crash the library (and therefore,
 	e.g. the authoritative server) if some RR of the same apex name
-	is stored in the hot spot cache.  (Trac #307, svn r2923)
+	is stored in the hot spot cache. (Trac #307, svn r2923)
 
   92.	[func]*		jelte
 	libdns_python (the python wrappers for libdns++) has been renamed
@@ -286,7 +402,7 @@
   66.  [bug]		each
 	Check for duplicate RRsets before inserting data into a message
 	section; this, among other things, will prevent multiple copies
-	of the same CNAME from showing up when there's a loop.  (Trac #69,
+	of the same CNAME from showing up when there's a loop. (Trac #69,
 	svn r2350)
     
   65.  [func]		shentingting
@@ -408,7 +524,7 @@
 	#205, svn r1957)
 
   44.   [build]         jreed
-	Install headers for libdns and libexception.  (Trac #68,
+	Install headers for libdns and libexception. (Trac #68,
 	svn r1941)
 
   43.   [func]          jelte
@@ -416,7 +532,7 @@
 
   42.   [func]          jelte
 	lib/python/isc/config:      Make temporary file with python
-	tempfile module instead of manual with fixed name.  (Trac
+	tempfile module instead of manual with fixed name. (Trac
 	#184, svn r1859)
 
   41.   [func]          jelte
@@ -424,7 +540,7 @@
 
   40.   [build]         jreed
 	Report detected features and configure settings at end of
-	configure output.  (svn r1836)
+	configure output. (svn r1836)
 
   39.   [func]*         each
 	Renamed libauth to libdatasrc.
@@ -437,7 +553,7 @@
 	(Trac #135, #151, #134, svn r1797)
 
   37.   [build]         jinmei
-	Check for the availability of python-config.  (Trac #159,
+	Check for the availability of python-config. (Trac #159,
 	svn r1794)
 
   36.	[func]		shane
@@ -482,7 +598,7 @@
 
   27.	[build]
 	Add missing copyright license statements to various source
-	files.  (svn r1750)
+	files. (svn r1750)
 
   26.	[func]
 	Use PACKAGE_STRING (name + version) from config.h instead

Modified: branches/trac397focused/Makefile.am
==============================================================================
--- branches/trac397focused/Makefile.am (original)
+++ branches/trac397focused/Makefile.am Mon Dec 20 08:19:35 2010
@@ -37,7 +37,7 @@
 			\*_unittest.cc \
 			\*_unittests.h \
 		--output report.info
-	$(GENHTML) -o coverage report.info 
+	$(GENHTML) --legend -o coverage report.info 
 
 coverage: clean-coverage perform-coverage report-coverage
 

Modified: branches/trac397focused/README
==============================================================================
--- branches/trac397focused/README (original)
+++ branches/trac397focused/README Mon Dec 20 08:19:35 2010
@@ -17,8 +17,9 @@
 bus, b10-auth authoritative DNS server (with SQLite3 backend),
 b10-cmdctl remote control daemon, b10-cfgmgr configuration manager,
 b10-xfrin AXFR inbound service, b10-xfrout outgoing AXFR service,
-b10-zonemgr secondary manager, and a new libdns++ library for C++
-with a python wrapper.
+b10-zonemgr secondary manager, b10-stats statistics collection and
+reporting daemon, and a new libdns++ library for C++ with a python
+wrapper.
 
 Documentation is included and also available via the BIND 10
 website at http://bind10.isc.org/

Modified: branches/trac397focused/configure.ac
==============================================================================
--- branches/trac397focused/configure.ac (original)
+++ branches/trac397focused/configure.ac Mon Dec 20 08:19:35 2010
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ([2.59])
-AC_INIT(bind10-devel, 20101013, bind10-dev at isc.org)
+AC_INIT(bind10-devel, 20101201, bind10-dev at isc.org)
 AC_CONFIG_SRCDIR(README)
 AM_INIT_AUTOMAKE
 AC_CONFIG_HEADERS([config.h])
@@ -17,6 +17,8 @@
 # Identify the compiler: this check must be after AC_PROG_CXX and AC_LANG.
 AM_CONDITIONAL(USE_GXX, test "X${GXX}" = "Xyes")
 AC_CHECK_DECL([__SUNPRO_CC], [SUNCXX="yes"], [SUNCXX="no"])
+AC_CHECK_DECL([__clang__], [CLANGPP="yes"], [CLANGPP="no"])
+AM_CONDITIONAL(USE_CLANGPP, test "X${CLANGPP}" = "Xyes")
 
 # Linker options
 
@@ -193,18 +195,49 @@
 # specify the default warning flags in CXXFLAGS and let specific modules
 # "override" the default.
 
+# This may be used to try compiler flags.
+AC_DEFUN([BIND10_CXX_TRY_FLAG], [
+  AC_MSG_CHECKING([whether $CXX supports $1])
+
+  bind10_save_CXXFLAGS="$CXXFLAGS"
+  CXXFLAGS="$CXXFLAGS $1"
+
+  AC_COMPILE_IFELSE([ ], [bind10_cxx_flag=yes], [bind10_cxx_flag=no])
+  CXXFLAGS="$bind10_save_CXXFLAGS"
+
+  if test "x$bind10_cxx_flag" = "xyes"; then
+    ifelse([$2], , :, [$2])
+  else
+    ifelse([$3], , :, [$3])
+  fi
+
+  AC_MSG_RESULT([$bind10_cxx_flag])
+])
+
 werror_ok=0
 
 # SunStudio compiler requires special compiler options for boost
 # (http://blogs.sun.com/sga/entry/boost_mini_howto)
 if test "$SUNCXX" = "yes"; then
 CXXFLAGS="$CXXFLAGS -library=stlport4 -features=tmplife -features=tmplrefstatic"
-fi
+MULTITHREADING_FLAG="-mt"
+fi
+
+BIND10_CXX_TRY_FLAG(-Wno-missing-field-initializers,
+	[WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG="-Wno-missing-field-initializers"])
+AC_SUBST(WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG)
 
 # gcc specific settings:
 if test "X$GXX" = "Xyes"; then
 B10_CXXFLAGS="-Wall -Wextra -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare"
-UNUSED_PARAM_ATTRIBUTE='__attribute__((unused))'
+case "$host" in
+*-solaris*)
+	MULTITHREADING_FLAG=-pthreads
+	;;
+*)
+	MULTITHREADING_FLAG=-pthread
+	;;
+esac
 
 # Certain versions of gcc (g++) have a bug that incorrectly warns about
 # the use of anonymous name spaces even if they're closed in a single
@@ -223,7 +256,6 @@
 fi				dnl GXX = yes
 
 AM_CONDITIONAL(GCC_WERROR_OK, test $werror_ok = 1)
-AC_DEFINE_UNQUOTED(UNUSED_PARAM, $UNUSED_PARAM_ATTRIBUTE, Define to compiler keyword indicating a function argument is intentionally unused)
 
 # produce PIC unless we disable shared libraries. need this for python bindings.
 if test $enable_shared != "no" -a "X$GXX" = "Xyes"; then
@@ -313,13 +345,50 @@
 		fi
 	done
 fi
+CPPFLAGS_SAVES="$CPPFLAGS"
 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_CHECK_HEADERS([boost/shared_ptr.hpp boost/foreach.hpp boost/interprocess/sync/interprocess_upgradable_mutex.hpp],,
   AC_MSG_ERROR([Missing required header files.]))
+CPPFLAGS="$CPPFLAGS_SAVES"
 AC_SUBST(BOOST_INCLUDES)
+
+# Using boost::mutex can result in requiring libboost_thread with older
+# versions of Boost.  We'd like to avoid relying on a compiled Boost library
+# whenever possible, so we need to check for it step by step.
+#
+# NOTE: another fix of this problem is to simply require newer versions of
+# boost.  If we choose that solution we should simplify the following tricky
+# checks accordingly and all Makefile.am's that refer to NEED_LIBBOOST_THREAD.
+AC_MSG_CHECKING(for boost::mutex)
+CPPFLAGS_SAVES="$CPPFLAGS"
+LIBS_SAVES="$LIBS"
+CPPFLAGS="$BOOST_INCLUDES $CPPFLAGS $MULTITHREADING_FLAG"
+need_libboost_thread=0
+AC_TRY_LINK([
+#include <boost/thread.hpp>
+],[
+boost::mutex m;
+],
+	[ AC_MSG_RESULT(yes (without libboost_thread)) ],
+	[ LIBS=" $LIBS -lboost_thread"
+	  AC_TRY_LINK([
+#include <boost/thread.hpp>
+],[
+boost::mutex m;
+],
+		  [ AC_MSG_RESULT(yes (with libboost_thread))
+		    need_libboost_thread=1 ],
+		  [ AC_MSG_RESULT(no)
+		    AC_MSG_ERROR([boost::mutex cannot be linked in this build environment.
+Perhaps you are using an older version of Boost that requires libboost_thread for the mutex support, which does not appear to be available.
+You may want to check the availability of the library or to upgrade Boost.])
+   		  ])])
+CPPFLAGS="$CPPFLAGS_SAVES"
+LIBS="$LIBS_SAVES"
+AM_CONDITIONAL(NEED_LIBBOOST_THREAD, test $need_libboost_thread = 1)
 
 #
 # Check availability of gtest, which will be used for unit tests.
@@ -385,6 +454,8 @@
 PTHREAD_LDFLAGS=
 AC_CHECK_LIB(pthread, pthread_create,[ PTHREAD_LDFLAGS=-lpthread ], [])
 AC_SUBST(PTHREAD_LDFLAGS)
+
+AC_SUBST(MULTITHREADING_FLAG)
 
 #
 # ASIO: we extensively use it as the C++ event management module.
@@ -465,6 +536,7 @@
                  src/bin/auth/tests/Makefile
                  src/bin/auth/tests/testdata/Makefile
                  src/bin/auth/benchmarks/Makefile
+                 src/bin/recurse/Makefile
                  src/bin/xfrin/Makefile
                  src/bin/xfrin/tests/Makefile
                  src/bin/xfrout/Makefile
@@ -476,7 +548,7 @@
                  src/bin/stats/tests/isc/Makefile
                  src/bin/stats/tests/isc/cc/Makefile
                  src/bin/stats/tests/isc/config/Makefile
-                 src/bin/stats/tests/isc/utils/Makefile
+                 src/bin/stats/tests/isc/util/Makefile
                  src/bin/stats/tests/testdata/Makefile
                  src/bin/usermgr/Makefile
                  src/bin/tests/Makefile
@@ -488,9 +560,10 @@
                  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/util/Makefile
+                 src/lib/python/isc/util/tests/Makefile
                  src/lib/python/isc/datasrc/Makefile
+                 src/lib/python/isc/datasrc/tests/Makefile
                  src/lib/python/isc/cc/Makefile
                  src/lib/python/isc/cc/tests/Makefile
                  src/lib/python/isc/config/Makefile
@@ -514,6 +587,8 @@
                  src/lib/datasrc/Makefile
                  src/lib/datasrc/tests/Makefile
                  src/lib/xfr/Makefile
+                 src/lib/nsas/Makefile
+                 src/lib/nsas/tests/Makefile
                ])
 AC_OUTPUT([src/bin/cfgmgr/b10-cfgmgr.py
            src/bin/cfgmgr/tests/b10-cfgmgr_test.py
@@ -528,6 +603,9 @@
            src/bin/xfrout/xfrout.spec.pre
            src/bin/xfrout/tests/xfrout_test
            src/bin/xfrout/run_b10-xfrout.sh
+           src/bin/recurse/recurse.py
+           src/bin/recurse/recurse.spec.pre
+           src/bin/recurse/run_b10-recurse.sh
            src/bin/zonemgr/zonemgr.py
            src/bin/zonemgr/zonemgr.spec.pre
            src/bin/zonemgr/tests/zonemgr_test
@@ -570,6 +648,7 @@
            chmod +x src/bin/cmdctl/run_b10-cmdctl.sh
            chmod +x src/bin/xfrin/run_b10-xfrin.sh
            chmod +x src/bin/xfrout/run_b10-xfrout.sh
+           chmod +x src/bin/recurse/run_b10-recurse.sh
            chmod +x src/bin/zonemgr/run_b10-zonemgr.sh
            chmod +x src/bin/stats/tests/stats_test
            chmod +x src/bin/stats/run_b10-stats.sh
@@ -604,6 +683,8 @@
   Name:          $PACKAGE_NAME
   Version:       $PACKAGE_VERSION
 
+C++ Compiler:    $CXX
+
 Flags:
   DEFS:          $DEFS
   CPPFLAGS:      $CPPFLAGS
@@ -613,6 +694,7 @@
   Python:        ${PYTHON_INCLUDES}
                  ${PYTHON_LDFLAGS}
                  ${PYTHON_LIB}
+  Boost:         ${BOOST_INCLUDES}
   SQLite:        $SQLITE_CFLAGS
                  $SQLITE_LIBS
 
@@ -632,4 +714,3 @@
   Now you can type "make" to build BIND 10
 
 EOF
-

Modified: branches/trac397focused/doc/Doxyfile
==============================================================================
--- branches/trac397focused/doc/Doxyfile (original)
+++ branches/trac397focused/doc/Doxyfile Mon Dec 20 08:19:35 2010
@@ -568,7 +568,7 @@
 # directories like "/usr/src/myproject". Separate the files or directories
 # with spaces.
 
-INPUT                  = ../src/lib/cc ../src/lib/config ../src/lib/dns ../src/lib/exceptions ../src/lib/datasrc ../src/bin/auth ../src/lib/bench
+INPUT                  = ../src/lib/cc ../src/lib/config ../src/lib/dns ../src/lib/exceptions ../src/lib/datasrc ../src/bin/auth ../src/lib/bench ../src/lib/nsas
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is

Modified: branches/trac397focused/doc/guide/bind10-guide.html
==============================================================================
--- branches/trac397focused/doc/guide/bind10-guide.html (original)
+++ branches/trac397focused/doc/guide/bind10-guide.html Mon Dec 20 08:19:35 2010
@@ -128,7 +128,7 @@
             libraries, to build BIND 10 from source code.
           </p></div><p>
           Building from source code requires the Boost
-          build-time headers. At least Boost version 1.34 is required.
+          build-time headers. At least Boost version 1.35 is required.
   
   
         </p><p>

Modified: branches/trac397focused/doc/guide/bind10-guide.xml
==============================================================================
--- branches/trac397focused/doc/guide/bind10-guide.xml (original)
+++ branches/trac397focused/doc/guide/bind10-guide.xml Mon Dec 20 08:19:35 2010
@@ -274,7 +274,7 @@
 
         <para>
           Building from source code requires the Boost
-          build-time headers. At least Boost version 1.34 is required.
+          build-time headers. At least Boost version 1.35 is required.
   <!-- TODO: we don't check for this version -->
   <!-- NOTE: jreed has tested with 1.34, 1.38, and 1.41. -->
         </para>

Modified: branches/trac397focused/src/bin/Makefile.am
==============================================================================
--- branches/trac397focused/src/bin/Makefile.am (original)
+++ branches/trac397focused/src/bin/Makefile.am Mon Dec 20 08:19:35 2010
@@ -1,4 +1,4 @@
 SUBDIRS = bind10 bindctl cfgmgr loadzone msgq host cmdctl auth xfrin xfrout \
-	usermgr zonemgr stats tests
+	usermgr zonemgr stats tests recurse
 
 check-recursive: all-recursive

Modified: branches/trac397focused/src/bin/auth/Makefile.am
==============================================================================
--- branches/trac397focused/src/bin/auth/Makefile.am (original)
+++ branches/trac397focused/src/bin/auth/Makefile.am Mon Dec 20 08:19:35 2010
@@ -5,6 +5,7 @@
 AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
 AM_CPPFLAGS += -I$(top_builddir)/src/lib/cc
 AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin
+AM_CPPFLAGS += $(BOOST_INCLUDES)
 
 AM_CXXFLAGS = $(B10_CXXFLAGS)
 
@@ -46,11 +47,16 @@
 if USE_GXX
 libasio_link_a_CXXFLAGS += -Wno-unused-parameter
 endif
+if USE_CLANGPP
+# Same for clang++, but we need to turn off -Werror completely.
+libasio_link_a_CXXFLAGS += -Wno-error
+endif
 libasio_link_a_CPPFLAGS = $(AM_CPPFLAGS)
 
 BUILT_SOURCES = spec_config.h 
 pkglibexec_PROGRAMS = b10-auth
 b10_auth_SOURCES = auth_srv.cc auth_srv.h
+b10_auth_SOURCES += query.cc query.h
 b10_auth_SOURCES += change_user.cc change_user.h
 b10_auth_SOURCES += common.h
 b10_auth_SOURCES += main.cc

Modified: branches/trac397focused/src/bin/auth/asio_link.cc
==============================================================================
--- branches/trac397focused/src/bin/auth/asio_link.cc (original)
+++ branches/trac397focused/src/bin/auth/asio_link.cc Mon Dec 20 08:19:35 2010
@@ -505,9 +505,7 @@
         }
     }
 
-    void sendCompleted(const asio::error_code& error UNUSED_PARAM,
-                       size_t bytes_sent UNUSED_PARAM)
-    {
+    void sendCompleted(const asio::error_code&, size_t) {
         // Even if error occurred there's nothing to do.  Simply handle
         // the next request.
         startReceive();

Modified: branches/trac397focused/src/bin/auth/asio_link.h
==============================================================================
--- branches/trac397focused/src/bin/auth/asio_link.h (original)
+++ branches/trac397focused/src/bin/auth/asio_link.h Mon Dec 20 08:19:35 2010
@@ -88,7 +88,7 @@
 /// http://think-async.com/Asio/asio-1.3.1/doc/asio/reference/asio_handler_allocate.html
 
 namespace asio_link {
-struct IOServiceImpl;
+class IOServiceImpl;
 
 /// \brief An exception that is thrown if an error occurs within the IO
 /// module.  This is mainly intended to be a wrapper exception class for
@@ -132,7 +132,7 @@
     /// This constructor never throws an exception.
     ///
     /// \param asio_address The ASIO \c ip::address to be converted.
-    IOAddress(const asio::ip::address& asio_adress);
+    IOAddress(const asio::ip::address& asio_address);
     //@}
 
     /// \brief Convert the address to a string.

Modified: branches/trac397focused/src/bin/auth/auth_srv.cc
==============================================================================
--- branches/trac397focused/src/bin/auth/auth_srv.cc (original)
+++ branches/trac397focused/src/bin/auth/auth_srv.cc Mon Dec 20 08:19:35 2010
@@ -77,7 +77,7 @@
                             MessageRenderer& response_renderer);
     bool processAxfrQuery(const IOMessage& io_message, Message& message,
                             MessageRenderer& response_renderer);
-    bool processNotify(const IOMessage& io_message, Message& message, 
+    bool processNotify(const IOMessage& io_message, Message& message,
                             MessageRenderer& response_renderer);
     std::string db_file_;
     ModuleCCSession* config_session_;
@@ -152,8 +152,8 @@
     // XXX: with the current implementation, it's not easy to set EDNS0
     // depending on whether the query had it.  So we'll simply omit it.
     const qid_t qid = message.getQid();
-    const bool rd = message.getHeaderFlag(MessageFlag::RD());
-    const bool cd = message.getHeaderFlag(MessageFlag::CD());
+    const bool rd = message.getHeaderFlag(Message::HEADERFLAG_RD);
+    const bool cd = message.getHeaderFlag(Message::HEADERFLAG_CD);
     const Opcode& opcode = message.getOpcode();
     vector<QuestionPtr> questions;
 
@@ -166,12 +166,12 @@
     message.clear(Message::RENDER);
     message.setQid(qid);
     message.setOpcode(opcode);
-    message.setHeaderFlag(MessageFlag::QR());
+    message.setHeaderFlag(Message::HEADERFLAG_QR);
     if (rd) {
-        message.setHeaderFlag(MessageFlag::RD());
+        message.setHeaderFlag(Message::HEADERFLAG_RD);
     }
     if (cd) {
-        message.setHeaderFlag(MessageFlag::CD());
+        message.setHeaderFlag(Message::HEADERFLAG_CD);
     }
     for_each(questions.begin(), questions.end(), QuestionInserter(&message));
     message.setRcode(rcode);
@@ -231,7 +231,7 @@
         message.parseHeader(request_buffer);
 
         // Ignore all responses.
-        if (message.getHeaderFlag(MessageFlag::QR())) {
+        if (message.getHeaderFlag(Message::HEADERFLAG_QR)) {
             if (impl_->verbose_mode_) {
                 cerr << "[b10-auth] received unexpected response, ignoring"
                      << endl;
@@ -279,7 +279,7 @@
         return (true);
     }
 
-    if (message.getRRCount(Section::QUESTION()) != 1) {
+    if (message.getRRCount(Message::SECTION_QUESTION) != 1) {
         makeErrorMessage(message, response_renderer, Rcode::FORMERR(),
                          impl_->verbose_mode_);
         return (true);
@@ -307,10 +307,10 @@
     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::DEFAULT_MAX_UDPSIZE;
 
     message.makeResponse();
-    message.setHeaderFlag(MessageFlag::AA());
+    message.setHeaderFlag(Message::HEADERFLAG_AA);
     message.setRcode(Rcode::NOERROR());
 
     if (remote_edns) {
@@ -360,8 +360,10 @@
     }
 
     try {
-        xfrout_client_.connect();
-        xfrout_connected_ = true;
+        if (!xfrout_connected_) {
+            xfrout_client_.connect();
+            xfrout_connected_ = true;
+        }
         xfrout_client_.sendXfroutRequestInfo(
             io_message.getSocket().getNative(),
             io_message.getData(),
@@ -375,7 +377,7 @@
             xfrout_client_.disconnect();
             xfrout_connected_ = false;
         }
-        
+
         if (verbose_mode_) {
             cerr << "[b10-auth] Error in handling XFR request: " << err.what()
                  << endl;
@@ -385,22 +387,19 @@
         return (true);
     }
 
-    xfrout_client_.disconnect();
-    xfrout_connected_ = false;
-
     return (false);
 }
 
 bool
-AuthSrvImpl::processNotify(const IOMessage& io_message, Message& message, 
-                           MessageRenderer& response_renderer) 
+AuthSrvImpl::processNotify(const IOMessage& io_message, Message& message,
+                           MessageRenderer& response_renderer)
 {
     // The incoming notify must contain exactly one question for SOA of the
     // zone name.
-    if (message.getRRCount(Section::QUESTION()) != 1) {
+    if (message.getRRCount(Message::SECTION_QUESTION) != 1) {
         if (verbose_mode_) {
                 cerr << "[b10-auth] invalid number of questions in notify: "
-                     << message.getRRCount(Section::QUESTION()) << endl;
+                     << message.getRRCount(Message::SECTION_QUESTION) << endl;
         }
         makeErrorMessage(message, response_renderer, Rcode::FORMERR(),
                          verbose_mode_);
@@ -446,7 +445,7 @@
 
     try {
         ConstElementPtr notify_command = Element::fromJSON(
-                command_template_start + question->getName().toText() + 
+                command_template_start + question->getName().toText() +
                 command_template_master + remote_ip_address +
                 command_template_rrclass + question->getClass().toText() +
                 command_template_end);
@@ -460,7 +459,7 @@
         if (rcode != 0) {
             if (verbose_mode_) {
                 cerr << "[b10-auth] failed to notify Zonemgr: "
-                     << parsed_answer->str() << endl; 
+                     << parsed_answer->str() << endl;
             }
             return (false);
         }
@@ -472,7 +471,7 @@
     }
 
     message.makeResponse();
-    message.setHeaderFlag(MessageFlag::AA());
+    message.setHeaderFlag(Message::HEADERFLAG_AA);
     message.setRcode(Rcode::NOERROR());
     message.toWire(response_renderer);
     return (true);

Modified: branches/trac397focused/src/bin/auth/auth_srv.h
==============================================================================
--- branches/trac397focused/src/bin/auth/auth_srv.h (original)
+++ branches/trac397focused/src/bin/auth/auth_srv.h Mon Dec 20 08:19:35 2010
@@ -84,7 +84,7 @@
             isc::xfr::AbstractXfroutClient& xfrout_client);
     ~AuthSrv();
     //@}
-    /// \return \c true if the \message contains a response to be returned;
+    /// \return \c true if the \a message contains a response to be returned;
     /// otherwise \c false.
     bool processMessage(const asio_link::IOMessage& io_message,
                         isc::dns::Message& message,
@@ -138,7 +138,7 @@
     /// containing the result of the update operation.
     isc::data::ConstElementPtr updateConfig(isc::data::ConstElementPtr config);
 
-    /// \param Returns the command and configuration session for the
+    /// \brief Returns the command and configuration session for the
     /// \c AuthSrv.
     ///
     /// This method never throws an exception.
@@ -199,6 +199,7 @@
     /// is shutdown.
     ///
     void setXfrinSession(isc::cc::AbstractSession* xfrin_session);
+
 private:
     AuthSrvImpl* impl_;
 };

Modified: branches/trac397focused/src/bin/auth/benchmarks/Makefile.am
==============================================================================
--- branches/trac397focused/src/bin/auth/benchmarks/Makefile.am (original)
+++ branches/trac397focused/src/bin/auth/benchmarks/Makefile.am Mon Dec 20 08:19:35 2010
@@ -1,5 +1,6 @@
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin
+AM_CPPFLAGS += $(BOOST_INCLUDES)
 
 AM_CXXFLAGS = $(B10_CXXFLAGS)
 

Modified: branches/trac397focused/src/bin/auth/tests/Makefile.am
==============================================================================
--- branches/trac397focused/src/bin/auth/tests/Makefile.am (original)
+++ branches/trac397focused/src/bin/auth/tests/Makefile.am Mon Dec 20 08:19:35 2010
@@ -3,6 +3,7 @@
 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 += $(BOOST_INCLUDES)
 AM_CPPFLAGS += -DTEST_DATA_DIR=\"$(srcdir)/testdata\"
 AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/bin/auth/tests/testdata\"
 
@@ -20,8 +21,10 @@
 run_unittests_SOURCES = $(top_srcdir)/src/lib/dns/tests/unittest_util.h
 run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.cc
 run_unittests_SOURCES += ../auth_srv.h ../auth_srv.cc
+run_unittests_SOURCES += ../query.h ../query.cc
 run_unittests_SOURCES += ../change_user.h ../change_user.cc
 run_unittests_SOURCES += auth_srv_unittest.cc
+run_unittests_SOURCES += query_unittest.cc
 run_unittests_SOURCES += change_user_unittest.cc
 run_unittests_SOURCES += asio_link_unittest.cc
 run_unittests_SOURCES += run_unittests.cc

Modified: branches/trac397focused/src/bin/auth/tests/auth_srv_unittest.cc
==============================================================================
--- branches/trac397focused/src/bin/auth/tests/auth_srv_unittest.cc (original)
+++ branches/trac397focused/src/bin/auth/tests/auth_srv_unittest.cc Mon Dec 20 08:19:35 2010
@@ -97,7 +97,7 @@
         virtual void startRead(boost::function<void()> read_callback);
         virtual int reply(ConstElementPtr envelope, ConstElementPtr newmsg);
         virtual bool hasQueuedMsgs() const;
-        virtual void setTimeout(size_t timeout UNUSED_PARAM) {};
+        virtual void setTimeout(size_t) {}
         virtual size_t getTimeout() const { return 0; };
 
         void setMessage(ConstElementPtr msg) { msg_ = msg; }
@@ -156,30 +156,25 @@
 };
 
 void
-AuthSrvTest::MockSession::establish(const char* socket_file UNUSED_PARAM) {}
+AuthSrvTest::MockSession::establish(const char*) {}
 
 void
 AuthSrvTest::MockSession::disconnect() {}
 
 void
-AuthSrvTest::MockSession::subscribe(string group UNUSED_PARAM,
-                                    string instance UNUSED_PARAM)
+AuthSrvTest::MockSession::subscribe(string, string)
 {}
 
 void
-AuthSrvTest::MockSession::unsubscribe(string group UNUSED_PARAM,
-                                      string instance UNUSED_PARAM)
+AuthSrvTest::MockSession::unsubscribe(string, string)
 {}
 
 void
-AuthSrvTest::MockSession::startRead(
-    boost::function<void()> read_callback UNUSED_PARAM)
+AuthSrvTest::MockSession::startRead(boost::function<void()>)
 {}
 
 int
-AuthSrvTest::MockSession::reply(ConstElementPtr envelope UNUSED_PARAM,
-                                ConstElementPtr newmsg UNUSED_PARAM)
-{
+AuthSrvTest::MockSession::reply(ConstElementPtr, ConstElementPtr) {
     return (-1);
 }
 
@@ -190,8 +185,7 @@
 
 int
 AuthSrvTest::MockSession::group_sendmsg(ConstElementPtr msg, string group,
-                                        string instance UNUSED_PARAM,
-                                        string to UNUSED_PARAM)
+                                        string, string)
 {
     if (!send_ok_) {
         isc_throw(XfroutError, "mock session send is disabled for test");
@@ -203,10 +197,8 @@
 }
 
 bool
-AuthSrvTest::MockSession::group_recvmsg(ConstElementPtr& envelope UNUSED_PARAM,
-                                        ConstElementPtr& msg,
-                                        bool nonblock UNUSED_PARAM,
-                                        int seq UNUSED_PARAM)
+AuthSrvTest::MockSession::group_recvmsg(ConstElementPtr&,
+                                        ConstElementPtr& msg, bool, int)
 {
     if (!receive_ok_) {
         isc_throw(XfroutError, "mock session receive is disabled for test");
@@ -234,10 +226,9 @@
 }
 
 int
-AuthSrvTest::MockXfroutClient::sendXfroutRequestInfo(
-    const int tcp_sock UNUSED_PARAM,
-    const void* msg_data UNUSED_PARAM,
-    const uint16_t msg_len UNUSED_PARAM)
+AuthSrvTest::MockXfroutClient::sendXfroutRequestInfo(const int,
+                                                     const void*,
+                                                     const uint16_t)
 {
     if (!send_ok_) {
         isc_throw(XfroutError, "xfrout connection send is disabled for test");
@@ -321,18 +312,25 @@
     EXPECT_EQ(qid, message.getQid());
     EXPECT_EQ(rcode, message.getRcode());
     EXPECT_EQ(opcodeval, message.getOpcode().getCode());
-    EXPECT_EQ((flags & QR_FLAG) != 0, message.getHeaderFlag(MessageFlag::QR()));
-    EXPECT_EQ((flags & AA_FLAG) != 0, message.getHeaderFlag(MessageFlag::AA()));
-    EXPECT_EQ((flags & TC_FLAG) != 0, message.getHeaderFlag(MessageFlag::TC()));
-    EXPECT_EQ((flags & RA_FLAG) != 0, message.getHeaderFlag(MessageFlag::RA()));
-    EXPECT_EQ((flags & RD_FLAG) != 0, message.getHeaderFlag(MessageFlag::RD()));
-    EXPECT_EQ((flags & AD_FLAG) != 0, message.getHeaderFlag(MessageFlag::AD()));
-    EXPECT_EQ((flags & CD_FLAG) != 0, message.getHeaderFlag(MessageFlag::CD()));
-
-    EXPECT_EQ(qdcount, message.getRRCount(Section::QUESTION()));
-    EXPECT_EQ(ancount, message.getRRCount(Section::ANSWER()));
-    EXPECT_EQ(nscount, message.getRRCount(Section::AUTHORITY()));
-    EXPECT_EQ(arcount, message.getRRCount(Section::ADDITIONAL()));
+    EXPECT_EQ((flags & QR_FLAG) != 0,
+              message.getHeaderFlag(Message::HEADERFLAG_QR));
+    EXPECT_EQ((flags & AA_FLAG) != 0,
+              message.getHeaderFlag(Message::HEADERFLAG_AA));
+    EXPECT_EQ((flags & TC_FLAG) != 0,
+              message.getHeaderFlag(Message::HEADERFLAG_TC));
+    EXPECT_EQ((flags & RA_FLAG) != 0,
+              message.getHeaderFlag(Message::HEADERFLAG_RA));
+    EXPECT_EQ((flags & RD_FLAG) != 0,
+              message.getHeaderFlag(Message::HEADERFLAG_RD));
+    EXPECT_EQ((flags & AD_FLAG) != 0,
+              message.getHeaderFlag(Message::HEADERFLAG_AD));
+    EXPECT_EQ((flags & CD_FLAG) != 0,
+              message.getHeaderFlag(Message::HEADERFLAG_CD));
+
+    EXPECT_EQ(qdcount, message.getRRCount(Message::SECTION_QUESTION));
+    EXPECT_EQ(ancount, message.getRRCount(Message::SECTION_ANSWER));
+    EXPECT_EQ(nscount, message.getRRCount(Message::SECTION_AUTHORITY));
+    EXPECT_EQ(arcount, message.getRRCount(Message::SECTION_ADDITIONAL));
 }
 
 // Unsupported requests.  Should result in NOTIMP.
@@ -348,8 +346,8 @@
         data[2] = ((i << 3) & 0xff);
 
         parse_message.clear(Message::PARSE);
-        EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
-                                              response_renderer));
+        EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                          response_renderer));
         headerCheck(parse_message, default_qid, Rcode::NOTIMP(), i, QR_FLAG,
                     0, 0, 0, 0);
     }
@@ -367,8 +365,8 @@
 // Multiple questions.  Should result in FORMERR.
 TEST_F(AuthSrvTest, multiQuestion) {
     createDataFromFile("multiquestion_fromWire.wire");
-    EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
-                                          response_renderer));
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
     headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
                 QR_FLAG, 2, 0, 0, 0);
 
@@ -388,8 +386,8 @@
 // dropped.
 TEST_F(AuthSrvTest, shortMessage) {
     createDataFromFile("shortmessage_fromWire");
-    EXPECT_EQ(false, server.processMessage(*io_message, parse_message,
-                                           response_renderer));
+    EXPECT_FALSE(server.processMessage(*io_message, parse_message,
+                                       response_renderer));
 }
 
 // Response messages.  Must be silently dropped, whether it's a valid response
@@ -397,26 +395,26 @@
 TEST_F(AuthSrvTest, response) {
     // A valid (although unusual) response
     createDataFromFile("simpleresponse_fromWire.wire");
-    EXPECT_EQ(false, server.processMessage(*io_message, parse_message,
-                                           response_renderer));
+    EXPECT_FALSE(server.processMessage(*io_message, parse_message,
+                                       response_renderer));
 
     // A response with a broken question section.  must be dropped rather than
     // returning FORMERR.
     createDataFromFile("shortresponse_fromWire");
-    EXPECT_EQ(false, server.processMessage(*io_message, parse_message,
-                                           response_renderer));
+    EXPECT_FALSE(server.processMessage(*io_message, parse_message,
+                                       response_renderer));
 
     // A response to iquery.  must be dropped rather than returning NOTIMP.
     createDataFromFile("iqueryresponse_fromWire.wire");
-    EXPECT_EQ(false, server.processMessage(*io_message, parse_message,
-                                           response_renderer));
+    EXPECT_FALSE(server.processMessage(*io_message, parse_message,
+                                       response_renderer));
 }
 
 // Query with a broken question
 TEST_F(AuthSrvTest, shortQuestion) {
     createDataFromFile("shortquestion_fromWire");
-    EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
-                                          response_renderer));
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
     // Since the query's question is broken, the question section of the
     // response should be empty.
     headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
@@ -426,8 +424,8 @@
 // Query with a broken answer section
 TEST_F(AuthSrvTest, shortAnswer) {
     createDataFromFile("shortanswer_fromWire.wire");
-    EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
-                                          response_renderer));
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
 
     // This is a bogus query, but question section is valid.  So the response
     // should copy the question section.
@@ -445,8 +443,8 @@
 // Query with unsupported version of EDNS.
 TEST_F(AuthSrvTest, ednsBadVers) {
     createDataFromFile("queryBadEDNS_fromWire.wire");
-    EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
-                                          response_renderer));
+    EXPECT_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.
@@ -468,8 +466,8 @@
     // AXFR over UDP is invalid and should result in FORMERR.
     createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
                         RRType::AXFR(), IPPROTO_UDP);
-    EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
-                                          response_renderer));
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
     headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
                 QR_FLAG, 1, 0, 0, 0);
 }
@@ -480,9 +478,9 @@
                         RRType::AXFR(), IPPROTO_TCP);
     // On success, the AXFR query has been passed to a separate process,
     // so we shouldn't have to respond.
-    EXPECT_EQ(false, server.processMessage(*io_message, parse_message,
-                                           response_renderer));
-    EXPECT_FALSE(xfrout.isConnected());
+    EXPECT_FALSE(server.processMessage(*io_message, parse_message,
+                                       response_renderer));
+    EXPECT_TRUE(xfrout.isConnected());
 }
 
 TEST_F(AuthSrvTest, AXFRConnectFail) {
@@ -494,8 +492,6 @@
                                       response_renderer));
     headerCheck(parse_message, default_qid, Rcode::SERVFAIL(),
                 opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
-    // For a shot term workaround with xfrout we currently close the connection
-    // for each AXFR attempt
     EXPECT_FALSE(xfrout.isConnected());
 }
 
@@ -505,7 +501,7 @@
     createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
                         RRType::AXFR(), IPPROTO_TCP);
     server.processMessage(*io_message, parse_message, response_renderer);
-    EXPECT_FALSE(xfrout.isConnected()); // see above
+    EXPECT_TRUE(xfrout.isConnected());
 
     xfrout.disableSend();
     parse_message.clear(Message::PARSE);
@@ -540,10 +536,10 @@
 TEST_F(AuthSrvTest, notify) {
     createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
                         RRType::SOA());
-    request_message.setHeaderFlag(MessageFlag::AA());
-    createRequestPacket(IPPROTO_UDP);
-    EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
-                                          response_renderer));
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
+    createRequestPacket(IPPROTO_UDP);
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
 
     // An internal command message should have been created and sent to an
     // external module.  Check them.
@@ -572,10 +568,10 @@
     // Same as the previous test, but for the CH RRClass.
     createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::CH(),
                         RRType::SOA());
-    request_message.setHeaderFlag(MessageFlag::AA());
-    createRequestPacket(IPPROTO_UDP);
-    EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
-                                          response_renderer));
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
+    createRequestPacket(IPPROTO_UDP);
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
 
     // Other conditions should be the same, so simply confirm the RR class is
     // set correctly.
@@ -588,12 +584,12 @@
     request_message.clear(Message::RENDER);
     request_message.setOpcode(Opcode::NOTIFY());
     request_message.setRcode(Rcode::NOERROR());
-    request_message.setHeaderFlag(MessageFlag::AA());
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
     request_message.setQid(default_qid);
     request_message.toWire(request_renderer);
     createRequestPacket(IPPROTO_UDP);
-    EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
-                                          response_renderer));
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
     headerCheck(parse_message, default_qid, Rcode::FORMERR(),
                 Opcode::NOTIFY().getCode(), QR_FLAG, 0, 0, 0, 0);
 }
@@ -604,10 +600,10 @@
     // add one more SOA question
     request_message.addQuestion(Question(Name("example.com"), RRClass::IN(),
                                          RRType::SOA()));
-    request_message.setHeaderFlag(MessageFlag::AA());
-    createRequestPacket(IPPROTO_UDP);
-    EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
-                                          response_renderer));
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
+    createRequestPacket(IPPROTO_UDP);
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
     headerCheck(parse_message, default_qid, Rcode::FORMERR(),
                 Opcode::NOTIFY().getCode(), QR_FLAG, 2, 0, 0, 0);
 }
@@ -615,10 +611,10 @@
 TEST_F(AuthSrvTest, notifyNonSOAQuestion) {
     createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
                         RRType::NS());
-    request_message.setHeaderFlag(MessageFlag::AA());
-    createRequestPacket(IPPROTO_UDP);
-    EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
-                                          response_renderer));
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
+    createRequestPacket(IPPROTO_UDP);
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
     headerCheck(parse_message, default_qid, Rcode::FORMERR(),
                 Opcode::NOTIFY().getCode(), QR_FLAG, 1, 0, 0, 0);
 }
@@ -627,8 +623,8 @@
     // implicitly leave the AA bit off.  our implementation will accept it.
     createRequestPacket(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
                         RRType::SOA());
-    EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
-                                          response_renderer));
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
     headerCheck(parse_message, default_qid, Rcode::NOERROR(),
                 Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
 }
@@ -636,11 +632,11 @@
 TEST_F(AuthSrvTest, notifyWithErrorRcode) {
     createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
                         RRType::SOA());
-    request_message.setHeaderFlag(MessageFlag::AA());
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
     request_message.setRcode(Rcode::SERVFAIL());
     createRequestPacket(IPPROTO_UDP);
-    EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
-                                          response_renderer));
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
     headerCheck(parse_message, default_qid, Rcode::NOERROR(),
                 Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
 }
@@ -650,7 +646,7 @@
 
     createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
                         RRType::SOA());
-    request_message.setHeaderFlag(MessageFlag::AA());
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
     createRequestPacket(IPPROTO_UDP);
 
     // we simply ignore the notify and let it be resent if an internal error
@@ -664,7 +660,7 @@
 
     createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
                         RRType::SOA());
-    request_message.setHeaderFlag(MessageFlag::AA());
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
     createRequestPacket(IPPROTO_UDP);
 
     EXPECT_FALSE(server.processMessage(*io_message, parse_message,
@@ -676,7 +672,7 @@
 
     createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
                         RRType::SOA());
-    request_message.setHeaderFlag(MessageFlag::AA());
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
     createRequestPacket(IPPROTO_UDP);
     EXPECT_FALSE(server.processMessage(*io_message, parse_message,
                                        response_renderer));
@@ -687,7 +683,7 @@
 
     createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
                         RRType::SOA());
-    request_message.setHeaderFlag(MessageFlag::AA());
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
     createRequestPacket(IPPROTO_UDP);
     EXPECT_FALSE(server.processMessage(*io_message, parse_message,
                                        response_renderer));
@@ -699,7 +695,7 @@
 
     createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
                         RRType::SOA());
-    request_message.setHeaderFlag(MessageFlag::AA());
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
     createRequestPacket(IPPROTO_UDP);
     EXPECT_FALSE(server.processMessage(*io_message, parse_message,
                                        response_renderer));
@@ -727,8 +723,8 @@
     // response should have the AA flag on, and have an RR in each answer
     // and authority section.
     createDataFromFile("examplequery_fromWire.wire");
-    EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
-                                          response_renderer));
+    EXPECT_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);
 }
@@ -741,8 +737,8 @@
     // in a SERVFAIL response, and the answer and authority sections should
     // be empty.
     createDataFromFile("badExampleQuery_fromWire.wire");
-    EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
-                                          response_renderer));
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
     headerCheck(parse_message, default_qid, Rcode::SERVFAIL(),
                 opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
 }
@@ -756,8 +752,8 @@
 
     // The original data source should still exist.
     createDataFromFile("examplequery_fromWire.wire");
-    EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
-                                          response_renderer));
+    EXPECT_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);
 }

Modified: branches/trac397focused/src/bin/bind10/bind10.py.in
==============================================================================
--- branches/trac397focused/src/bin/bind10/bind10.py.in (original)
+++ branches/trac397focused/src/bin/bind10/bind10.py.in Mon Dec 20 08:19:35 2010
@@ -15,7 +15,7 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-"""\
+"""
 This file implements the Boss of Bind (BoB, or bob) program.
 
 Its purpose is to start up the BIND 10 system, and then manage the
@@ -63,16 +63,16 @@
 import posix
 
 import isc.cc
+import isc.util.process
 import isc.net.parse
-import isc.utils.process
 
 # Assign this process some longer name
-isc.utils.process.rename(sys.argv[0])
+isc.util.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
 # number, and the overall BIND 10 version number (set in configure.ac).
-VERSION = "bind10 20100916 (BIND 10 @PACKAGE_VERSION@)"
+VERSION = "bind10 20101129 (BIND 10 @PACKAGE_VERSION@)"
 
 # This is for bind10.boottime of stats module
 _BASETIME = time.gmtime()
@@ -141,9 +141,14 @@
         self.username = username
         self._spawn()
 
-    def _setuid(self):
+    def _preexec_work(self):
         """Function used before running a program that needs to run as a
         different user."""
+        # First, put us into a separate process group so we don't get
+        # SIGINT signals on Ctrl-C (the boss will shut everthing down by
+        # other means).
+        os.setpgrp()
+        # Second, set the user ID if one has been specified
         if self.uid is not None:
             try:
                 posix.setuid(self.uid)
@@ -177,144 +182,240 @@
                                         stderr=spawn_stderr,
                                         close_fds=True,
                                         env=spawn_env,
-                                        preexec_fn=self._setuid)
+                                        preexec_fn=self._preexec_work)
         self.pid = self.process.pid
         self.restart_schedule.set_run_start_time()
 
     def respawn(self):
         self._spawn()
+
+class CChannelConnectError(Exception): pass
 
 class BoB:
     """Boss of BIND class."""
     
     def __init__(self, msgq_socket_file=None, auth_port=5300, address=None,
                  nocache=False, verbose=False, setuid=None, username=None):
-        """Initialize the Boss of BIND. This is a singleton (only one
-        can run).
+        """
+            Initialize the Boss of BIND. This is a singleton (only one can run).
         
-        The msgq_socket_file specifies the UNIX domain socket file
-        that the msgq process listens on.
-        If verbose is True, then the boss reports what it is doing.
-        """
-        self.verbose = verbose
-        self.msgq_socket_file = msgq_socket_file
+            The msgq_socket_file specifies the UNIX domain socket file that the
+            msgq process listens on.  If verbose is True, then the boss reports
+            what it is doing.
+        """
+        self.address = address
         self.auth_port = auth_port
-        self.address = None
-        if address:
-            self.address = address
         self.cc_session = None
         self.ccs = None
+        self.cfg_start_auth = True
+        self.cfg_start_recurse = False
+        self.curproc = None
+        self.dead_processes = {}
+        self.msgq_socket_file = msgq_socket_file
+        self.nocache = nocache
         self.processes = {}
-        self.dead_processes = {}
         self.runnable = False
         self.uid = setuid
         self.username = username
-        self.nocache = nocache
+        self.verbose = verbose
 
     def config_handler(self, new_config):
         if self.verbose:
-            sys.stdout.write("[bind10] handling new config:\n")
-            sys.stdout.write(new_config + "\n")
+            sys.stdout.write("[bind10] Handling new configuration: " +
+                str(new_config) + "\n")
         answer = isc.config.ccsession.create_answer(0)
         return answer
         # TODO
 
     def command_handler(self, command, args):
         if self.verbose:
-            sys.stdout.write("[bind10] Boss got command:\n")
-            sys.stdout.write(command + "\n")
+            sys.stdout.write("[bind10] Boss got command: " + command + "\n")
         answer = isc.config.ccsession.create_answer(1, "command not implemented")
         if type(command) != str:
             answer = isc.config.ccsession.create_answer(1, "bad command")
         else:
-            cmd = command
-            if cmd == "shutdown":
-                sys.stdout.write("[bind10] got shutdown command\n")
+            if command == "shutdown":
                 self.runnable = False
                 answer = isc.config.ccsession.create_answer(0)
             else:
                 answer = isc.config.ccsession.create_answer(1, 
                                                             "Unknown command")
         return answer
-    
-    def startup(self):
-        """Start the BoB instance.
- 
-        Returns None if successful, otherwise an string describing the
-        problem.
-        """
-        # try to connect to the c-channel daemon, 
-        # to see if it is already running
-        c_channel_env = {}
-        if self.msgq_socket_file is not None:
-             c_channel_env["BIND10_MSGQ_SOCKET_FILE"] = self.msgq_socket_file 
-        if self.verbose:
-            sys.stdout.write("[bind10] Checking for already running b10-msgq\n")
-        # try to connect, and if we can't wait a short while
-        try:
-            self.cc_session = isc.cc.Session(self.msgq_socket_file)
-            return "b10-msgq already running, or socket file not cleaned , cannot start"
-        except isc.cc.session.SessionError:
-            # this is the case we want, where the msgq is not running
-            pass
-
-        # start the c-channel daemon
-        if self.verbose:
-            if self.msgq_socket_file:
-                sys.stdout.write("[bind10] Starting b10-msgq\n")
-        try:
-            c_channel = ProcessInfo("b10-msgq", ["b10-msgq"], c_channel_env,
-                                    True, not self.verbose, uid=self.uid,
-                                    username=self.username)
-        except Exception as e:
-            return "Unable to start b10-msgq; " + str(e)
+
+    def kill_started_processes(self):
+        """
+            Called as part of the exception handling when a process fails to
+            start, this runs through the list of started processes, killing
+            each one.  It then clears that list.
+        """
+        if self.verbose:
+            sys.stdout.write("[bind10] killing started processes:\n")
+
+        for pid in self.processes:
+            if self.verbose:
+                sys.stdout.write("[bind10] - %s\n" % self.processes[pid].name)
+            self.processes[pid].process.kill()
+        self.processes = {}
+
+    def read_bind10_config(self):
+        """
+            Reads the parameters associated with the BoB module itself.
+
+            At present these are the components to start although arguably this
+            information should be in the configuration for the appropriate
+            module itself. (However, this would cause difficulty in the case of
+            xfrin/xfrout and zone manager as we don't need to start those if we
+            are not running the authoritative server.)
+        """
+        if self.verbose:
+            sys.stdout.write("[bind10] Reading Boss configuration:\n")
+
+        config_data = self.ccs.get_full_config()
+        self.cfg_start_auth = config_data.get("start_auth")
+        self.cfg_start_recurse = config_data.get("start_recurse")
+
+        if self.verbose:
+            sys.stdout.write("[bind10] - start_auth: %s\n" %
+                str(self.cfg_start_auth))
+            sys.stdout.write("[bind10] - start_recurse: %s\n" %
+                str(self.cfg_start_recurse))
+
+    def log_starting(self, process, port = None, address = None):
+        """
+            A convenience function to output a "Starting xxx" message if the
+            verbose option is set.  Putting this into a separate method ensures
+            that the output form is consistent across all processes.
+
+            The process name (passed as the first argument) is put into
+            self.curproc, and is used to indicate which process failed to
+            start if there is an error (and is used in the "Started" message
+            on success).  The optional port and address information are
+            appended to the message (if present).
+        """
+        self.curproc = process
+        if self.verbose:
+            sys.stdout.write("[bind10] Starting %s" % self.curproc)
+            if port is not None:
+                sys.stdout.write(" on port %d" % port)
+                if address is not None:
+                    sys.stdout.write(" (address %s)" % str(address))
+            sys.stdout.write("\n")
+
+    def log_started(self, pid = None):
+        """
+            A convenience function to output a 'Started xxxx (PID yyyy)'
+            message.  As with starting_message(), this ensures a consistent
+            format.
+        """
+        if self.verbose:
+            sys.stdout.write("[bind10] Started %s" % self.curproc)
+            if pid is not None:
+                sys.stdout.write(" (PID %d)" % pid)
+            sys.stdout.write("\n")
+
+    # The next few methods start the individual processes of BIND-10.  They
+    # are called via start_all_process().  If any fail, an exception is raised
+    # which is caught by the caller of start_all_processes(); this kills
+    # processes started up to that point before terminating the program.
+
+    def start_msgq(self, c_channel_env):
+        """
+            Start the message queue and connect to the command channel.
+        """
+        self.log_starting("b10-msgq")
+        c_channel = ProcessInfo("b10-msgq", ["b10-msgq"], c_channel_env,
+                                True, not self.verbose, uid=self.uid,
+                                username=self.username)
         self.processes[c_channel.pid] = c_channel
-        if self.verbose:
-            sys.stdout.write("[bind10] Started b10-msgq (PID %d)\n" % 
-                             c_channel.pid)
-
-        # now connect to the c-channel
+        self.log_started(c_channel.pid)
+
+        # Now connect to the c-channel
         cc_connect_start = time.time()
         while self.cc_session is None:
             # if we have been trying for "a while" give up
             if (time.time() - cc_connect_start) > 5:
-                c_channel.process.kill()
-                return "Unable to connect to c-channel after 5 seconds"
+                raise CChannelConnectError("Unable to connect to c-channel after 5 seconds")
+
             # try to connect, and if we can't wait a short while
             try:
                 self.cc_session = isc.cc.Session(self.msgq_socket_file)
             except isc.cc.session.SessionError:
                 time.sleep(0.1)
 
-        # start the configuration manager
-        if self.verbose:
-            sys.stdout.write("[bind10] Starting b10-cfgmgr\n")
-        try:
-            bind_cfgd = ProcessInfo("b10-cfgmgr", ["b10-cfgmgr"],
-                                    c_channel_env, uid=self.uid,
-                                    username=self.username)
-        except Exception as e:
-            c_channel.process.kill()
-            return "Unable to start b10-cfgmgr; " + str(e)
+    def start_cfgmgr(self, c_channel_env):
+        """
+            Starts the configuration manager process
+        """
+        self.log_starting("b10-cfgmgr")
+        bind_cfgd = ProcessInfo("b10-cfgmgr", ["b10-cfgmgr"],
+                                c_channel_env, uid=self.uid,
+                                username=self.username)
         self.processes[bind_cfgd.pid] = bind_cfgd
-        if self.verbose:
-            sys.stdout.write("[bind10] Started b10-cfgmgr (PID %d)\n" % 
-                             bind_cfgd.pid)
+        self.log_started(bind_cfgd.pid)
 
         # sleep until b10-cfgmgr is fully up and running, this is a good place
         # to have a (short) timeout on synchronized groupsend/receive
         # TODO: replace the sleep by a listen for ConfigManager started
         # message
         time.sleep(1)
-        if self.verbose:
-            sys.stdout.write("[bind10] starting ccsession\n")
+
+    def start_ccsession(self, c_channel_env):
+        """
+            Start the CC Session
+
+            The argument c_channel_env is unused but is supplied to keep the
+            argument list the same for all start_xxx methods.
+        """
+        self.log_starting("ccsession")
         self.ccs = isc.config.ModuleCCSession(SPECFILE_LOCATION, 
                                       self.config_handler, self.command_handler)
         self.ccs.start()
-        if self.verbose:
-            sys.stdout.write("[bind10] ccsession started\n")
-
-        # start b10-auth
+        self.log_started()
+
+    # A couple of utility methods for starting processes...
+
+    def start_process(self, name, args, c_channel_env, port=None, address=None):
+        """
+            Given a set of command arguments, start the process and output
+            appropriate log messages.  If the start is successful, the process
+            is added to the list of started processes.
+
+            The port and address arguments are for log messages only.
+        """
+        self.log_starting(name, port, address)
+        newproc = ProcessInfo(name, args, c_channel_env)
+        self.processes[newproc.pid] = newproc
+        self.log_started(newproc.pid)
+
+    def start_simple(self, name, c_channel_env, port=None, address=None):
+        """
+            Most of the BIND-10 processes are started with the command:
+
+                <process-name> [-v]
+
+            ... where -v is appended if verbose is enabled.  This method
+            generates the arguments from the name and starts the process.
+
+            The port and address arguments are for log messages only.
+        """
+        # Set up the command arguments.
+        args = [name]
+        if self.verbose:
+            args += ['-v']
+
+        # ... and start the process
+        self.start_process(name, args, c_channel_env, port, address)
+
+    # The next few methods start up the rest of the BIND-10 processes.
+    # Although many of these methods are little more than a call to
+    # start_simple, they are retained (a) for testing reasons and (b) as a place
+    # where modifications can be made if the process start-up sequence changes
+    # for a given process.
+
+    def start_auth(self, c_channel_env):
+        """
+            Start the Authoritative server
+        """
         # XXX: this must be read from the configuration manager in the future
         authargs = ['b10-auth', '-p', str(self.auth_port)]
         if self.address:
@@ -325,130 +426,115 @@
             authargs += ['-u', str(self.uid)]
         if self.verbose:
             authargs += ['-v']
-            sys.stdout.write("Starting b10-auth using port %d" %
-                             self.auth_port)
-            if self.address:
-                sys.stdout.write(" on %s" % str(self.address))
-            sys.stdout.write("\n")
-        try:
-            auth = ProcessInfo("b10-auth", authargs,
-                               c_channel_env)
-        except Exception as e:
-            c_channel.process.kill()
-            bind_cfgd.process.kill()
-            xfrout.process.kill()
-            return "Unable to start b10-auth; " + str(e)
-        self.processes[auth.pid] = auth
-        if self.verbose:
-            sys.stdout.write("[bind10] Started b10-auth (PID %d)\n" % auth.pid)
-
-        # everything after the authoritative server can run as non-root
+
+        # ... and start
+        self.start_process("b10-auth", authargs, c_channel_env,
+            self.auth_port, self.address)
+
+    def start_recurse(self, c_channel_env):
+        """
+            Start the Resolver.  At present, all these arguments and switches
+            are pure speculation.  As with the auth daemon, they should be
+            read from the configuration database.
+        """
+        self.curproc = "b10-recurse"
+        # XXX: this must be read from the configuration manager in the future
+        resargs = ['b10-recurse']
+        if self.uid:
+            resargs += ['-u', str(self.uid)]
+        if self.verbose:
+            resargs += ['-v']
+
+        # ... and start
+        self.start_process("b10-recurse", resargs, c_channel_env)
+
+    def start_xfrout(self, c_channel_env):
+        self.start_simple("b10-xfrout", c_channel_env)
+
+    def start_xfrin(self, c_channel_env):
+        self.start_simple("b10-xfrin", c_channel_env)
+
+    def start_zonemgr(self, c_channel_env):
+        self.start_simple("b10-zonemgr", c_channel_env)
+
+    def start_stats(self, c_channel_env):
+        self.start_simple("b10-stats", c_channel_env)
+
+    def start_cmdctl(self, c_channel_env):
+        # XXX: we hardcode port 8080
+        self.start_simple("b10-cmdctl", c_channel_env, 8080)
+
+    def start_all_processes(self, c_channel_env):
+        """
+            Starts up all the processes.  Any exception generated during the
+            starting of the processes is handled by the caller.
+        """
+        self.start_msgq(c_channel_env)
+        self.start_cfgmgr(c_channel_env)
+        self.start_ccsession(c_channel_env)
+
+        # Extract the parameters associated with Bob.  This can only be
+        # done after the CC Session is started.
+        self.read_bind10_config()
+
+        # Continue starting the processes.  The authoritative server (if
+        # selected):
+        if self.cfg_start_auth:
+            self.start_auth(c_channel_env)
+
+        # ... and resolver (if selected):
+        if self.cfg_start_recurse:
+            self.start_recurse(c_channel_env)
+
+        # Everything after the main components can run as non-root.
+        # TODO: this is only temporary - once the privileged socket creator is
+        # fully working, nothing else will run as root.
         if self.uid is not None:
             posix.setuid(self.uid)
 
-        # start the xfrout before auth-server, to make sure every xfr-query can
-        # be processed properly.
-        xfrout_args = ['b10-xfrout']
-        if self.verbose:
-            sys.stdout.write("[bind10] Starting b10-xfrout\n")
-            xfrout_args += ['-v']
+        # xfrin/xfrout and the zone manager are only meaningful if the
+        # authoritative server has been started.
+        if self.cfg_start_auth:
+            self.start_xfrout(c_channel_env)
+            self.start_xfrin(c_channel_env)
+            self.start_zonemgr(c_channel_env)
+
+        # ... and finally start the remaining processes
+        self.start_stats(c_channel_env)
+        self.start_cmdctl(c_channel_env)
+    
+    def startup(self):
+        """
+            Start the BoB instance.
+ 
+            Returns None if successful, otherwise an string describing the
+            problem.
+        """
+        # Try to connect to the c-channel daemon, to see if it is already
+        # running
+        c_channel_env = {}
+        if self.msgq_socket_file is not None:
+             c_channel_env["BIND10_MSGQ_SOCKET_FILE"] = self.msgq_socket_file 
+        if self.verbose:
+           sys.stdout.write("[bind10] Checking for already running b10-msgq\n")
+        # try to connect, and if we can't wait a short while
         try:
-            xfrout = ProcessInfo("b10-xfrout", xfrout_args, 
-                                 c_channel_env )
+            self.cc_session = isc.cc.Session(self.msgq_socket_file)
+            return "b10-msgq already running, or socket file not cleaned , cannot start"
+        except isc.cc.session.SessionError:
+            # this is the case we want, where the msgq is not running
+            pass
+
+        # Start all processes.  If any one fails to start, kill all started
+        # processes and exit with an error indication.
+        try:
+            self.start_all_processes(c_channel_env)
         except Exception as e:
-            c_channel.process.kill()
-            bind_cfgd.process.kill()
-            return "Unable to start b10-xfrout; " + str(e)
-        self.processes[xfrout.pid] = xfrout
-        if self.verbose:
-            sys.stdout.write("[bind10] Started b10-xfrout (PID %d)\n" % 
-                             xfrout.pid)
-
-        # start b10-xfrin
-        xfrin_args = ['b10-xfrin']
-        if self.verbose:
-            sys.stdout.write("[bind10] Starting b10-xfrin\n")
-            xfrin_args += ['-v']
-        try:
-            xfrind = ProcessInfo("b10-xfrin", xfrin_args,
-                                 c_channel_env)
-        except Exception as e:
-            c_channel.process.kill()
-            bind_cfgd.process.kill()
-            xfrout.process.kill()
-            auth.process.kill()
-            return "Unable to start b10-xfrin; " + str(e)
-        self.processes[xfrind.pid] = xfrind
-        if self.verbose:
-            sys.stdout.write("[bind10] Started b10-xfrin (PID %d)\n" % 
-                             xfrind.pid)
-
-        # start b10-zonemgr
-        zonemgr_args = ['b10-zonemgr']
-        if self.verbose:
-            sys.stdout.write("[bind10] Starting b10-zonemgr\n")
-            zonemgr_args += ['-v']
-        try:
-            zonemgr = ProcessInfo("b10-zonemgr", zonemgr_args,
-                                 c_channel_env)
-        except Exception as e:
-            c_channel.process.kill()
-            bind_cfgd.process.kill()
-            xfrout.process.kill()
-            auth.process.kill()
-            xfrind.process.kill()
-            return "Unable to start b10-zonemgr; " + str(e)
-        self.processes[zonemgr.pid] = zonemgr 
-        if self.verbose:
-            sys.stdout.write("[bind10] Started b10-zonemgr(PID %d)\n" % 
-                             zonemgr.pid)
-
-        # start b10-stats
-        stats_args = ['b10-stats']
-        if self.verbose:
-            sys.stdout.write("[bind10] Starting b10-stats\n")
-            stats_args += ['-v']
-        try:
-            statsd = ProcessInfo("b10-stats", stats_args,
-                                 c_channel_env)
-        except Exception as e:
-            c_channel.process.kill()
-            bind_cfgd.process.kill()
-            xfrout.process.kill()
-            auth.process.kill()
-            xfrind.process.kill()
-            zonemgr.process.kill()
-            return "Unable to start b10-stats; " + str(e)
-
-        self.processes[statsd.pid] = statsd
-        if self.verbose:
-            sys.stdout.write("[bind10] Started b10-stats (PID %d)\n" % statsd.pid)
-
-        # start the b10-cmdctl
-        # XXX: we hardcode port 8080
-        cmdctl_args = ['b10-cmdctl']
-        if self.verbose:
-            sys.stdout.write("[bind10] Starting b10-cmdctl on port 8080\n")
-            cmdctl_args += ['-v']
-        try:
-            cmd_ctrld = ProcessInfo("b10-cmdctl", cmdctl_args,
-                                    c_channel_env)
-        except Exception as e:
-            c_channel.process.kill()
-            bind_cfgd.process.kill()
-            xfrout.process.kill()
-            auth.process.kill()
-            xfrind.process.kill()
-            zonemgr.process.kill()
-            statsd.process.kill()
-            return "Unable to start b10-cmdctl; " + str(e)
-        self.processes[cmd_ctrld.pid] = cmd_ctrld
-        if self.verbose:
-            sys.stdout.write("[bind10] Started b10-cmdctl (PID %d)\n" % 
-                             cmd_ctrld.pid)
-
+            self.kill_started_processes()
+            return "Unable to start " + self.curproc + ": " + str(e)
+
+        # Started successfully
         self.runnable = True
-
         return None
 
     def stop_all_processes(self):
@@ -457,6 +543,7 @@
         self.cc_session.group_sendmsg(cmd, 'Cmdctl', 'Cmdctl')
         self.cc_session.group_sendmsg(cmd, "ConfigManager", "ConfigManager")
         self.cc_session.group_sendmsg(cmd, "Auth", "Auth")
+        self.cc_session.group_sendmsg(cmd, "Recurse", "Recurse")
         self.cc_session.group_sendmsg(cmd, "Xfrout", "Xfrout")
         self.cc_session.group_sendmsg(cmd, "Xfrin", "Xfrin")
         self.cc_session.group_sendmsg(cmd, "Zonemgr", "Zonemgr")
@@ -525,27 +612,44 @@
                 raise
             if pid == 0: break
             if pid in self.processes:
+
+                # One of the processes we know about.  Get information on it.
                 proc_info = self.processes.pop(pid)
                 proc_info.restart_schedule.set_run_stop_time()
                 self.dead_processes[proc_info.pid] = proc_info
-                if self.verbose:
-                    sys.stdout.write("[bind10] Process %s (PID %d) died.\n" % 
-                                     (proc_info.name, proc_info.pid))
-                if proc_info.name == "b10-msgq":
-                    if self.verbose and self.runnable:
+
+                # Write out message, but only if in the running state:
+                # During startup and shutdown, these messages are handled
+                # elsewhere.
+                if self.runnable:
+                    if exit_status is None:
+                        sys.stdout.write(
+                            "[bind10] Process %s (PID %d) died: exit status not available" % 
+                            (proc_info.name, proc_info.pid))
+                    else:
+                        sys.stdout.write(
+                            "[bind10] Process %s (PID %d) terminated, exit status = %d\n" % 
+                            (proc_info.name, proc_info.pid, exit_status))
+
+                    # Was it a special process?
+                    if proc_info.name == "b10-msgq":
                         sys.stdout.write(
                                  "[bind10] The b10-msgq process died, shutting down.\n")
-                    self.runnable = False
+                        self.runnable = False
             else:
                 sys.stdout.write("[bind10] Unknown child pid %d exited.\n" % pid)
 
     def restart_processes(self):
-        """Restart any dead processes.
-        Returns the time when the next process is ready to be restarted. 
-          If the server is shutting down, returns 0.
-          If there are no processes, returns None.
-        The values returned can be safely passed into select() as the 
-        timeout value."""
+        """
+            Restart any dead processes:
+
+            * Returns the time when the next process is ready to be restarted. 
+            * If the server is shutting down, returns 0.
+            * If there are no processes, returns None.
+
+            The values returned can be safely passed into select() as the 
+            timeout value.
+        """
         next_restart = None
         # if we're shutting down, then don't restart
         if not self.runnable:
@@ -562,13 +666,12 @@
             else:
                 if self.verbose:
                     sys.stdout.write("[bind10] Resurrecting dead %s process...\n" % 
-                                     proc_info.name)
+                        proc_info.name)
                 try:
                     proc_info.respawn()
                     self.processes[proc_info.pid] = proc_info
-                    if self.verbose:
-                        sys.stdout.write("[bind10] Resurrected %s (PID %d)\n" %
-                                         (proc_info.name, proc_info.pid))
+                    sys.stdout.write("[bind10] Resurrected %s (PID %d)\n" %
+                                     (proc_info.name, proc_info.pid))
                 except:
                     still_dead[proc_info.pid] = proc_info
         # remember any processes that refuse to be resurrected
@@ -629,7 +732,7 @@
 
 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)
+    isc.util.process.rename(value)
 
 def main():
     global options
@@ -637,11 +740,10 @@
     # Enforce line buffering on stdout, even when not a TTY
     sys.stdout = io.TextIOWrapper(sys.stdout.detach(), line_buffering=True)
 
-
     # Parse any command-line options.
     parser = OptionParser(version=VERSION)
     parser.add_option("-a", "--address", dest="address", type="string",
-                      action="callback", callback=check_addr, default='',
+                      action="callback", callback=check_addr, default=None,
                       help="address the b10-auth daemon will use (default: listen on all addresses)")
     parser.add_option("-m", "--msgq-socket-file", dest="msgq_socket_file",
                       type="string", default=None,
@@ -776,6 +878,7 @@
     # shutdown
     signal.signal(signal.SIGCHLD, signal.SIG_DFL)
     boss_of_bind.shutdown()
+    sys.stdout.write("[bind10] BIND 10 exiting\n");
     sys.exit(0)
 
 if __name__ == "__main__":

Modified: branches/trac397focused/src/bin/bind10/bob.spec
==============================================================================
--- branches/trac397focused/src/bin/bind10/bob.spec (original)
+++ branches/trac397focused/src/bin/bind10/bob.spec Mon Dec 20 08:19:35 2010
@@ -3,6 +3,18 @@
     "module_name": "Boss",
     "module_description": "Master process",
     "config_data": [
+      {
+        "item_name": "start_auth",
+        "item_type": "boolean",
+        "item_optional": false,
+        "item_default": true
+      },
+      {
+        "item_name": "start_recurse",
+        "item_type": "boolean",
+        "item_optional": false,
+        "item_default": false
+      }
     ],
     "commands": [
       {

Modified: branches/trac397focused/src/bin/bind10/run_bind10.sh.in
==============================================================================
--- branches/trac397focused/src/bin/bind10/run_bind10.sh.in (original)
+++ branches/trac397focused/src/bin/bind10/run_bind10.sh.in Mon Dec 20 08:19:35 2010
@@ -20,7 +20,7 @@
 
 BIND10_PATH=@abs_top_builddir@/src/bin/bind10
 
-PATH=@abs_top_builddir@/src/bin/msgq:@abs_top_builddir@/src/bin/auth:@abs_top_builddir@/src/bin/cfgmgr:@abs_top_builddir@/src/bin/cmdctl:@abs_top_builddir@/src/bin/stats:@abs_top_builddir@/src/bin/xfrin:@abs_top_builddir@/src/bin/xfrout:@abs_top_builddir@/src/bin/zonemgr:$PATH
+PATH=@abs_top_builddir@/src/bin/msgq:@abs_top_builddir@/src/bin/auth:@abs_top_builddir@/src/bin/cfgmgr:@abs_top_builddir@/src/bin/cmdctl:@abs_top_builddir@/src/bin/stats:@abs_top_builddir@/src/bin/xfrin:@abs_top_builddir@/src/bin/xfrout:@abs_top_builddir@/src/bin/zonemgr:@abs_top_builddir@/src/bin/recurse:$PATH
 export PATH
 
 PYTHONPATH=@abs_top_builddir@/src/lib/python:@abs_top_builddir@/src/lib/dns/python/.libs:@abs_top_builddir@/src/lib/xfr/.libs

Modified: branches/trac397focused/src/bin/bind10/tests/bind10_test.py
==============================================================================
--- branches/trac397focused/src/bin/bind10/tests/bind10_test.py (original)
+++ branches/trac397focused/src/bin/bind10/tests/bind10_test.py Mon Dec 20 08:19:35 2010
@@ -79,43 +79,237 @@
         self.assertEqual(bob.verbose, False)
         self.assertEqual(bob.msgq_socket_file, None)
         self.assertEqual(bob.auth_port, 5300)
+        self.assertEqual(bob.address, None)
         self.assertEqual(bob.cc_session, None)
-        self.assertEqual(bob.address, None)
+        self.assertEqual(bob.ccs, None)
         self.assertEqual(bob.processes, {})
         self.assertEqual(bob.dead_processes, {})
         self.assertEqual(bob.runnable, False)
+        self.assertEqual(bob.uid, None)
+        self.assertEqual(bob.username, None)
+        self.assertEqual(bob.nocache, False)
+        self.assertEqual(bob.cfg_start_auth, True)
+        self.assertEqual(bob.cfg_start_recurse, False)
 
     def test_init_alternate_socket(self):
         bob = BoB("alt_socket_file")
         self.assertEqual(bob.verbose, False)
         self.assertEqual(bob.msgq_socket_file, "alt_socket_file")
+        self.assertEqual(bob.auth_port, 5300)
+        self.assertEqual(bob.address, None)
         self.assertEqual(bob.cc_session, None)
+        self.assertEqual(bob.ccs, None)
         self.assertEqual(bob.processes, {})
         self.assertEqual(bob.dead_processes, {})
         self.assertEqual(bob.runnable, False)
+        self.assertEqual(bob.uid, None)
+        self.assertEqual(bob.username, None)
+        self.assertEqual(bob.nocache, False)
+        self.assertEqual(bob.cfg_start_auth, True)
+        self.assertEqual(bob.cfg_start_recurse, False)
 
     def test_init_alternate_auth_port(self):
         bob = BoB(None, 9999)
         self.assertEqual(bob.verbose, False)
         self.assertEqual(bob.msgq_socket_file, None)
         self.assertEqual(bob.auth_port, 9999)
+        self.assertEqual(bob.address, None)
         self.assertEqual(bob.cc_session, None)
-        self.assertEqual(bob.address, None)
+        self.assertEqual(bob.ccs, None)
         self.assertEqual(bob.processes, {})
         self.assertEqual(bob.dead_processes, {})
         self.assertEqual(bob.runnable, False)
+        self.assertEqual(bob.uid, None)
+        self.assertEqual(bob.username, None)
+        self.assertEqual(bob.nocache, False)
+        self.assertEqual(bob.cfg_start_auth, True)
+        self.assertEqual(bob.cfg_start_recurse, False)
 
     def test_init_alternate_address(self):
-        bob = BoB(None, 5300, IPAddr('127.127.127.127'))
+        bob = BoB(None, 1234, IPAddr('127.127.127.127'))
         self.assertEqual(bob.verbose, False)
-        self.assertEqual(bob.auth_port, 5300)
         self.assertEqual(bob.msgq_socket_file, None)
+        self.assertEqual(bob.auth_port, 1234)
+        self.assertEqual(bob.address.addr, socket.inet_aton('127.127.127.127'))
         self.assertEqual(bob.cc_session, None)
-        self.assertEqual(bob.address.addr, socket.inet_aton('127.127.127.127'))
+        self.assertEqual(bob.ccs, None)
         self.assertEqual(bob.processes, {})
         self.assertEqual(bob.dead_processes, {})
         self.assertEqual(bob.runnable, False)
-    # verbose testing...
+        self.assertEqual(bob.uid, None)
+        self.assertEqual(bob.username, None)
+        self.assertEqual(bob.nocache, False)
+        self.assertEqual(bob.cfg_start_auth, True)
+        self.assertEqual(bob.cfg_start_recurse, False)
+
+# Class for testing the Bob.start_all_processes() method call.
+#
+# Although testing that external processes start is outside the scope
+# of the unit test, by overriding the process start methods we can check
+# that the right processes are started depending on the configuration
+# options.
+class StartAllProcessesBob(BoB):
+    def __init__(self):
+        BoB.__init__(self)
+
+# Set flags as to which of the overridden methods has been run.
+        self.msgq = False
+        self.cfgmgr = False
+        self.ccsession = False
+        self.auth = False
+        self.recurse = False
+        self.xfrout = False
+        self.xfrin = False
+        self.zonemgr = False
+        self.stats = False
+        self.cmdctl = False
+
+    def read_bind10_config(self):
+        # Configuration options are set directly
+        pass
+
+    def start_msgq(self, c_channel_env):
+        self.msgq = True
+
+    def start_cfgmgr(self, c_channel_env):
+        self.cfgmgr = True
+
+    def start_ccsession(self, c_channel_env):
+        self.ccsession = True
+
+    def start_auth(self, c_channel_env):
+        self.auth = True
+
+    def start_recurse(self, c_channel_env):
+        self.recurse = True
+
+    def start_xfrout(self, c_channel_env):
+        self.xfrout = True
+
+    def start_xfrin(self, c_channel_env):
+        self.xfrin = True
+
+    def start_zonemgr(self, c_channel_env):
+        self.zonemgr = True
+
+    def start_stats(self, c_channel_env):
+        self.stats = True
+
+    def start_cmdctl(self, c_channel_env):
+        self.cmdctl = True
+
+# Check that the start_all_processes method starts the right combination
+# of processes.
+class TestStartAllProcessesBob(unittest.TestCase):
+    def check_preconditions(self, bob):
+        self.assertEqual(bob.msgq, False)
+        self.assertEqual(bob.cfgmgr, False)
+        self.assertEqual(bob.ccsession, False)
+        self.assertEqual(bob.auth, False)
+        self.assertEqual(bob.recurse, False)
+        self.assertEqual(bob.xfrout, False)
+        self.assertEqual(bob.xfrin, False)
+        self.assertEqual(bob.zonemgr, False)
+        self.assertEqual(bob.stats, False)
+        self.assertEqual(bob.cmdctl, False)
+
+    # Checks the processes started when starting neither auth nor recurse
+    # is specified.
+    def test_start_none(self):
+        # Created Bob and ensure initialization correct
+        bob = StartAllProcessesBob()
+        self.check_preconditions(bob)
+
+        # Start processes and check what was started
+        c_channel_env = {}
+        bob.cfg_start_auth = False
+        bob.cfg_start_recurse = False
+
+        bob.start_all_processes(c_channel_env)
+
+        self.assertEqual(bob.msgq, True)
+        self.assertEqual(bob.cfgmgr, True)
+        self.assertEqual(bob.ccsession, True)
+        self.assertEqual(bob.auth, False)
+        self.assertEqual(bob.recurse, False)
+        self.assertEqual(bob.xfrout, False)
+        self.assertEqual(bob.xfrin, False)
+        self.assertEqual(bob.zonemgr, False)
+        self.assertEqual(bob.stats, True)
+        self.assertEqual(bob.cmdctl, True)
+
+    # Checks the processes started when starting only the auth process
+    def test_start_auth(self):
+        # Created Bob and ensure initialization correct
+        bob = StartAllProcessesBob()
+        self.check_preconditions(bob)
+
+        # Start processes and check what was started
+        c_channel_env = {}
+        bob.cfg_start_auth = True
+        bob.cfg_start_recurse = False
+
+        bob.start_all_processes(c_channel_env)
+
+        self.assertEqual(bob.msgq, True)
+        self.assertEqual(bob.cfgmgr, True)
+        self.assertEqual(bob.ccsession, True)
+        self.assertEqual(bob.auth, True)
+        self.assertEqual(bob.recurse, False)
+        self.assertEqual(bob.xfrout, True)
+        self.assertEqual(bob.xfrin, True)
+        self.assertEqual(bob.zonemgr, True)
+        self.assertEqual(bob.stats, True)
+        self.assertEqual(bob.cmdctl, True)
+
+    # Checks the processes started when starting only the recurse process
+    def test_start_recurse(self):
+        # Created Bob and ensure initialization correct
+        bob = StartAllProcessesBob()
+        self.check_preconditions(bob)
+
+        # Start processes and check what was started
+        c_channel_env = {}
+        bob.cfg_start_auth = False
+        bob.cfg_start_recurse = True
+
+        bob.start_all_processes(c_channel_env)
+
+        self.assertEqual(bob.msgq, True)
+        self.assertEqual(bob.cfgmgr, True)
+        self.assertEqual(bob.ccsession, True)
+        self.assertEqual(bob.auth, False)
+        self.assertEqual(bob.recurse, True)
+        self.assertEqual(bob.xfrout, False)
+        self.assertEqual(bob.xfrin, False)
+        self.assertEqual(bob.zonemgr, False)
+        self.assertEqual(bob.stats, True)
+        self.assertEqual(bob.cmdctl, True)
+
+    # Checks the processes started when starting both auth and recurse process
+    def test_start_both(self):
+        # Created Bob and ensure initialization correct
+        bob = StartAllProcessesBob()
+        self.check_preconditions(bob)
+
+        # Start processes and check what was started
+        c_channel_env = {}
+        bob.cfg_start_auth = True
+        bob.cfg_start_recurse = True
+
+        bob.start_all_processes(c_channel_env)
+
+        self.assertEqual(bob.msgq, True)
+        self.assertEqual(bob.cfgmgr, True)
+        self.assertEqual(bob.ccsession, True)
+        self.assertEqual(bob.auth, True)
+        self.assertEqual(bob.recurse, True)
+        self.assertEqual(bob.xfrout, True)
+        self.assertEqual(bob.xfrin, True)
+        self.assertEqual(bob.zonemgr, True)
+        self.assertEqual(bob.stats, True)
+        self.assertEqual(bob.cmdctl, True)
+
 
 if __name__ == '__main__':
     unittest.main()

Modified: branches/trac397focused/src/bin/bindctl/bindcmd.py
==============================================================================
--- branches/trac397focused/src/bin/bindctl/bindcmd.py (original)
+++ branches/trac397focused/src/bin/bindctl/bindcmd.py Mon Dec 20 08:19:35 2010
@@ -558,7 +558,7 @@
                     if value_map['type'] in [ 'module', 'map', 'list' ]:
                         line += "/"
                     else:
-                        line += ":\t" + str(value_map['value'])
+                        line += ":\t" + json.dumps(value_map['value'])
                     line += "\t" + value_map['type']
                     line += "\t"
                     if value_map['default']:
@@ -569,7 +569,10 @@
             elif cmd.command == "add":
                 self.config_data.add_value(identifier, cmd.params['value'])
             elif cmd.command == "remove":
-                self.config_data.remove_value(identifier, cmd.params['value'])
+                if 'value' in cmd.params:
+                    self.config_data.remove_value(identifier, cmd.params['value'])
+                else:
+                    self.config_data.remove_value(identifier, None)
             elif cmd.command == "set":
                 if 'identifier' not in cmd.params:
                     print("Error: missing identifier or value")

Modified: branches/trac397focused/src/bin/bindctl/bindctl-source.py.in
==============================================================================
--- branches/trac397focused/src/bin/bindctl/bindctl-source.py.in (original)
+++ branches/trac397focused/src/bin/bindctl/bindctl-source.py.in Mon Dec 20 08:19:35 2010
@@ -24,11 +24,14 @@
 from bindctl.bindcmd import *
 import pprint
 from optparse import OptionParser, OptionValueError
-import isc.utils.process
+import isc.util.process
 
-isc.utils.process.rename()
+isc.util.process.rename()
 
-__version__ = 'Bindctl'
+# This is the version that gets displayed to the user.
+# The VERSION string consists of the module name, the module version
+# number, and the overall BIND 10 version number (set in configure.ac).
+VERSION = "bindctl 20101201 (BIND 10 @PACKAGE_VERSION@)"
 
 def prepare_config_commands(tool):
     '''Prepare fixed commands for local configuration editing'''
@@ -48,7 +51,7 @@
     cmd = CommandInfo(name = "remove", desc = "Remove entry from configuration list")
     param = ParamInfo(name = "identifier", type = "string", optional=True)
     cmd.add_param(param)
-    param = ParamInfo(name = "value", type = "string", optional=False)
+    param = ParamInfo(name = "value", type = "string", optional=True)
     cmd.add_param(param)
     module.add_command(cmd)
 
@@ -113,7 +116,7 @@
 
 if __name__ == '__main__':
     try:
-        parser = OptionParser(version = __version__)
+        parser = OptionParser(version = VERSION)
         set_bindctl_options(parser)
         (options, args) = parser.parse_args()
         server_addr = options.addr + ':' + str(options.port)

Modified: branches/trac397focused/src/bin/cfgmgr/b10-cfgmgr.py.in
==============================================================================
--- branches/trac397focused/src/bin/cfgmgr/b10-cfgmgr.py.in (original)
+++ branches/trac397focused/src/bin/cfgmgr/b10-cfgmgr.py.in Mon Dec 20 08:19:35 2010
@@ -21,11 +21,11 @@
 
 from isc.config.cfgmgr import ConfigManager, ConfigManagerDataReadError
 from isc.cc import SessionError
-import isc.utils.process
+import isc.util.process
 import signal
 import os
 
-isc.utils.process.rename()
+isc.util.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/trac397focused/src/bin/cmdctl/cmdctl.py.in
==============================================================================
--- branches/trac397focused/src/bin/cmdctl/cmdctl.py.in (original)
+++ branches/trac397focused/src/bin/cmdctl/cmdctl.py.in Mon Dec 20 08:19:35 2010
@@ -43,18 +43,18 @@
 import time
 import signal
 from isc.config import ccsession
+import isc.util.process
 import isc.net.parse
-import isc.utils.process
 from optparse import OptionParser, OptionValueError
 from hashlib import sha1
-from isc.utils import socketserver_mixin
+from isc.util import socketserver_mixin
 
 try:
     import threading
 except ImportError:
     import dummy_threading as threading
 
-isc.utils.process.rename()
+isc.util.process.rename()
 
 __version__ = 'BIND10'
 URL_PATTERN = re.compile('/([\w]+)(?:/([\w]+))?/?')

Modified: branches/trac397focused/src/bin/host/Makefile.am
==============================================================================
--- branches/trac397focused/src/bin/host/Makefile.am (original)
+++ branches/trac397focused/src/bin/host/Makefile.am Mon Dec 20 08:19:35 2010
@@ -1,5 +1,6 @@
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
+AM_CPPFLAGS += $(BOOST_INCLUDES)
 
 AM_CXXFLAGS = $(B10_CXXFLAGS)
 

Modified: branches/trac397focused/src/bin/host/host.cc
==============================================================================
--- branches/trac397focused/src/bin/host/host.cc (original)
+++ branches/trac397focused/src/bin/host/host.cc Mon Dec 20 08:19:35 2010
@@ -58,7 +58,7 @@
     msg.setOpcode(Opcode::QUERY());
     msg.setRcode(Rcode::NOERROR());
     if (recursive_bit) {
-        msg.setHeaderFlag(MessageFlag::RD());    // set recursive bit
+        msg.setHeaderFlag(Message::HEADERFLAG_RD); // set recursive bit
     }
 
     msg.addQuestion(Question(Name(name),
@@ -122,15 +122,16 @@
 
             rmsg.fromWire(ibuffer);
             if (!verbose) {
-                  for (RRsetIterator it = rmsg.beginSection(Section::ANSWER());
-                       it != rmsg.endSection(Section::ANSWER());
-                       ++it) {
+                for (RRsetIterator it =
+                         rmsg.beginSection(Message::SECTION_ANSWER);
+                     it != rmsg.endSection(Message::SECTION_ANSWER);
+                     ++it) {
                       if ((*it)->getType() != RRType::A()) {
                           continue;
                       }
 
                       RdataIteratorPtr rit = (*it)->getRdataIterator();
-                      for (rit->first(); !rit->isLast(); rit->next()) {
+                      for (; !rit->isLast(); rit->next()) {
                           // instead of using my name, maybe use returned label?
                           cout << name << " has address " <<
                               (*rit).getCurrent().toText() << endl;

Modified: branches/trac397focused/src/bin/loadzone/b10-loadzone.py.in
==============================================================================
--- branches/trac397focused/src/bin/loadzone/b10-loadzone.py.in (original)
+++ branches/trac397focused/src/bin/loadzone/b10-loadzone.py.in Mon Dec 20 08:19:35 2010
@@ -18,12 +18,12 @@
 import sys; sys.path.append ('@@PYTHONPATH@@')
 import re, getopt
 import isc.datasrc
-import isc.utils.process
+import isc.util.process
 from isc.datasrc.master import MasterFile
 import time
 import os
 
-isc.utils.process.rename()
+isc.util.process.rename()
 
 #########################################################################
 # usage: print usage note and exit

Modified: branches/trac397focused/src/bin/msgq/msgq.py.in
==============================================================================
--- branches/trac397focused/src/bin/msgq/msgq.py.in (original)
+++ branches/trac397focused/src/bin/msgq/msgq.py.in Mon Dec 20 08:19:35 2010
@@ -31,14 +31,16 @@
 import pprint
 import random
 from optparse import OptionParser, OptionValueError
-import isc.utils.process
+import isc.util.process
 
 import isc.cc
 
-isc.utils.process.rename()
+isc.util.process.rename()
 
 # This is the version that gets displayed to the user.
-__version__ = "v20091030 (Paving the DNS Parking Lot)"
+# The VERSION string consists of the module name, the module version
+# number, and the overall BIND 10 version number (set in configure.ac).
+VERSION = "b10-msgq 20100818 (BIND 10 @PACKAGE_VERSION@)"
 
 class MsgQReceiveError(Exception): pass
 
@@ -421,7 +423,7 @@
         parser.values.msgq_port = intval
 
     # Parse any command-line options.
-    parser = OptionParser(version=__version__)
+    parser = OptionParser(version=VERSION)
     parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
                       help="display more about what is going on")
     parser.add_option("-s", "--socket-file", dest="msgq_socket_file",
@@ -433,7 +435,7 @@
 
     # Announce startup.
     if options.verbose:
-        sys.stdout.write("[b10-msgq] MsgQ %s\n" % __version__)
+        sys.stdout.write("[b10-msgq] %s\n" % VERSION)
 
     msgq = MsgQ(options.msgq_socket_file, options.verbose)
 

Modified: branches/trac397focused/src/bin/stats/stats.py.in
==============================================================================
--- branches/trac397focused/src/bin/stats/stats.py.in (original)
+++ branches/trac397focused/src/bin/stats/stats.py.in Mon Dec 20 08:19:35 2010
@@ -35,8 +35,8 @@
         pass						#@@REMOVED@@
 
 # for setproctitle
-import isc.utils.process
-isc.utils.process.rename()
+import isc.util.process
+isc.util.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/trac397focused/src/bin/stats/stats_stub.py.in
==============================================================================
--- branches/trac397focused/src/bin/stats/stats_stub.py.in (original)
+++ branches/trac397focused/src/bin/stats/stats_stub.py.in Mon Dec 20 08:19:35 2010
@@ -27,8 +27,8 @@
 from stats import get_datetime
 
 # for setproctitle
-import isc.utils.process
-isc.utils.process.rename()
+import isc.util.process
+isc.util.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/trac397focused/src/bin/stats/tests/isc/Makefile.am
==============================================================================
--- branches/trac397focused/src/bin/stats/tests/isc/Makefile.am (original)
+++ branches/trac397focused/src/bin/stats/tests/isc/Makefile.am Mon Dec 20 08:19:35 2010
@@ -1,3 +1,3 @@
-SUBDIRS = cc config utils
+SUBDIRS = cc config util
 EXTRA_DIST = __init__.py
 CLEANFILES = __init__.pyc

Modified: branches/trac397focused/src/bin/tests/process_rename_test.py.in
==============================================================================
--- branches/trac397focused/src/bin/tests/process_rename_test.py.in (original)
+++ branches/trac397focused/src/bin/tests/process_rename_test.py.in Mon Dec 20 08:19:35 2010
@@ -17,7 +17,7 @@
 import unittest
 import os
 import os.path
-import isc.utils.process
+import isc.util.process
 import re
 
 class TestRename(unittest.TestCase):
@@ -28,7 +28,7 @@
         data = ''.join(open(filename).readlines())
         prettyname = 'src' + filename[filename.rfind('../') + 2:]
         self.assertTrue(fun.search(data),
-            "Didn't find a call to isc.utils.process.rename in " + prettyname)
+            "Didn't find a call to isc.util.process.rename in " + prettyname)
 
     def test_calls(self):
         """
@@ -45,7 +45,7 @@
         # Script name regular expression
         scripts = re.compile(r'((\w|[-.0-9])+)')
         # Line with the call
-        fun = re.compile(r'^\s*isc\.utils\.process\.rename\s*\(.*\)\s*(|#.*)$',
+        fun = re.compile(r'^\s*isc\.util\.process\.rename\s*\(.*\)\s*(|#.*)$',
             re.MULTILINE)
 
         # Find all Makefile and extract names of scripts

Modified: branches/trac397focused/src/bin/usermgr/b10-cmdctl-usermgr.py.in
==============================================================================
--- branches/trac397focused/src/bin/usermgr/b10-cmdctl-usermgr.py.in (original)
+++ branches/trac397focused/src/bin/usermgr/b10-cmdctl-usermgr.py.in Mon Dec 20 08:19:35 2010
@@ -25,9 +25,9 @@
 import getpass
 import getopt
 import sys
-import isc.utils.process
+import isc.util.process
 
-isc.utils.process.rename()
+isc.util.process.rename()
 
 VERSION_NUMBER = 'bind10'
 DEFAULT_FILE = 'cmdctl-accounts.csv'

Modified: branches/trac397focused/src/bin/xfrin/b10-xfrin.xml
==============================================================================
--- branches/trac397focused/src/bin/xfrin/b10-xfrin.xml (original)
+++ branches/trac397focused/src/bin/xfrin/b10-xfrin.xml Mon Dec 20 08:19:35 2010
@@ -149,7 +149,6 @@
       the authoritative server to transfer from,
       and <varname>port</varname> to define the port number on the
       authoritative server (defaults to 53).
-<!-- TODO: note: not documenting db_file since that will be removed. -->
      </para>
 <!-- TODO: later hostname for master? -->
 

Modified: branches/trac397focused/src/bin/xfrin/tests/xfrin_test.py
==============================================================================
--- branches/trac397focused/src/bin/xfrin/tests/xfrin_test.py (original)
+++ branches/trac397focused/src/bin/xfrin/tests/xfrin_test.py Mon Dec 20 08:19:35 2010
@@ -135,9 +135,9 @@
         resp.set_opcode(Opcode.QUERY())
         resp.set_rcode(rcode)
         if response:
-            resp.set_header_flag(MessageFlag.QR())
+            resp.set_header_flag(Message.HEADERFLAG_QR)
         [resp.add_question(q) for q in questions]
-        [resp.add_rrset(Section.ANSWER(), a) for a in answers]
+        [resp.add_rrset(Message.SECTION_ANSWER, a) for a in answers]
 
         renderer = MessageRenderer()
         resp.to_wire(renderer)

Modified: branches/trac397focused/src/bin/xfrin/xfrin.py.in
==============================================================================
--- branches/trac397focused/src/bin/xfrin/xfrin.py.in (original)
+++ branches/trac397focused/src/bin/xfrin/xfrin.py.in Mon Dec 20 08:19:35 2010
@@ -30,8 +30,8 @@
 from optparse import OptionParser, OptionValueError
 from isc.config.ccsession import *
 from isc.notify import notify_out
+import isc.util.process
 import isc.net.parse
-import isc.utils.process
 try:
     from pydnspp import *
 except ImportError as e:
@@ -39,7 +39,7 @@
     # 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()
+isc.util.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
@@ -240,7 +240,7 @@
         if msg_rcode != Rcode.NOERROR():
             raise XfrinException('error response: %s' % msg_rcode.to_text())
 
-        if not msg.get_header_flag(MessageFlag.QR()):
+        if not msg.get_header_flag(Message.HEADERFLAG_QR):
             raise XfrinException('response is not a response ')
 
         if msg.get_qid() != self._query_id:
@@ -251,10 +251,10 @@
 
         self._check_response_header(msg)
 
-        if msg.get_rr_count(Section.ANSWER()) == 0:
+        if msg.get_rr_count(Message.SECTION_ANSWER) == 0:
             raise XfrinException('answer section is empty')
 
-        if msg.get_rr_count(Section.QUESTION()) > 1:
+        if msg.get_rr_count(Message.SECTION_QUESTION) > 1:
             raise XfrinException('query section count greater than 1')
 
     def _handle_answer_section(self, answer_section):
@@ -294,7 +294,7 @@
             msg.from_wire(recvdata)
             self._check_response_status(msg)
             
-            answer_section = msg.get_section(Section.ANSWER())
+            answer_section = msg.get_section(Message.SECTION_ANSWER)
             for rr in self._handle_answer_section(answer_section):
                 yield rr
 

Modified: branches/trac397focused/src/bin/xfrout/b10-xfrout.8
==============================================================================
--- branches/trac397focused/src/bin/xfrout/b10-xfrout.8 (original)
+++ branches/trac397focused/src/bin/xfrout/b10-xfrout.8 Mon Dec 20 08:19:35 2010
@@ -2,12 +2,12 @@
 .\"     Title: b10-xfrout
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: September 8, 2010
+.\"      Date: December 1, 2010
 .\"    Manual: BIND10
 .\"    Source: BIND10
 .\"  Language: English
 .\"
-.TH "B10\-XFROUT" "8" "September 8, 2010" "BIND10" "BIND10"
+.TH "B10\-XFROUT" "8" "December 1, 2010" "BIND10" "BIND10"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
@@ -67,11 +67,6 @@
 The configurable settings are:
 .PP
 
-\fIdb_file\fR
-defines the path to the SQLite3 data store file\&. The default is
-/usr/local/var/bind10\-devel/zone\&.sqlite3\&.
-.PP
-
 \fItransfers_out\fR
 defines the maximum number of outgoing zone transfers that can run concurrently\&. The default is 10\&.
 .if n \{\

Modified: branches/trac397focused/src/bin/xfrout/b10-xfrout.xml
==============================================================================
--- branches/trac397focused/src/bin/xfrout/b10-xfrout.xml (original)
+++ branches/trac397focused/src/bin/xfrout/b10-xfrout.xml Mon Dec 20 08:19:35 2010
@@ -21,7 +21,7 @@
 <refentry>
 
   <refentryinfo>
-    <date>September 8, 2010</date>
+    <date>December 1, 2010</date>
   </refentryinfo>
 
   <refmeta>
@@ -92,13 +92,6 @@
     <title>CONFIGURATION AND COMMANDS</title>
     <para>
       The configurable settings are:
-    </para>
-    <para>
-      <varname>db_file</varname>
-      defines the path to the SQLite3 data store file.
-      The default is
-      <filename>/usr/local/var/bind10-devel/zone.sqlite3</filename>.
-<!-- TODO: db_file will be removed -->
     </para>
     <para>
       <varname>transfers_out</varname>

Modified: branches/trac397focused/src/bin/xfrout/tests/xfrout_test.py
==============================================================================
--- branches/trac397focused/src/bin/xfrout/tests/xfrout_test.py (original)
+++ branches/trac397focused/src/bin/xfrout/tests/xfrout_test.py Mon Dec 20 08:19:35 2010
@@ -47,22 +47,29 @@
         result = self.sendqueue[:size]
         self.sendqueue = self.sendqueue[size:]
         return result
-    
+
     def read_msg(self):
         sent_data = self.readsent()
         get_msg = Message(Message.PARSE)
         get_msg.from_wire(bytes(sent_data[2:]))
         return get_msg
-    
+
     def clear_send(self):
         del self.sendqueue[:]
 
 # We subclass the Session class we're testing here, only
-# to override the __init__() method, which wants a socket,
+# to override the handle() and _send_data() method
 class MyXfroutSession(XfroutSession):
     def handle(self):
         pass
-    
+
+    def _send_data(self, sock, data):
+        size = len(data)
+        total_count = 0
+        while total_count < size:
+            count = sock.send(data[total_count:])
+            total_count += count
+
 class Dbserver:
     def __init__(self):
         self._shutdown_event = threading.Event()
@@ -80,12 +87,21 @@
     def setUp(self):
         request = MySocket(socket.AF_INET,socket.SOCK_STREAM)
         self.log = isc.log.NSLogger('xfrout', '',  severity = 'critical', log_to_console = False )
-        self.xfrsess = MyXfroutSession(request, None, None, self.log)
+        (self.write_sock, self.read_sock) = socket.socketpair()
+        self.xfrsess = MyXfroutSession(request, None, None, self.log, self.read_sock)
         self.xfrsess.server = Dbserver()
         self.mdata = bytes(b'\xd6=\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x07example\x03com\x00\x00\xfc\x00\x01')
         self.sock = MySocket(socket.AF_INET,socket.SOCK_STREAM)
         self.soa_record = (4, 3, 'example.com.', 'com.example.', 3600, 'SOA', None, 'master.example.com. admin.example.com. 1234 3600 1800 2419200 7200')
 
+    def test_receive_query_message(self):
+        send_msg = b"\xd6=\x00\x00\x00\x01\x00"
+        msg_len = struct.pack('H', socket.htons(len(send_msg)))
+        self.write_sock.send(msg_len)
+        self.write_sock.send(send_msg)
+        recv_msg = self.xfrsess._receive_query_message(self.read_sock)
+        self.assertEqual(recv_msg, send_msg)
+
     def test_parse_query_message(self):
         [get_rcode, get_msg] = self.xfrsess._parse_query_message(self.mdata)
         self.assertEqual(get_rcode.to_text(), "NOERROR")
@@ -93,7 +109,7 @@
     def test_get_query_zone_name(self):
         msg = self.getmsg()
         self.assertEqual(self.xfrsess._get_query_zone_name(msg), "example.com.")
-  
+
     def test_send_data(self):
         self.xfrsess._send_data(self.sock, self.mdata)
         senddata = self.sock.readsent()
@@ -103,8 +119,8 @@
         msg = self.getmsg()
         self.xfrsess._reply_query_with_error_rcode(msg, self.sock, Rcode(3))
         get_msg = self.sock.read_msg()
-        self.assertEqual(get_msg.get_rcode().to_text(), "NXDOMAIN") 
-     
+        self.assertEqual(get_msg.get_rcode().to_text(), "NXDOMAIN")
+
     def test_clear_message(self):
         msg = self.getmsg()
         qid = msg.get_qid()
@@ -115,10 +131,10 @@
         self.assertEqual(msg.get_qid(), qid)
         self.assertEqual(msg.get_opcode(), opcode)
         self.assertEqual(msg.get_rcode(), rcode)
-        self.assertTrue(msg.get_header_flag(MessageFlag.AA()))
+        self.assertTrue(msg.get_header_flag(Message.HEADERFLAG_AA))
 
     def test_reply_query_with_format_error(self):
-         
+
         msg = self.getmsg()
         self.xfrsess._reply_query_with_format_error(msg, self.sock)
         get_msg = self.sock.read_msg()
@@ -140,12 +156,12 @@
         self.xfrsess._send_message_with_last_soa(msg, self.sock, rrset_soa, 0)
         get_msg = self.sock.read_msg()
 
-        self.assertEqual(get_msg.get_rr_count(Section.QUESTION()), 1)
-        self.assertEqual(get_msg.get_rr_count(Section.ANSWER()), 1)
-        self.assertEqual(get_msg.get_rr_count(Section.AUTHORITY()), 0)
+        self.assertEqual(get_msg.get_rr_count(Message.SECTION_QUESTION), 1)
+        self.assertEqual(get_msg.get_rr_count(Message.SECTION_ANSWER), 1)
+        self.assertEqual(get_msg.get_rr_count(Message.SECTION_AUTHORITY), 0)
 
         #answer_rrset_iter = section_iter(get_msg, section.ANSWER())
-        answer = get_msg.get_section(Section.ANSWER())[0]#answer_rrset_iter.get_rrset()
+        answer = get_msg.get_section(Message.SECTION_ANSWER)[0]#answer_rrset_iter.get_rrset()
         self.assertEqual(answer.get_name().to_text(), "example.com.")
         self.assertEqual(answer.get_class(), RRClass("IN"))
         self.assertEqual(answer.get_type().to_text(), "SOA")
@@ -160,7 +176,7 @@
         msg = self.getmsg()
         msg.make_response()
 
-        msg.add_rrset(Section.ANSWER(), rrset_a)
+        msg.add_rrset(Message.SECTION_ANSWER, rrset_a)
         # give the function a value that is larger than MAX-len(rrset)
         self.xfrsess._send_message_with_last_soa(msg, self.sock, rrset_soa, 65520)
 
@@ -168,11 +184,11 @@
         # (1 with the rrset we added manually, and 1 that triggered
         # the sending in _with_last_soa)
         get_msg = self.sock.read_msg()
-        self.assertEqual(get_msg.get_rr_count(Section.QUESTION()), 1)
-        self.assertEqual(get_msg.get_rr_count(Section.ANSWER()), 1)
-        self.assertEqual(get_msg.get_rr_count(Section.AUTHORITY()), 0)
-
-        answer = get_msg.get_section(Section.ANSWER())[0]
+        self.assertEqual(get_msg.get_rr_count(Message.SECTION_QUESTION), 1)
+        self.assertEqual(get_msg.get_rr_count(Message.SECTION_ANSWER), 1)
+        self.assertEqual(get_msg.get_rr_count(Message.SECTION_AUTHORITY), 0)
+
+        answer = get_msg.get_section(Message.SECTION_ANSWER)[0]
         self.assertEqual(answer.get_name().to_text(), "example.com.")
         self.assertEqual(answer.get_class(), RRClass("IN"))
         self.assertEqual(answer.get_type().to_text(), "A")
@@ -180,12 +196,12 @@
         self.assertEqual(rdata[0].to_text(), "192.0.2.1")
 
         get_msg = self.sock.read_msg()
-        self.assertEqual(get_msg.get_rr_count(Section.QUESTION()), 0)
-        self.assertEqual(get_msg.get_rr_count(Section.ANSWER()), 1)
-        self.assertEqual(get_msg.get_rr_count(Section.AUTHORITY()), 0)
-
-        #answer_rrset_iter = section_iter(get_msg, section.ANSWER())
-        answer = get_msg.get_section(Section.ANSWER())[0]
+        self.assertEqual(get_msg.get_rr_count(Message.SECTION_QUESTION), 0)
+        self.assertEqual(get_msg.get_rr_count(Message.SECTION_ANSWER), 1)
+        self.assertEqual(get_msg.get_rr_count(Message.SECTION_AUTHORITY), 0)
+
+        #answer_rrset_iter = section_iter(get_msg, Message.SECTION_ANSWER)
+        answer = get_msg.get_section(Message.SECTION_ANSWER)[0]
         self.assertEqual(answer.get_name().to_text(), "example.com.")
         self.assertEqual(answer.get_class(), RRClass("IN"))
         self.assertEqual(answer.get_type().to_text(), "SOA")
@@ -217,7 +233,7 @@
         sqlite3_ds.get_zone_soa = zone_soa
         self.assertEqual(self.xfrsess._zone_exist(True), True)
         self.assertEqual(self.xfrsess._zone_exist(False), False)
-    
+
     def test_check_xfrout_available(self):
         def zone_exist(zone):
             return zone
@@ -243,7 +259,7 @@
         self.xfrsess.dns_xfrout_start(self.sock, b"\xd6=\x00\x00\x00\x01\x00")
         sent_data = self.sock.readsent()
         self.assertEqual(len(sent_data), 0)
-    
+
     def default(self, param):
         return "example.com"
 
@@ -255,20 +271,20 @@
         self.xfrsess.dns_xfrout_start(self.sock, self.mdata)
         get_msg = self.sock.read_msg()
         self.assertEqual(get_msg.get_rcode().to_text(), "NOTAUTH")
-    
+
     def test_dns_xfrout_start_noerror(self):
         self.xfrsess._get_query_zone_name = self.default
         def noerror(form):
-            return Rcode.NOERROR() 
+            return Rcode.NOERROR()
         self.xfrsess._check_xfrout_available = noerror
-        
+
         def myreply(msg, sock, zonename):
             self.sock.send(b"success")
-        
+
         self.xfrsess._reply_xfrout_query = myreply
         self.xfrsess.dns_xfrout_start(self.sock, self.mdata)
         self.assertEqual(self.sock.readsent(), b"success")
-    
+
     def test_reply_xfrout_query_noerror(self):
         global sqlite3_ds
         def get_zone_soa(zonename, file):
@@ -281,7 +297,7 @@
         sqlite3_ds.get_zone_datas = get_zone_datas
         self.xfrsess._reply_xfrout_query(self.getmsg(), self.sock, "example.com.")
         reply_msg = self.sock.read_msg()
-        self.assertEqual(reply_msg.get_rr_count(Section.ANSWER()), 2)
+        self.assertEqual(reply_msg.get_rr_count(Message.SECTION_ANSWER), 2)
 
 class MyCCSession():
     def __init__(self):
@@ -292,7 +308,7 @@
             return "initdb.file", False
         else:
             return "unknown", False
-    
+
 
 class MyUnixSockServer(UnixSockServer):
     def __init__(self):
@@ -306,7 +322,7 @@
 class TestUnixSockServer(unittest.TestCase):
     def setUp(self):
         self.unix = MyUnixSockServer()
-     
+
     def test_updata_config_data(self):
         self.unix.update_config_data({'transfers_out':10 })
         self.assertEqual(self.unix._max_transfers_out, 10)
@@ -324,7 +340,7 @@
         count = self.unix._transfers_counter
         self.assertEqual(self.unix.increase_transfers_counter(), False)
         self.assertEqual(count, self.unix._transfers_counter)
- 
+
     def test_decrease_transfers_counter(self):
         count = self.unix._transfers_counter
         self.unix.decrease_transfers_counter()
@@ -335,7 +351,7 @@
             os.remove(sock_file)
         except OSError:
             pass
- 
+
     def test_sock_file_in_use_file_exist(self):
         sock_file = 'temp.sock.file'
         self._remove_file(sock_file)

Modified: branches/trac397focused/src/bin/xfrout/xfrout.py.in
==============================================================================
--- branches/trac397focused/src/bin/xfrout/xfrout.py.in (original)
+++ branches/trac397focused/src/bin/xfrout/xfrout.py.in Mon Dec 20 08:19:35 2010
@@ -30,12 +30,12 @@
 from isc.log.log import *
 from isc.cc import SessionError, SessionTimeout
 from isc.notify import notify_out
-import isc.utils.process
+import isc.util.process
 import socket
 import select
 import errno
 from optparse import OptionParser, OptionValueError
-from isc.utils import socketserver_mixin
+from isc.util import socketserver_mixin
 
 try:
     from libxfr_python import *
@@ -45,7 +45,7 @@
     # 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()
+isc.util.process.rename()
 
 if "B10_FROM_BUILD" in os.environ:
     SPECFILE_PATH = os.environ["B10_FROM_BUILD"] + "/src/bin/xfrout"
@@ -63,6 +63,7 @@
 MAX_TRANSFERS_OUT = 10
 VERBOSE_MODE = False
 
+
 XFROUT_MAX_MESSAGE_SIZE = 65535
 
 def get_rrset_len(rrset):
@@ -73,46 +74,78 @@
 
 
 class XfroutSession(BaseRequestHandler):
-    def __init__(self, request, client_address, server, log):
+    def __init__(self, request, client_address, server, log, sock):
         # The initializer for the superclass may call functions
         # that need _log to be set, so we set it first
         self._log = log
+        self._shutdown_sock = sock
         BaseRequestHandler.__init__(self, request, client_address, server)
 
     def handle(self):
-        fd = recv_fd(self.request.fileno())
-        
-        if fd < 0:
-            # This may happen when one xfrout process try to connect to
-            # xfrout unix socket server, to check whether there is another
-            # xfrout running. 
-            self._log.log_message("error", "Failed to receive the file descriptor for XFR connection")
-            return
-
-        data_len = self.request.recv(2)
+        '''Handle a request until shutdown or xfrout client is closed.'''
+        # check self.server._shutdown_event to ensure the real shutdown comes.
+        # Linux could trigger a spurious readable event on the _shutdown_sock 
+        # due to a bug, so we need perform a double check. 
+        while not self.server._shutdown_event.is_set(): # Check if xfrout is shutdown
+            try:
+                (rlist, wlist, xlist) = select.select([self._shutdown_sock, self.request], [], [])
+            except select.error as e:
+                if e.args[0] == errno.EINTR:
+                    (rlist, wlist, xlist) = ([], [], [])
+                    continue
+                else:
+                    self._log.log_message("error", "Error with select(): %s" %e)
+                    break
+            # self.server._shutdown_evnet will be set by now, if it is not a false
+            # alarm
+            if self._shutdown_sock in rlist:
+                continue
+
+            sock_fd = recv_fd(self.request.fileno())
+
+            if sock_fd < 0:
+                # This may happen when one xfrout process try to connect to
+                # xfrout unix socket server, to check whether there is another
+                # xfrout running.
+                if sock_fd == XFR_FD_RECEIVE_FAIL:
+                    self._log.log_message("error", "Failed to receive the file descriptor for XFR connection")
+                break
+
+            # receive query msg
+            msgdata = self._receive_query_message(self.request)
+            if not msgdata:
+                break
+
+            try:
+                self.dns_xfrout_start(sock_fd, msgdata)
+                #TODO, avoid catching all exceptions
+            except Exception as e:
+                self._log.log_message("error", str(e))
+
+            os.close(sock_fd)
+
+    def _receive_query_message(self, sock):
+        ''' receive query message from sock'''
+        # receive data length
+        data_len = sock.recv(2)
+        if not data_len:
+            return None
         msg_len = struct.unpack('!H', data_len)[0]
-        msgdata = self.request.recv(msg_len)
-        sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
-        try:
-            self.dns_xfrout_start(sock, msgdata)
-            #TODO, avoid catching all exceptions
-        except Exception as e:
-            self._log.log_message("error", str(e))
-
-        try:
-            sock.shutdown(socket.SHUT_RDWR)
-        except socket.error:
-            # Avoid socket error caused by shutting down 
-            # one non-connected socket.
-            pass
-
-        sock.close()
-        os.close(fd)
-        pass
+        # receive data
+        recv_size = 0
+        msgdata = b''
+        while recv_size < msg_len:
+            data = sock.recv(msg_len - recv_size)
+            if not data:
+                return None
+            recv_size += len(data)
+            msgdata += data
+
+        return msgdata
 
     def _parse_query_message(self, mdata):
         ''' parse query message to [socket,message]'''
-        #TODO, need to add parseHeader() in case the message header is invalid 
+        #TODO, need to add parseHeader() in case the message header is invalid
         try:
             msg = Message(Message.PARSE)
             Message.from_wire(msg, mdata)
@@ -127,37 +160,37 @@
         return question.get_name().to_text()
 
 
-    def _send_data(self, sock, data):
+    def _send_data(self, sock_fd, data):
         size = len(data)
         total_count = 0
         while total_count < size:
-            count = sock.send(data[total_count:])
+            count = os.write(sock_fd, data[total_count:])
             total_count += count
 
 
-    def _send_message(self, sock, msg):
+    def _send_message(self, sock_fd, msg):
         render = MessageRenderer()
         render.set_length_limit(XFROUT_MAX_MESSAGE_SIZE)
         msg.to_wire(render)
         header_len = struct.pack('H', socket.htons(render.get_length()))
-        self._send_data(sock, header_len)
-        self._send_data(sock, render.get_data())
-
-
-    def _reply_query_with_error_rcode(self, msg, sock, rcode_):
+        self._send_data(sock_fd, header_len)
+        self._send_data(sock_fd, render.get_data())
+
+
+    def _reply_query_with_error_rcode(self, msg, sock_fd, rcode_):
         msg.make_response()
         msg.set_rcode(rcode_)
-        self._send_message(sock, msg)
-
-
-    def _reply_query_with_format_error(self, msg, sock):
+        self._send_message(sock_fd, msg)
+
+
+    def _reply_query_with_format_error(self, msg, sock_fd):
         '''query message format isn't legal.'''
         if not msg:
-            return # query message is invalid. send nothing back. 
+            return # query message is invalid. send nothing back.
 
         msg.make_response()
         msg.set_rcode(Rcode.FORMERR())
-        self._send_message(sock, msg)
+        self._send_message(sock_fd, msg)
 
 
     def _zone_is_empty(self, zone):
@@ -167,24 +200,24 @@
         return True
 
     def _zone_exist(self, zonename):
-        # Find zone in datasource, should this works? maybe should ask 
+        # Find zone in datasource, should this works? maybe should ask
         # config manager.
         soa = sqlite3_ds.get_zone_soa(zonename, self.server.get_db_file())
         if soa:
             return True
         return False
 
-    
+
     def _check_xfrout_available(self, zone_name):
         '''Check if xfr request can be responsed.
            TODO, Get zone's configuration from cfgmgr or some other place
-           eg. check allow_transfer setting, 
+           eg. check allow_transfer setting,
         '''
         if not self._zone_exist(zone_name):
             return Rcode.NOTAUTH()
 
         if self._zone_is_empty(zone_name):
-            return Rcode.SERVFAIL() 
+            return Rcode.SERVFAIL()
 
         #TODO, check allow_transfer
         if not self.server.increase_transfers_counter():
@@ -193,45 +226,45 @@
         return Rcode.NOERROR()
 
 
-    def dns_xfrout_start(self, sock, msg_query):
+    def dns_xfrout_start(self, sock_fd, msg_query):
         rcode_, msg = self._parse_query_message(msg_query)
         #TODO. create query message and parse header
         if rcode_ != Rcode.NOERROR():
-            return self._reply_query_with_format_error(msg, sock)
+            return self._reply_query_with_format_error(msg, sock_fd)
 
         zone_name = self._get_query_zone_name(msg)
         rcode_ = self._check_xfrout_available(zone_name)
         if rcode_ != Rcode.NOERROR():
             self._log.log_message("info", "transfer of '%s/IN' failed: %s",
                                   zone_name, rcode_.to_text())
-            return self. _reply_query_with_error_rcode(msg, sock, rcode_)
+            return self. _reply_query_with_error_rcode(msg, sock_fd, rcode_)
 
         try:
             self._log.log_message("info", "transfer of '%s/IN': AXFR started" % zone_name)
-            self._reply_xfrout_query(msg, sock, zone_name)
+            self._reply_xfrout_query(msg, sock_fd, zone_name)
             self._log.log_message("info", "transfer of '%s/IN': AXFR end" % zone_name)
         except Exception as err:
             self._log.log_message("error", str(err))
 
         self.server.decrease_transfers_counter()
-        return    
+        return
 
 
     def _clear_message(self, msg):
         qid = msg.get_qid()
         opcode = msg.get_opcode()
         rcode = msg.get_rcode()
-        
+
         msg.clear(Message.RENDER)
         msg.set_qid(qid)
         msg.set_opcode(opcode)
         msg.set_rcode(rcode)
-        msg.set_header_flag(MessageFlag.AA())
-        msg.set_header_flag(MessageFlag.QR())
+        msg.set_header_flag(Message.HEADERFLAG_AA)
+        msg.set_header_flag(Message.HEADERFLAG_QR)
         return msg
 
     def _create_rrset_from_db_record(self, record):
-        '''Create one rrset from one record of datasource, if the schema of record is changed, 
+        '''Create one rrset from one record of datasource, if the schema of record is changed,
         This function should be updated first.
         '''
         rrtype_ = RRType(record[5])
@@ -239,30 +272,30 @@
         rrset_ = RRset(Name(record[2]), RRClass("IN"), rrtype_, RRTTL( int(record[4])))
         rrset_.add_rdata(rdata_)
         return rrset_
-         
-    def _send_message_with_last_soa(self, msg, sock, rrset_soa, message_upper_len):
+
+    def _send_message_with_last_soa(self, msg, sock_fd, rrset_soa, message_upper_len):
         '''Add the SOA record to the end of message. If it can't be
         added, a new message should be created to send out the last soa .
         '''
         rrset_len = get_rrset_len(rrset_soa)
 
         if message_upper_len + rrset_len < XFROUT_MAX_MESSAGE_SIZE:
-            msg.add_rrset(Section.ANSWER(), rrset_soa)
+            msg.add_rrset(Message.SECTION_ANSWER, rrset_soa)
         else:
-            self._send_message(sock, msg)
+            self._send_message(sock_fd, msg)
             msg = self._clear_message(msg)
-            msg.add_rrset(Section.ANSWER(), rrset_soa)
-
-        self._send_message(sock, msg)
-
-
-    def _reply_xfrout_query(self, msg, sock, zone_name):
+            msg.add_rrset(Message.SECTION_ANSWER, rrset_soa)
+
+        self._send_message(sock_fd, msg)
+
+
+    def _reply_xfrout_query(self, msg, sock_fd, zone_name):
         #TODO, there should be a better way to insert rrset.
         msg.make_response()
-        msg.set_header_flag(MessageFlag.AA())
+        msg.set_header_flag(Message.HEADERFLAG_AA)
         soa_record = sqlite3_ds.get_zone_soa(zone_name, self.server.get_db_file())
         rrset_soa = self._create_rrset_from_db_record(soa_record)
-        msg.add_rrset(Section.ANSWER(), rrset_soa)
+        msg.add_rrset(Message.SECTION_ANSWER, rrset_soa)
 
         message_upper_len = get_rrset_len(rrset_soa)
 
@@ -282,16 +315,16 @@
             # may have reached the limit
             rrset_len = get_rrset_len(rrset_)
             if message_upper_len + rrset_len < XFROUT_MAX_MESSAGE_SIZE:
-                msg.add_rrset(Section.ANSWER(), rrset_)
+                msg.add_rrset(Message.SECTION_ANSWER, rrset_)
                 message_upper_len += rrset_len
                 continue
 
-            self._send_message(sock, msg)
+            self._send_message(sock_fd, msg)
             msg = self._clear_message(msg)
-            msg.add_rrset(Section.ANSWER(), rrset_) # Add the rrset to the new message
+            msg.add_rrset(Message.SECTION_ANSWER, rrset_) # Add the rrset to the new message
             message_upper_len = rrset_len
 
-        self._send_message_with_last_soa(msg, sock, rrset_soa, message_upper_len)
+        self._send_message_with_last_soa(msg, sock_fd, rrset_soa, message_upper_len)
 
 class UnixSockServer(socketserver_mixin.NoPollMixIn, ThreadingUnixStreamServer):
     '''The unix domain socket server which accept xfr query sent from auth server.'''
@@ -304,22 +337,23 @@
         self._lock = threading.Lock()
         self._transfers_counter = 0
         self._shutdown_event = shutdown_event
+        self._write_sock, self._read_sock = socket.socketpair()
         self._log = log
         self.update_config_data(config_data)
         self._cc = cc
-        
+
     def finish_request(self, request, client_address):
         '''Finish one request by instantiating RequestHandlerClass.'''
-        self.RequestHandlerClass(request, client_address, self, self._log)
+        self.RequestHandlerClass(request, client_address, self, self._log, self._read_sock)
 
     def _remove_unused_sock_file(self, sock_file):
-        '''Try to remove the socket file. If the file is being used 
-        by one running xfrout process, exit from python. 
+        '''Try to remove the socket file. If the file is being used
+        by one running xfrout process, exit from python.
         If it's not a socket file or nobody is listening
         , it will be removed. If it can't be removed, exit from python. '''
         if self._sock_file_in_use(sock_file):
-            sys.stderr.write("[b10-xfrout] Fail to start xfrout process, unix socket" 
-                  " file '%s' is being used by another xfrout process\n" % sock_file)
+            self._log.log_message("error", "Fail to start xfrout process, unix socket file '%s'"
+                                 " is being used by another xfrout process\n" % sock_file)
             sys.exit(0)
         else:
             if not os.path.exists(sock_file):
@@ -328,12 +362,12 @@
             try:
                 os.unlink(sock_file)
             except OSError as err:
-                sys.stderr.write('[b10-xfrout] Fail to remove file %s: %s\n' % (sock_file, err))
+                self._log.log_message("error", '[b10-xfrout] Fail to remove file %s: %s\n' % (sock_file, err))
                 sys.exit(0)
-   
+
     def _sock_file_in_use(self, sock_file):
-        '''Check whether the socket file 'sock_file' exists and 
-        is being used by one running xfrout process. If it is, 
+        '''Check whether the socket file 'sock_file' exists and
+        is being used by one running xfrout process. If it is,
         return True, or else return False. '''
         try:
             sock = socket.socket(socket.AF_UNIX)
@@ -341,9 +375,10 @@
         except socket.error as err:
             return False
         else:
-            return True 
+            return True
 
     def shutdown(self):
+        self._write_sock.send(b"shutdown") #terminate the xfrout session thread
         super().shutdown() # call the shutdown() of class socketserver_mixin.NoPollMixIn
         try:
             os.unlink(self._sock_file)
@@ -390,7 +425,7 @@
     def __init__(self):
         self._unix_socket_server = None
         self._log = None
-        self._listen_sock_file = UNIX_SOCKET_FILE 
+        self._listen_sock_file = UNIX_SOCKET_FILE
         self._shutdown_event = threading.Event()
         self._cc = isc.config.ModuleCCSession(SPECFILE_LOCATION, self.config_handler, self.command_handler)
         self._config_data = self._cc.get_full_config()
@@ -404,12 +439,12 @@
 
     def _start_xfr_query_listener(self):
         '''Start a new thread to accept xfr query. '''
-        self._unix_socket_server = UnixSockServer(self._listen_sock_file, XfroutSession, 
+        self._unix_socket_server = UnixSockServer(self._listen_sock_file, XfroutSession,
                                                   self._shutdown_event, self._config_data,
                                                   self._cc, self._log);
         listener = threading.Thread(target=self._unix_socket_server.serve_forever)
         listener.start()
-        
+
     def _start_notifier(self):
         datasrc = self._unix_socket_server.get_db_file()
         self._notifier = notify_out.NotifyOut(datasrc, self._log)
@@ -472,7 +507,7 @@
             else:
                 answer = create_answer(1, "Bad command parameter:" + str(args))
 
-        else: 
+        else:
             answer = create_answer(1, "Unknown command:" + str(cmd))
 
         return answer
@@ -514,7 +549,7 @@
         sys.stderr.write("[b10-xfrout] Error creating xfrout, "
                            "is the command channel daemon running?\n")
     except SessionTimeout as e:
-        sys.stderr.write("[b10-xfrout] Error creating xfrout, " 
+        sys.stderr.write("[b10-xfrout] Error creating xfrout, "
                            "is the configuration manager running?\n")
     except ModuleCCSessionError as e:
         sys.stderr.write("[b10-xfrout] exit xfrout process:%s\n" % str(e))

Modified: branches/trac397focused/src/bin/xfrout/xfrout.spec.pre.in
==============================================================================
--- branches/trac397focused/src/bin/xfrout/xfrout.spec.pre.in (original)
+++ branches/trac397focused/src/bin/xfrout/xfrout.spec.pre.in Mon Dec 20 08:19:35 2010
@@ -7,12 +7,6 @@
          "item_type": "integer",
          "item_optional": false,
          "item_default": 10
-       },
-       {
-         "item_name": "db_file",
-         "item_type": "string",
-         "item_optional": false,
-         "item_default": "@@LOCALSTATEDIR@@/@PACKAGE@/zone.sqlite3"
        },
        {
          "item_name": "log_name",

Modified: branches/trac397focused/src/bin/zonemgr/zonemgr.py.in
==============================================================================
--- branches/trac397focused/src/bin/zonemgr/zonemgr.py.in (original)
+++ branches/trac397focused/src/bin/zonemgr/zonemgr.py.in Mon Dec 20 08:19:35 2010
@@ -37,9 +37,9 @@
 from isc.datasrc import sqlite3_ds
 from optparse import OptionParser, OptionValueError
 from isc.config.ccsession import *
-import isc.utils.process
-
-isc.utils.process.rename()
+import isc.util.process
+
+isc.util.process.rename()
 
 # If B10_FROM_BUILD is set in the environment, we use data files
 # from a directory relative to that, otherwise we use the ones
@@ -90,26 +90,26 @@
 
 class ZonemgrRefresh:
     """This class will maintain and manage zone refresh info.
-    It also provides methods to keep track of zone timers and 
-    do zone refresh. 
-    Zone timers can be started by calling run_timer(), and it 
+    It also provides methods to keep track of zone timers and
+    do zone refresh.
+    Zone timers can be started by calling run_timer(), and it
     can be stopped by calling shutdown() in another thread.
 
     """
 
     def __init__(self, cc, db_file, slave_socket, config_data):
         self._cc = cc
-        self._check_sock = slave_socket 
+        self._check_sock = slave_socket
         self._db_file = db_file
         self.update_config_data(config_data)
-        self._zonemgr_refresh_info = {} 
+        self._zonemgr_refresh_info = {}
         self._build_zonemgr_refresh_info()
         self._running = False
-    
+
     def _random_jitter(self, max, jitter):
         """Imposes some random jitters for refresh and
         retry timers to avoid many zones need to do refresh
-        at the same time. 
+        at the same time.
         The value should be between (max - jitter) and max.
         """
         if 0 == jitter:
@@ -120,7 +120,7 @@
         return time.time()
 
     def _set_zone_timer(self, zone_name_class, max, jitter):
-        """Set zone next refresh time. 
+        """Set zone next refresh time.
         jitter should not be bigger than half the original value."""
         self._set_zone_next_refresh_time(zone_name_class, self._get_current_time() + \
                                             self._random_jitter(max, jitter))
@@ -143,7 +143,7 @@
 
     def _set_zone_notify_timer(self, zone_name_class):
         """Set zone next refresh time after receiving notify
-           next_refresh_time = now 
+           next_refresh_time = now
         """
         self._set_zone_timer(zone_name_class, 0, 0)
 
@@ -199,7 +199,7 @@
             raise ZonemgrException("[b10-zonemgr] zone (%s, %s) doesn't have soa." % zone_name_class)
         zone_info["zone_soa_rdata"] = zone_soa[7]
         zone_info["zone_state"] = ZONE_OK
-        zone_info["last_refresh_time"] = self._get_current_time() 
+        zone_info["last_refresh_time"] = self._get_current_time()
         zone_info["next_refresh_time"] = self._get_current_time() + \
                                          float(zone_soa[7].split(" ")[REFRESH_OFFSET])
         self._zonemgr_refresh_info[zone_name_class] = zone_info
@@ -233,7 +233,7 @@
 
     def _get_zone_notifier_master(self, zone_name_class):
         if ("notify_master" in self._zonemgr_refresh_info[zone_name_class].keys()):
-            return self._zonemgr_refresh_info[zone_name_class]["notify_master"] 
+            return self._zonemgr_refresh_info[zone_name_class]["notify_master"]
 
         return None
 
@@ -248,7 +248,7 @@
         return self._zonemgr_refresh_info[zone_name_class]["zone_state"]
 
     def _set_zone_state(self, zone_name_class, zone_state):
-        self._zonemgr_refresh_info[zone_name_class]["zone_state"] = zone_state 
+        self._zonemgr_refresh_info[zone_name_class]["zone_state"] = zone_state
 
     def _get_zone_refresh_timeout(self, zone_name_class):
         return self._zonemgr_refresh_info[zone_name_class]["refresh_timeout"]
@@ -268,7 +268,7 @@
         try:
             self._cc.group_sendmsg(msg, module_name)
         except socket.error:
-            sys.stderr.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
@@ -281,10 +281,10 @@
             if (ZONE_REFRESHING == zone_state and
                 (self._get_zone_refresh_timeout(zone_name_class) > self._get_current_time())):
                 continue
-                    
-            # Get the zone with minimum next_refresh_time 
-            if ((zone_need_refresh is None) or 
-                (self._get_zone_next_refresh_time(zone_name_class) < 
+
+            # Get the zone with minimum next_refresh_time
+            if ((zone_need_refresh is None) or
+                (self._get_zone_next_refresh_time(zone_name_class) <
                  self._get_zone_next_refresh_time(zone_need_refresh))):
                 zone_need_refresh = zone_name_class
 
@@ -292,14 +292,14 @@
             if (self._get_zone_next_refresh_time(zone_need_refresh) < self._get_current_time()):
                 break
 
-        return zone_need_refresh 
-
-    
+        return zone_need_refresh
+
+
     def _do_refresh(self, zone_name_class):
         """Do zone refresh."""
         log_msg("Do refresh for zone (%s, %s)." % zone_name_class)
         self._set_zone_state(zone_name_class, ZONE_REFRESHING)
-        self._set_zone_refresh_timeout(zone_name_class, self._get_current_time() + self._max_transfer_timeout) 
+        self._set_zone_refresh_timeout(zone_name_class, self._get_current_time() + self._max_transfer_timeout)
         notify_master = self._get_zone_notifier_master(zone_name_class)
         # If the zone has notify master, send notify command to xfrin module
         if notify_master:
@@ -307,7 +307,7 @@
                      "zone_class" : zone_name_class[1],
                      "master" : notify_master
                      }
-            self._send_command(XFRIN_MODULE_NAME, ZONE_NOTIFY_COMMAND, param) 
+            self._send_command(XFRIN_MODULE_NAME, ZONE_NOTIFY_COMMAND, param)
             self._clear_zone_notifier_master(zone_name_class)
         # Send refresh command to xfrin module
         else:
@@ -324,23 +324,29 @@
         return False
 
     def _run_timer(self, start_event):
-        start_event.set()
         while self._running:
+            # Notify run_timer that we already started and are inside the loop.
+            # It is set only once, but when it was outside the loop, there was
+            # a race condition and _running could be set to false before we
+            # could enter it
+            if start_event:
+                start_event.set()
+                start_event = None
             # If zonemgr has no zone, set timer timeout to self._lowerbound_retry.
             if self._zone_mgr_is_empty():
-                timeout = self._lowerbound_retry 
+                timeout = self._lowerbound_retry
             else:
                 zone_need_refresh = self._find_need_do_refresh_zone()
-                # If don't get zone with minimum next refresh time, set timer timeout to self._lowerbound_retry 
+                # If don't get zone with minimum next refresh time, set timer timeout to self._lowerbound_retry.
                 if not zone_need_refresh:
-                    timeout = self._lowerbound_retry 
+                    timeout = self._lowerbound_retry
                 else:
                     timeout = self._get_zone_next_refresh_time(zone_need_refresh) - self._get_current_time()
                     if (timeout < 0):
                         self._do_refresh(zone_need_refresh)
                         continue
 
-            """ Wait for the socket notification for a maximum time of timeout 
+            """ Wait for the socket notification for a maximum time of timeout
             in seconds (as float)."""
             try:
                 rlist, wlist, xlist = select.select([self._check_sock, self._read_sock], [], [], timeout)
@@ -352,9 +358,10 @@
                     break
 
             for fd in rlist:
-                if fd == self._read_sock: # awaken by shutdown socket 
+                if fd == self._read_sock: # awaken by shutdown socket
                     # self._running will be False by now, if it is not a false
-                    # alarm
+                    # alarm (linux kernel is said to trigger spurious wakeup
+                    # on a filehandle that is not really readable).
                     continue
                 if fd == self._check_sock: # awaken by check socket
                     self._check_sock.recv(32)
@@ -416,7 +423,7 @@
         self._zone_refresh = None
         self._setup_session()
         self._db_file = self.get_db_file()
-        # Create socket pair for communicating between main thread and zonemgr timer thread 
+        # Create socket pair for communicating between main thread and zonemgr timer thread
         self._master_socket, self._slave_socket = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM)
         self._zone_refresh = ZonemgrRefresh(self._cc, self._db_file, self._slave_socket, self._config_data)
         self._zone_refresh.run_timer()
@@ -426,7 +433,7 @@
         self.running = False
 
     def _setup_session(self):
-        """Setup two sessions for zonemgr, one(self._module_cc) is used for receiving 
+        """Setup two sessions for zonemgr, one(self._module_cc) is used for receiving
         commands and config data sent from other modules, another one (self._cc)
         is used to send commands to proper modules."""
         self._cc = isc.cc.Session()
@@ -450,7 +457,7 @@
     def shutdown(self):
         """Shutdown the zonemgr process. the thread which is keeping track of zone
         timers should be terminated.
-        """ 
+        """
         self._zone_refresh.shutdown()
 
         self._slave_socket.close()
@@ -503,7 +510,7 @@
 
     def command_handler(self, command, args):
         """Handle command receivd from command channel.
-        ZONE_NOTIFY_COMMAND is issued by Auth process; ZONE_XFRIN_SUCCESS_COMMAND 
+        ZONE_NOTIFY_COMMAND is issued by Auth process; ZONE_XFRIN_SUCCESS_COMMAND
         and ZONE_XFRIN_FAILED_COMMAND are issued by Xfrin process; shutdown is issued
         by a user or Boss process. """
         answer = create_answer(0)
@@ -572,10 +579,10 @@
     except KeyboardInterrupt:
         sys.stderr.write("[b10-zonemgr] exit zonemgr process\n")
     except isc.cc.session.SessionError as e:
-        sys.stderr.write("[b10-zonemgr] Error creating zonemgr, " 
+        sys.stderr.write("[b10-zonemgr] Error creating zonemgr, "
                            "is the command channel daemon running?\n")
     except isc.cc.session.SessionTimeout as e:
-        sys.stderr.write("[b10-zonemgr] Error creating zonemgr, " 
+        sys.stderr.write("[b10-zonemgr] Error creating zonemgr, "
                            "is the configuration manager running?\n")
     except isc.config.ModuleCCSessionError as e:
         sys.stderr.write("[b10-zonemgr] exit zonemgr process: %s\n" % str(e))

Modified: branches/trac397focused/src/lib/Makefile.am
==============================================================================
--- branches/trac397focused/src/lib/Makefile.am (original)
+++ branches/trac397focused/src/lib/Makefile.am Mon Dec 20 08:19:35 2010
@@ -1,1 +1,1 @@
-SUBDIRS = exceptions dns cc config datasrc python xfr bench
+SUBDIRS = exceptions dns cc config datasrc python xfr bench nsas

Modified: branches/trac397focused/src/lib/bench/Makefile.am
==============================================================================
--- branches/trac397focused/src/lib/bench/Makefile.am (original)
+++ branches/trac397focused/src/lib/bench/Makefile.am Mon Dec 20 08:19:35 2010
@@ -1,6 +1,7 @@
 SUBDIRS = . tests example
 
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
 AM_CXXFLAGS = $(B10_CXXFLAGS)
 
 CLEANFILES = *.gcno *.gcda

Modified: branches/trac397focused/src/lib/bench/benchmark.h
==============================================================================
--- branches/trac397focused/src/lib/bench/benchmark.h (original)
+++ branches/trac397focused/src/lib/bench/benchmark.h Mon Dec 20 08:19:35 2010
@@ -200,7 +200,7 @@
     BenchMark(const BenchMark& source);
     BenchMark& operator=(const BenchMark& source);
 public:
-    /// \bench Constructor for immediate run.
+    /// \brief Constructor for immediate run.
     ///
     /// This is the constructor that is expected to be used normally.
     /// It runs the benchmark within the constructor and prints the result,
@@ -217,7 +217,7 @@
         initialize(true);
     }
 
-    /// \bench Constructor for finer-grained control.
+    /// \brief Constructor for finer-grained control.
     ///
     /// This constructor takes the third parameter, \c immediate, to control
     /// whether to run the benchmark within the constructor.

Modified: branches/trac397focused/src/lib/bench/example/search_bench.cc
==============================================================================
--- branches/trac397focused/src/lib/bench/example/search_bench.cc (original)
+++ branches/trac397focused/src/lib/bench/example/search_bench.cc Mon Dec 20 08:19:35 2010
@@ -16,6 +16,7 @@
 
 #include <unistd.h>             // for getpid
 
+#include <cassert>
 #include <cstdlib>              // for rand
 #include <algorithm>
 #include <iostream>
@@ -42,9 +43,11 @@
         vector<int>::const_iterator end_key = keys_.end();
         for (iter = keys_.begin(); iter != end_key; ++iter) {
             if (Sorted) {
-                binary_search(data_.begin(), data_.end(), *iter);
+                // perform simple sanity check with assert() to ensure
+                // compiler optimization won't skip the search.
+                assert(binary_search(data_.begin(), data_.end(), *iter));
             } else {
-                find(data_.begin(), data_.end(), *iter);
+                assert(find(data_.begin(), data_.end(), *iter) != data_.end());
             }
         }
         return (keys_.size());
@@ -63,7 +66,7 @@
         vector<int>::const_iterator iter;
         vector<int>::const_iterator end_key = keys_.end();
         for (iter = keys_.begin(); iter != end_key; ++iter) {
-            data_.find(*iter);
+            assert(data_.find(*iter) != data_.end());
         }        
         return (keys_.size());
     }

Modified: branches/trac397focused/src/lib/bench/tests/Makefile.am
==============================================================================
--- branches/trac397focused/src/lib/bench/tests/Makefile.am (original)
+++ branches/trac397focused/src/lib/bench/tests/Makefile.am Mon Dec 20 08:19:35 2010
@@ -1,4 +1,5 @@
 AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
 AM_CPPFLAGS += -DTEST_DATA_DIR=\"$(srcdir)/testdata\"
 AM_CXXFLAGS = $(B10_CXXFLAGS)
 

Modified: branches/trac397focused/src/lib/bench/tests/loadquery_unittest.cc
==============================================================================
--- branches/trac397focused/src/lib/bench/tests/loadquery_unittest.cc (original)
+++ branches/trac397focused/src/lib/bench/tests/loadquery_unittest.cc Mon Dec 20 08:19:35 2010
@@ -82,12 +82,12 @@
         EXPECT_EQ(0, message.getQid());
         EXPECT_EQ(Opcode::QUERY(), message.getOpcode());
         EXPECT_EQ(Rcode::NOERROR(), message.getRcode());
-        EXPECT_FALSE(message.getHeaderFlag(MessageFlag::QR()));
-        EXPECT_FALSE(message.getHeaderFlag(MessageFlag::AA()));
-        EXPECT_EQ(1, message.getRRCount(Section::QUESTION()));
-        EXPECT_EQ(0, message.getRRCount(Section::ANSWER()));
-        EXPECT_EQ(0, message.getRRCount(Section::AUTHORITY()));
-        EXPECT_EQ(0, message.getRRCount(Section::ADDITIONAL()));
+        EXPECT_FALSE(message.getHeaderFlag(Message::HEADERFLAG_QR));
+        EXPECT_FALSE(message.getHeaderFlag(Message::HEADERFLAG_AA));
+        EXPECT_EQ(1, message.getRRCount(Message::SECTION_QUESTION));
+        EXPECT_EQ(0, message.getRRCount(Message::SECTION_ANSWER));
+        EXPECT_EQ(0, message.getRRCount(Message::SECTION_AUTHORITY));
+        EXPECT_EQ(0, message.getRRCount(Message::SECTION_ADDITIONAL));
 
         // Check if the question matches our original data, if the expected
         // data is given.

Modified: branches/trac397focused/src/lib/cc/Makefile.am
==============================================================================
--- branches/trac397focused/src/lib/cc/Makefile.am (original)
+++ branches/trac397focused/src/lib/cc/Makefile.am Mon Dec 20 08:19:35 2010
@@ -1,15 +1,22 @@
 SUBDIRS = . tests
 
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
 AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
 
 AM_CXXFLAGS = $(B10_CXXFLAGS)
-# ASIO header files used in session.cc will trigger "unused-parameter"
-# error.  Unfortunately there doesn't seem to be an easy way to selectively
+if USE_GXX
+# ASIO header files used in session.cc will trigger the "unused-parameter"
+# warning.  Unfortunately there doesn't seem to be an easy way to selectively
 # avoid the error.  As a short term workaround we suppress this warning
 # for the entire this module.  See also src/bin/auth/Makefile.am.
-if USE_GXX
 AM_CXXFLAGS += -Wno-unused-parameter
+endif
+if USE_CLANGPP
+# Likewise, ASIO header files will trigger various warnings with clang++.
+# Worse, there doesn't seem to be any option to disable one of the warnings
+# in any way, so we need to turn off -Werror.
+AM_CXXFLAGS += -Wno-error
 endif
 
 lib_LTLIBRARIES = libcc.la

Modified: branches/trac397focused/src/lib/cc/data.cc
==============================================================================
--- branches/trac397focused/src/lib/cc/data.cc (original)
+++ branches/trac397focused/src/lib/cc/data.cc Mon Dec 20 08:19:35 2010
@@ -62,84 +62,82 @@
 // installed files we define the methods here.
 //
 bool
-Element::getValue(long int& t UNUSED_PARAM) {
-    return (false);
-}
-
-bool
-Element::getValue(double& t UNUSED_PARAM) {
-    return (false);
-}
-
-bool
-Element::getValue(bool& t UNUSED_PARAM) {
-    return (false);
-}
-
-bool
-Element::getValue(std::string& t UNUSED_PARAM) {
-    return (false);
-}
-
-bool
-Element::getValue(std::vector<ConstElementPtr>& t UNUSED_PARAM) {
-    return (false);
-}
-
-bool
-Element::getValue(std::map<std::string, ConstElementPtr>& t UNUSED_PARAM) {
-    return (false);
-}
-
-bool
-Element::setValue(const long int v UNUSED_PARAM) {
-    return (false);
-}
-
-bool
-Element::setValue(const double v UNUSED_PARAM) {
-    return (false);
-}
-
-bool
-Element::setValue(const bool t UNUSED_PARAM) {
-    return (false);
-}
-
-bool
-Element::setValue(const std::string& v UNUSED_PARAM) {
-    return (false);
-}
-
-bool
-Element::setValue(const std::vector<ConstElementPtr>& v UNUSED_PARAM) {
-    return (false);
-}
-
-bool
-Element::setValue(const std::map<std::string,
-                  ConstElementPtr>& v UNUSED_PARAM)
-{
+Element::getValue(long int&) {
+    return (false);
+}
+
+bool
+Element::getValue(double&) {
+    return (false);
+}
+
+bool
+Element::getValue(bool&) {
+    return (false);
+}
+
+bool
+Element::getValue(std::string&) {
+    return (false);
+}
+
+bool
+Element::getValue(std::vector<ConstElementPtr>&) {
+    return (false);
+}
+
+bool
+Element::getValue(std::map<std::string, ConstElementPtr>&) {
+    return (false);
+}
+
+bool
+Element::setValue(const long int) {
+    return (false);
+}
+
+bool
+Element::setValue(const double) {
+    return (false);
+}
+
+bool
+Element::setValue(const bool) {
+    return (false);
+}
+
+bool
+Element::setValue(const std::string&) {
+    return (false);
+}
+
+bool
+Element::setValue(const std::vector<ConstElementPtr>&) {
+    return (false);
+}
+
+bool
+Element::setValue(const std::map<std::string, ConstElementPtr>&) {
     return (false);
 }
 
 ConstElementPtr
-Element::get(const int i UNUSED_PARAM) const {
+Element::get(const int) const {
     isc_throw(TypeError, "get(int) called on a non-list Element");
 }
 
 void
-Element::set(const size_t i UNUSED_PARAM, ConstElementPtr element UNUSED_PARAM) {
+Element::set(const size_t, ConstElementPtr) {
     isc_throw(TypeError, "set(int, element) called on a non-list Element");
 }
 
 void
-Element::add(ConstElementPtr element UNUSED_PARAM) {
+Element::add(ConstElementPtr) {
     isc_throw(TypeError, "add() called on a non-list Element");
 }
 
 void
-Element::remove(const int i UNUSED_PARAM) {
+Element::remove(const int) {
     isc_throw(TypeError, "remove(int) called on a non-list Element");
 }
 
@@ -149,36 +147,32 @@
 }
 
 ConstElementPtr
-Element::get(const std::string& name UNUSED_PARAM) const {
+Element::get(const std::string&) const {
     isc_throw(TypeError, "get(string) called on a non-map Element");
 }
 
 void
-Element::set(const std::string& name UNUSED_PARAM,
-             ConstElementPtr element UNUSED_PARAM)
-{
+Element::set(const std::string&, ConstElementPtr) {
     isc_throw(TypeError, "set(name, element) called on a non-map Element");
 }
 
 void
-Element::remove(const std::string& name UNUSED_PARAM) {
+Element::remove(const std::string&) {
     isc_throw(TypeError, "remove(string) called on a non-map Element");
 }
 
 bool
-Element::contains(const std::string& name UNUSED_PARAM) const {
+Element::contains(const std::string&) const {
     isc_throw(TypeError, "contains(string) called on a non-map Element");
 }
 
 ConstElementPtr
-Element::find(const std::string& identifier UNUSED_PARAM) const {
+Element::find(const std::string&) const {
     isc_throw(TypeError, "find(string) called on a non-map Element");
 }
 
 bool
-Element::find(const std::string& identifier UNUSED_PARAM,
-              ConstElementPtr t UNUSED_PARAM) const
-{
+Element::find(const std::string&, ConstElementPtr) const {
     return (false);
 }
 
@@ -725,7 +719,7 @@
 }
 
 ElementPtr
-Element::fromWire(std::stringstream& in, int length) {
+Element::fromWire(std::stringstream& in, int) {
     //
     // Check protocol version
     //

Modified: branches/trac397focused/src/lib/cc/tests/Makefile.am
==============================================================================
--- branches/trac397focused/src/lib/cc/tests/Makefile.am (original)
+++ branches/trac397focused/src/lib/cc/tests/Makefile.am Mon Dec 20 08:19:35 2010
@@ -1,9 +1,13 @@
 AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
 AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
 
 AM_CXXFLAGS = $(B10_CXXFLAGS)
 if USE_GXX			#XXX: see ../Makefile.am
 AM_CXXFLAGS += -Wno-unused-parameter
+endif
+if USE_CLANGPP
+AM_CXXFLAGS += -Wno-error
 endif
 
 if USE_STATIC_LINK

Modified: branches/trac397focused/src/lib/cc/tests/data_unittests.cc
==============================================================================
--- branches/trac397focused/src/lib/cc/tests/data_unittests.cc (original)
+++ branches/trac397focused/src/lib/cc/tests/data_unittests.cc Mon Dec 20 08:19:35 2010
@@ -247,7 +247,7 @@
     EXPECT_EQ(b, true);
     b = false;
     EXPECT_TRUE(el->setValue(b));
-    EXPECT_EQ(false, el->boolValue());
+    EXPECT_FALSE(el->boolValue());
 
     el = Element::create("foo");
     EXPECT_THROW(el->intValue(), TypeError);

Modified: branches/trac397focused/src/lib/cc/tests/session_unittests.cc
==============================================================================
--- branches/trac397focused/src/lib/cc/tests/session_unittests.cc (original)
+++ branches/trac397focused/src/lib/cc/tests/session_unittests.cc Mon Dec 20 08:19:35 2010
@@ -76,7 +76,7 @@
     }
 
     void
-    acceptHandler(const asio::error_code& error UNUSED_PARAM) {
+    acceptHandler(const asio::error_code&) {
     }
 
     void

Modified: branches/trac397focused/src/lib/config/Makefile.am
==============================================================================
--- branches/trac397focused/src/lib/config/Makefile.am (original)
+++ branches/trac397focused/src/lib/config/Makefile.am Mon Dec 20 08:19:35 2010
@@ -2,6 +2,7 @@
 
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += -I$(top_builddir)/src/lib/cc
+AM_CPPFLAGS += $(BOOST_INCLUDES)
 AM_CXXFLAGS = $(B10_CXXFLAGS) -Wno-strict-aliasing
 
 lib_LTLIBRARIES = libcfgclient.la

Modified: branches/trac397focused/src/lib/config/config_data.cc
==============================================================================
--- branches/trac397focused/src/lib/config/config_data.cc (original)
+++ branches/trac397focused/src/lib/config/config_data.cc Mon Dec 20 08:19:35 2010
@@ -128,11 +128,6 @@
                 if (recurse && list_el->get("item_type")->stringValue() == "map") {
                     spec_name_list(result, list_el->get("map_item_spec"), new_prefix, recurse);
                 } else {
-                    if (list_el->get("item_type")->stringValue() == "map" ||
-                        list_el->get("item_type")->stringValue() == "list"
-                    ) {
-                        new_prefix += "/";
-                    }
                     result->add(Element::create(new_prefix));
                 }
             }

Modified: branches/trac397focused/src/lib/config/tests/Makefile.am
==============================================================================
--- branches/trac397focused/src/lib/config/tests/Makefile.am (original)
+++ branches/trac397focused/src/lib/config/tests/Makefile.am Mon Dec 20 08:19:35 2010
@@ -1,12 +1,9 @@
 SUBDIRS = testdata .
 
 AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
 
 AM_CXXFLAGS = $(B10_CXXFLAGS)
-# see src/lib/cc/Makefile.am for -Wno-unused-parameter
-if USE_GXX
-AM_CXXFLAGS += -Wno-unused-parameter
-endif
 
 if USE_STATIC_LINK
 AM_LDFLAGS = -static
@@ -25,8 +22,8 @@
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
 run_unittests_LDADD =  $(GTEST_LDADD)
+run_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.la
 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
 

Modified: branches/trac397focused/src/lib/config/tests/ccsession_unittests.cc
==============================================================================
--- branches/trac397focused/src/lib/config/tests/ccsession_unittests.cc (original)
+++ branches/trac397focused/src/lib/config/tests/ccsession_unittests.cc Mon Dec 20 08:19:35 2010
@@ -150,9 +150,9 @@
 }
 
 TEST_F(CCSessionTest, session1) {
-    EXPECT_EQ(false, session.haveSubscription("Spec1", "*"));
+    EXPECT_FALSE(session.haveSubscription("Spec1", "*"));
     ModuleCCSession mccs(ccspecfile("spec1.spec"), session, NULL, NULL);
-    EXPECT_EQ(true, session.haveSubscription("Spec1", "*"));
+    EXPECT_TRUE(session.haveSubscription("Spec1", "*"));
 
     EXPECT_EQ(1, session.getMsgQueue()->size());
     ConstElementPtr msg;
@@ -165,9 +165,9 @@
 }
 
 TEST_F(CCSessionTest, session2) {
-    EXPECT_EQ(false, session.haveSubscription("Spec2", "*"));
+    EXPECT_FALSE(session.haveSubscription("Spec2", "*"));
     ModuleCCSession mccs(ccspecfile("spec2.spec"), session, NULL, NULL);
-    EXPECT_EQ(true, session.haveSubscription("Spec2", "*"));
+    EXPECT_TRUE(session.haveSubscription("Spec2", "*"));
 
     EXPECT_EQ(1, session.getMsgQueue()->size());
     ConstElementPtr msg;
@@ -188,7 +188,7 @@
 }
 
 ConstElementPtr my_command_handler(const std::string& command,
-                                   ConstElementPtr arg UNUSED_PARAM)
+                                   ConstElementPtr arg)
 {
     if (command == "good_command") {
         return (createAnswer());
@@ -211,10 +211,10 @@
     // client will ask for config
     session.getMessages()->add(createAnswer(0, el("{}")));
 
-    EXPECT_EQ(false, session.haveSubscription("Spec2", "*"));
+    EXPECT_FALSE(session.haveSubscription("Spec2", "*"));
     ModuleCCSession mccs(ccspecfile("spec2.spec"), session, my_config_handler,
                          my_command_handler);
-    EXPECT_EQ(true, session.haveSubscription("Spec2", "*"));
+    EXPECT_TRUE(session.haveSubscription("Spec2", "*"));
 
     EXPECT_EQ(2, session.getMsgQueue()->size());
     ConstElementPtr msg;
@@ -235,10 +235,10 @@
     // client will ask for config
     session.getMessages()->add(createAnswer(0, el("{}")));
 
-    EXPECT_EQ(false, session.haveSubscription("Spec2", "*"));
+    EXPECT_FALSE(session.haveSubscription("Spec2", "*"));
     ModuleCCSession mccs(ccspecfile("spec2.spec"), session, my_config_handler,
                          my_command_handler);
-    EXPECT_EQ(true, session.haveSubscription("Spec2", "*"));
+    EXPECT_TRUE(session.haveSubscription("Spec2", "*"));
 
     EXPECT_EQ(2, session.getMsgQueue()->size());
     ConstElementPtr msg;
@@ -340,23 +340,23 @@
     int item1;
     
     ModuleCCSession mccs(ccspecfile("spec1.spec"), session, NULL, NULL);
-    EXPECT_EQ(true, session.haveSubscription("Spec1", "*"));
+    EXPECT_TRUE(session.haveSubscription("Spec1", "*"));
     
     // first simply connect, with no config values, and see we get
     // the default
     session.getMessages()->add(createAnswer(0, el("{}")));
 
-    EXPECT_EQ(false, session.haveSubscription("Spec2", "*"));
+    EXPECT_FALSE(session.haveSubscription("Spec2", "*"));
     module_name = mccs.addRemoteConfig(ccspecfile("spec2.spec"));
     EXPECT_EQ("Spec2", module_name);
-    EXPECT_EQ(true, session.haveSubscription("Spec2", "*"));
+    EXPECT_TRUE(session.haveSubscription("Spec2", "*"));
 
     item1 = mccs.getRemoteConfigValue(module_name, "item1")->intValue();
     EXPECT_EQ(1, item1);
 
     // Remove it and see we get an error asking for a config value
     mccs.removeRemoteConfig(module_name);
-    EXPECT_EQ(false, session.haveSubscription("Spec2", "*"));
+    EXPECT_FALSE(session.haveSubscription("Spec2", "*"));
     EXPECT_THROW(mccs.getRemoteConfigValue(module_name, "item1"), CCSessionError);
 
     // Now re-add it, with a specific config value, and see we get that
@@ -387,9 +387,9 @@
     // client will ask for config
     session.getMessages()->add(createAnswer(0, el("{  }")));
 
-    EXPECT_EQ(false, session.haveSubscription("Spec2", "*"));
+    EXPECT_FALSE(session.haveSubscription("Spec2", "*"));
     ModuleCCSession mccs(ccspecfile("spec2.spec"), session, my_config_handler, my_command_handler);
-    EXPECT_EQ(true, session.haveSubscription("Spec2", "*"));
+    EXPECT_TRUE(session.haveSubscription("Spec2", "*"));
 
     EXPECT_EQ(2, session.getMsgQueue()->size());
     ConstElementPtr msg;

Modified: branches/trac397focused/src/lib/config/tests/config_data_unittests.cc
==============================================================================
--- branches/trac397focused/src/lib/config/tests/config_data_unittests.cc (original)
+++ branches/trac397focused/src/lib/config/tests/config_data_unittests.cc Mon Dec 20 08:19:35 2010
@@ -120,8 +120,8 @@
     ModuleSpec spec2 = moduleSpecFromFile(std::string(TEST_DATA_PATH) + "/spec2.spec");
     ConfigData cd = ConfigData(spec2);
 
-    EXPECT_EQ("[ \"item1\", \"item2\", \"item3\", \"item4\", \"item5/\", \"item6/\" ]", cd.getItemList()->str());
-    EXPECT_EQ("[ \"item1\", \"item2\", \"item3\", \"item4\", \"item5/\", \"item6/value1\", \"item6/value2\" ]", cd.getItemList("", true)->str());
+    EXPECT_EQ("[ \"item1\", \"item2\", \"item3\", \"item4\", \"item5\", \"item6\" ]", cd.getItemList()->str());
+    EXPECT_EQ("[ \"item1\", \"item2\", \"item3\", \"item4\", \"item5\", \"item6/value1\", \"item6/value2\" ]", cd.getItemList("", true)->str());
     EXPECT_EQ("[ \"item6/value1\", \"item6/value2\" ]", cd.getItemList("item6")->str());
 }
 
@@ -129,12 +129,12 @@
     ModuleSpec spec2 = moduleSpecFromFile(std::string(TEST_DATA_PATH) + "/spec2.spec");
     ConfigData cd = ConfigData(spec2);
 
-    EXPECT_EQ("{ \"item1\": 1, \"item2\": 1.1, \"item3\": true, \"item4\": \"test\", \"item5/\": [ \"a\", \"b\" ], \"item6/value1\": \"default\", \"item6/value2\": None }", cd.getFullConfig()->str());
+    EXPECT_EQ("{ \"item1\": 1, \"item2\": 1.1, \"item3\": true, \"item4\": \"test\", \"item5\": [ \"a\", \"b\" ], \"item6/value1\": \"default\", \"item6/value2\": None }", cd.getFullConfig()->str());
     ElementPtr my_config = Element::fromJSON("{ \"item1\": 2 }");
     cd.setLocalConfig(my_config);
-    EXPECT_EQ("{ \"item1\": 2, \"item2\": 1.1, \"item3\": true, \"item4\": \"test\", \"item5/\": [ \"a\", \"b\" ], \"item6/value1\": \"default\", \"item6/value2\": None }", cd.getFullConfig()->str());
+    EXPECT_EQ("{ \"item1\": 2, \"item2\": 1.1, \"item3\": true, \"item4\": \"test\", \"item5\": [ \"a\", \"b\" ], \"item6/value1\": \"default\", \"item6/value2\": None }", cd.getFullConfig()->str());
     ElementPtr my_config2 = Element::fromJSON("{ \"item6\": { \"value1\": \"a\" } }");
     cd.setLocalConfig(my_config2);
-    EXPECT_EQ("{ \"item1\": 1, \"item2\": 1.1, \"item3\": true, \"item4\": \"test\", \"item5/\": [ \"a\", \"b\" ], \"item6/value1\": \"a\", \"item6/value2\": None }", cd.getFullConfig()->str());
+    EXPECT_EQ("{ \"item1\": 1, \"item2\": 1.1, \"item3\": true, \"item4\": \"test\", \"item5\": [ \"a\", \"b\" ], \"item6/value1\": \"a\", \"item6/value2\": None }", cd.getFullConfig()->str());
 }
 

Modified: branches/trac397focused/src/lib/config/tests/fake_session.cc
==============================================================================
--- branches/trac397focused/src/lib/config/tests/fake_session.cc (original)
+++ branches/trac397focused/src/lib/config/tests/fake_session.cc Mon Dec 20 08:19:35 2010
@@ -87,17 +87,15 @@
 }
 
 void
-FakeSession::startRead(boost::function<void()> read_callback UNUSED_PARAM) {
-}
-
-void
-FakeSession::establish(const char* socket_file) {
-}
-
-bool
-FakeSession::recvmsg(ConstElementPtr& msg, bool nonblock UNUSED_PARAM,
-                     int seq UNUSED_PARAM)
-{
+FakeSession::startRead(boost::function<void()>) {
+}
+
+void
+FakeSession::establish(const char*) {
+}
+
+bool
+FakeSession::recvmsg(ConstElementPtr& msg, bool, int) {
     //cout << "[XX] client asks for message " << endl;
     if (messages_ &&
         messages_->getType() == Element::list &&
@@ -111,10 +109,7 @@
 }
 
 bool
-FakeSession::recvmsg(ConstElementPtr& env, ConstElementPtr& msg,
-                     bool nonblock UNUSED_PARAM,
-                     int seq UNUSED_PARAM)
-{
+FakeSession::recvmsg(ConstElementPtr& env, ConstElementPtr& msg, bool, int) {
     //cout << "[XX] client asks for message and env" << endl;
     env = ElementPtr();
     if (messages_ &&
@@ -172,7 +167,7 @@
 
 int
 FakeSession::group_sendmsg(ConstElementPtr msg, std::string group,
-                           std::string to, std::string instance UNUSED_PARAM)
+                           std::string to, std::string)
 {
     //cout << "[XX] client sends message: " << msg << endl;
     //cout << "[XX] to: " << group << " . " << instance << "." << to << endl;

Modified: branches/trac397focused/src/lib/config/tests/fake_session.h
==============================================================================
--- branches/trac397focused/src/lib/config/tests/fake_session.h (original)
+++ branches/trac397focused/src/lib/config/tests/fake_session.h Mon Dec 20 08:19:35 2010
@@ -63,7 +63,7 @@
     virtual int reply(isc::data::ConstElementPtr envelope,
                       isc::data::ConstElementPtr newmsg);
     virtual bool hasQueuedMsgs() const;
-    virtual void setTimeout(size_t milliseconds) {}
+    virtual void setTimeout(size_t) {}
     virtual size_t getTimeout() const { return (0); }
     isc::data::ConstElementPtr getFirstMessage(std::string& group,
                                                std::string& to) const;

Modified: branches/trac397focused/src/lib/datasrc/Makefile.am
==============================================================================
--- branches/trac397focused/src/lib/datasrc/Makefile.am (original)
+++ branches/trac397focused/src/lib/datasrc/Makefile.am Mon Dec 20 08:19:35 2010
@@ -2,6 +2,7 @@
 
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
+AM_CPPFLAGS += $(BOOST_INCLUDES)
 AM_CPPFLAGS += $(SQLITE_CFLAGS)
 
 AM_CXXFLAGS = $(B10_CXXFLAGS)
@@ -15,3 +16,5 @@
 libdatasrc_la_SOURCES += query.h query.cc
 libdatasrc_la_SOURCES += cache.h cache.cc
 libdatasrc_la_SOURCES += rbtree.h 
+libdatasrc_la_SOURCES += zonetable.h zonetable.cc
+libdatasrc_la_SOURCES += memory_datasrc.h memory_datasrc.cc

Modified: branches/trac397focused/src/lib/datasrc/cache.h
==============================================================================
--- branches/trac397focused/src/lib/datasrc/cache.h (original)
+++ branches/trac397focused/src/lib/datasrc/cache.h Mon Dec 20 08:19:35 2010
@@ -170,9 +170,9 @@
     /// then promoted to the head of the LRU queue.  (NOTE: Because
     /// of this, "retrieve" cannot be implemented as a const method.)
     ///
-    /// \param name The query name
-    /// \param rrclass The query class
-    /// \param rrtype The query type
+    /// \param qname The query name
+    /// \param qclass The query class
+    /// \param qtype The query type
     /// \param rrset Returns the RRset found, if any, to the caller
     /// \param flags Returns the flags, if any, to the caller
     ///

Modified: branches/trac397focused/src/lib/datasrc/data_source.cc
==============================================================================
--- branches/trac397focused/src/lib/datasrc/data_source.cc (original)
+++ branches/trac397focused/src/lib/datasrc/data_source.cc Mon Dec 20 08:19:35 2010
@@ -95,20 +95,20 @@
     }
 
     RdataIteratorPtr it = rrset->getRdataIterator();
-    for (it->first(); !it->isLast(); it->next()) {
+    for (; !it->isLast(); it->next()) {
         const Rdata& rd(it->getCurrent());
         if (rrset->getType() == RRType::NS()) {
             const generic::NS& ns = dynamic_cast<const generic::NS&>(rd);
             q.tasks().push(QueryTaskPtr(
                                new QueryTask(q, ns.getNSName(),
-                                             Section::ADDITIONAL(),
+                                             Message::SECTION_ADDITIONAL,
                                              QueryTask::GLUE_QUERY,
                                              QueryTask::GETADDITIONAL))); 
         } else if (rrset->getType() == RRType::MX()) {
             const generic::MX& mx = dynamic_cast<const generic::MX&>(rd);
             q.tasks().push(QueryTaskPtr(
                                new QueryTask(q, mx.getMXName(),
-                                             Section::ADDITIONAL(),
+                                             Message::SECTION_ADDITIONAL,
                                              QueryTask::NOGLUE_QUERY,
                                              QueryTask::GETADDITIONAL))); 
         }
@@ -123,7 +123,6 @@
 
     // More than one DNAME RR in the RRset is illegal, so we only have
     // to process the first one.
-    it->first();
     if (it->isLast()) {
         return;
     }
@@ -152,7 +151,6 @@
 
     // More than one CNAME RR in the RRset is illegal, so we only have
     // to process the first one.
-    it->first();
     if (it->isLast()) {
         return;
     }
@@ -165,7 +163,7 @@
     q.tasks().push(QueryTaskPtr(
                        new QueryTask(q, dynamic_cast<const generic::CNAME&>
                                      (it->getCurrent()).getCname(),
-                                     task->qtype, Section::ANSWER(),
+                                     task->qtype, Message::SECTION_ANSWER,
                                      QueryTask::FOLLOWCNAME)));
 }
 
@@ -473,16 +471,19 @@
 // checking first to ensure that there isn't already an RRset with
 // the same name and type.
 inline void
-addToMessage(Query& q, const Section& sect, RRsetPtr rrset,
+addToMessage(Query& q, const Message::Section sect, RRsetPtr rrset,
              bool no_dnssec = false)
 {
     Message& m = q.message();
     if (no_dnssec) {
-        if (rrset->getType() == RRType::RRSIG() || !m.hasRRset(sect, rrset)) {
+        if (rrset->getType() == RRType::RRSIG() ||
+            !m.hasRRset(sect, rrset->getName(), rrset->getClass(),
+                        rrset->getType())) {
             m.addRRset(sect, rrset, false);
         }
     } else {
-        if (!m.hasRRset(sect, rrset)) {
+        if (!m.hasRRset(sect, rrset->getName(), rrset->getClass(),
+                        rrset->getType())) {
             m.addRRset(sect, rrset, q.wantDnssec());
         }
     }
@@ -498,7 +499,7 @@
         if (rrset->getType() == RRType::DS() && !q.wantDnssec()) {
             continue;
         }
-        addToMessage(q, Section::AUTHORITY(), rrset);
+        addToMessage(q, Message::SECTION_AUTHORITY, rrset);
         getAdditional(q, rrset);
     }
 }
@@ -560,11 +561,11 @@
             RRsetPtr r = ref.findRRset(RRType::DNAME(), q.qclass());
             if (r != NULL) {
                 RRsetList syn;
-                addToMessage(q, Section::ANSWER(), r);
-                q.message().setHeaderFlag(MessageFlag::AA());
+                addToMessage(q, Message::SECTION_ANSWER, r);
+                q.message().setHeaderFlag(Message::HEADERFLAG_AA);
                 synthesizeCname(task, r, syn);
                 if (syn.size() == 1) {
-                    addToMessage(q, Section::ANSWER(),
+                    addToMessage(q, Message::SECTION_ANSWER,
                                  syn.findRRset(RRType::CNAME(), q.qclass()));
                     chaseCname(q, task, syn.findRRset(RRType::CNAME(),
                                                       q.qclass()));
@@ -582,7 +583,7 @@
     // at the actual qname node.)
     if (task->op == QueryTask::AUTH_QUERY &&
         task->state == QueryTask::GETANSWER) {
-        q.message().setHeaderFlag(MessageFlag::AA());
+        q.message().setHeaderFlag(Message::HEADERFLAG_AA);
     }
 
     return (false);
@@ -599,7 +600,7 @@
         return (DataSrc::ERROR);
     }
 
-    addToMessage(q, Section::AUTHORITY(),
+    addToMessage(q, Message::SECTION_AUTHORITY,
                  soa.findRRset(RRType::SOA(), q.qclass()));
     return (DataSrc::SUCCESS);
 }
@@ -611,7 +612,7 @@
     QueryTask newtask(q, name, RRType::NSEC(), QueryTask::SIMPLE_QUERY); 
     RETERR(doQueryTask(newtask, zoneinfo, nsec));
     if (newtask.flags == 0) {
-        addToMessage(q, Section::AUTHORITY(),
+        addToMessage(q, Message::SECTION_AUTHORITY,
                      nsec.findRRset(RRType::NSEC(), q.qclass()));
     }
 
@@ -657,7 +658,6 @@
     // XXX: currently only one NSEC3 chain per zone is supported;
     // we will need to revisit this.
     RdataIteratorPtr it = rrset->getRdataIterator();
-    it->first();
     if (it->isLast()) {
         return (ConstNsec3ParamPtr());
     }
@@ -680,7 +680,7 @@
         RRsetPtr rrset;
         string hash1(nsec3->getHash(task->qname));
         RETERR(getNsec3(q, zoneinfo, hash1, rrset));
-        addToMessage(q, Section::AUTHORITY(), rrset);
+        addToMessage(q, Message::SECTION_AUTHORITY, rrset);
 
         // If this is an NXRRSET or NOERROR/NODATA, we're done
         if ((task->flags & DataSrc::TYPE_NOT_FOUND) != 0) {
@@ -705,7 +705,7 @@
             // we don't want to use one until we find an exact match
             RETERR(getNsec3(q, zoneinfo, hash2, rrset));
             if (hash2 == nodehash) {
-                addToMessage(q, Section::AUTHORITY(), rrset);
+                addToMessage(q, Message::SECTION_AUTHORITY, rrset);
                 break;
             }
         }
@@ -720,7 +720,7 @@
         string hash3(nsec3->getHash(Name("*").concatenate(enclosure)));
         RETERR(getNsec3(q, zoneinfo, hash3, rrset));
         if (hash3 != hash1 && hash3 != hash2) {
-            addToMessage(q, Section::AUTHORITY(), rrset);
+            addToMessage(q, Message::SECTION_AUTHORITY, rrset);
         }
     } else {
         Name nsecname(task->qname);
@@ -778,7 +778,7 @@
 
     for (int i = 1; i <= diff; ++i) {
         const Name& wname(star.concatenate(task->qname.split(i)));
-        QueryTask newtask(q, wname, task->qtype, Section::ANSWER(),
+        QueryTask newtask(q, wname, task->qtype, Message::SECTION_ANSWER,
                           QueryTask::AUTH_QUERY); 
         result = doQueryTask(newtask, zoneinfo, wild);
         if (result == DataSrc::SUCCESS) {
@@ -820,13 +820,13 @@
             RRsetPtr rrset = wild.findRRset(RRType::CNAME(), q.qclass());
             if (rrset != NULL) {
                 rrset->setName(task->qname);
-                addToMessage(q, Section::ANSWER(), rrset);
+                addToMessage(q, Message::SECTION_ANSWER, rrset);
                 chaseCname(q, task, rrset);
             }
         } else {
             BOOST_FOREACH (RRsetPtr rrset, wild) {
                 rrset->setName(task->qname);
-                addToMessage(q, Section::ANSWER(), rrset);
+                addToMessage(q, Message::SECTION_ANSWER, rrset);
             }
 
             RRsetList auth;
@@ -855,7 +855,7 @@
 
     // Process the query task queue.  (The queue is initialized
     // and the first task placed on it by the Query constructor.)
-    m.clearHeaderFlag(MessageFlag::AA());
+    m.setHeaderFlag(Message::HEADERFLAG_AA, false);
     while (!q.tasks().empty()) {
         QueryTaskPtr task = q.tasks().front();
         q.tasks().pop();
@@ -982,19 +982,19 @@
             // The qname node contains an out-of-zone referral.
             if (task->state == QueryTask::GETANSWER) {
                 RRsetList auth;
-                m.clearHeaderFlag(MessageFlag::AA());
+                m.setHeaderFlag(Message::HEADERFLAG_AA, false);
                 if (!refQuery(q, task->qname, zoneinfo, auth)) {
                     m.setRcode(Rcode::SERVFAIL());
                     return;
                 }
                 BOOST_FOREACH (RRsetPtr rrset, auth) {
                     if (rrset->getType() == RRType::NS()) {
-                        addToMessage(q, Section::AUTHORITY(), rrset);
+                        addToMessage(q, Message::SECTION_AUTHORITY, rrset);
                     } else if (rrset->getType() == task->qtype) {
-                        addToMessage(q, Section::ANSWER(), rrset);
+                        addToMessage(q, Message::SECTION_ANSWER, rrset);
                     } else if (rrset->getType() == RRType::DS() &&
                                q.wantDnssec()) {
-                        addToMessage(q, Section::AUTHORITY(), rrset);
+                        addToMessage(q, Message::SECTION_AUTHORITY, rrset);
                     }
                     getAdditional(q, rrset);
                 }
@@ -1063,13 +1063,14 @@
     // space, signatures in additional section are
     // optional.)
     BOOST_FOREACH(RRsetPtr rrset, additional) {
-        addToMessage(q, Section::ADDITIONAL(), rrset, true);
+        addToMessage(q, Message::SECTION_ADDITIONAL, rrset, true);
     }
 
     if (q.wantDnssec()) {
         BOOST_FOREACH(RRsetPtr rrset, additional) {
             if (rrset->getRRsig()) {
-                addToMessage(q, Section::ADDITIONAL(), rrset->getRRsig(), true);
+                addToMessage(q, Message::SECTION_ADDITIONAL, rrset->getRRsig(),
+                             true);
             }
         }
     }
@@ -1243,72 +1244,65 @@
     return (encodeBase32Hex(vector<uint8_t>(digest, digest + SHA1_HASHSIZE)));
 }
 
-//
-// The following methods are effectively empty, and their parameters are
-// unused.  To silence compilers that warn unused function parameters,
-// we specify a (compiler dependent) special keyword when available.
-// It's defined in config.h, and to avoid including this header file from
-// installed files we define the methods here.
-//
 DataSrc::Result
-DataSrc::init(isc::data::ConstElementPtr config UNUSED_PARAM) {
+DataSrc::init(isc::data::ConstElementPtr) {
     return (NOT_IMPLEMENTED);
 }
 
 DataSrc::Result
-MetaDataSrc::findRRset(const isc::dns::Name& qname UNUSED_PARAM,
-                       const isc::dns::RRClass& qclass UNUSED_PARAM,
-                       const isc::dns::RRType& qtype UNUSED_PARAM,
-                       isc::dns::RRsetList& target UNUSED_PARAM,
-                       uint32_t& flags UNUSED_PARAM,
-                       const isc::dns::Name* zonename UNUSED_PARAM) const
+MetaDataSrc::findRRset(const isc::dns::Name&,
+                       const isc::dns::RRClass&,
+                       const isc::dns::RRType&,
+                       isc::dns::RRsetList&,
+                       uint32_t&,
+                       const isc::dns::Name*) const
 {
     return (NOT_IMPLEMENTED);
 }
 
 DataSrc::Result
-MetaDataSrc::findExactRRset(const isc::dns::Name& qname UNUSED_PARAM,
-                            const isc::dns::RRClass& qclass UNUSED_PARAM,
-                            const isc::dns::RRType& qtype UNUSED_PARAM,
-                            isc::dns::RRsetList& target UNUSED_PARAM,
-                            uint32_t& flags UNUSED_PARAM,
-                            const isc::dns::Name* zonename UNUSED_PARAM) const
+MetaDataSrc::findExactRRset(const isc::dns::Name&,
+                            const isc::dns::RRClass&,
+                            const isc::dns::RRType&,
+                            isc::dns::RRsetList&,
+                            uint32_t&,
+                            const isc::dns::Name*) const
 {
     return (NOT_IMPLEMENTED);
 }
 
 DataSrc::Result
-MetaDataSrc::findAddrs(const isc::dns::Name& qname UNUSED_PARAM,
-                       const isc::dns::RRClass& qclass UNUSED_PARAM,
-                       isc::dns::RRsetList& target UNUSED_PARAM,
-                       uint32_t& flags UNUSED_PARAM,
-                       const isc::dns::Name* zonename UNUSED_PARAM) const
+MetaDataSrc::findAddrs(const isc::dns::Name&,
+                       const isc::dns::RRClass&,
+                       isc::dns::RRsetList&,
+                       uint32_t&,
+                       const isc::dns::Name*) const
 {
     return (NOT_IMPLEMENTED);
 }
 
 DataSrc::Result
-MetaDataSrc::findReferral(const isc::dns::Name& qname UNUSED_PARAM,
-                          const isc::dns::RRClass& qclass UNUSED_PARAM,
-                          isc::dns::RRsetList& target UNUSED_PARAM,
-                          uint32_t& flags UNUSED_PARAM,
-                          const isc::dns::Name* zonename UNUSED_PARAM) const
+MetaDataSrc::findReferral(const isc::dns::Name&,
+                          const isc::dns::RRClass&,
+                          isc::dns::RRsetList&,
+                          uint32_t&,
+                          const isc::dns::Name*) const
 {
     return (NOT_IMPLEMENTED);
 }
 
 DataSrc::Result
-MetaDataSrc::findPreviousName(const isc::dns::Name& qname UNUSED_PARAM,
-                              isc::dns::Name& target UNUSED_PARAM,
-                              const isc::dns::Name* zonename UNUSED_PARAM) const
+MetaDataSrc::findPreviousName(const isc::dns::Name&,
+                              isc::dns::Name&,
+                              const isc::dns::Name*) const
 {
     return (NOT_IMPLEMENTED);
 }
 
 DataSrc::Result
-MetaDataSrc::findCoveringNSEC3(const isc::dns::Name& zonename UNUSED_PARAM,
-                               std::string& hash UNUSED_PARAM,
-                               isc::dns::RRsetList& target UNUSED_PARAM) const
+MetaDataSrc::findCoveringNSEC3(const isc::dns::Name&,
+                               std::string&,
+                               isc::dns::RRsetList&) const
 {
     return (NOT_IMPLEMENTED);
 }

Modified: branches/trac397focused/src/lib/datasrc/query.cc
==============================================================================
--- branches/trac397focused/src/lib/datasrc/query.cc (original)
+++ branches/trac397focused/src/lib/datasrc/query.cc Mon Dec 20 08:19:35 2010
@@ -29,27 +29,31 @@
 namespace datasrc {
 
 QueryTask::QueryTask(const Query& qry, const isc::dns::Name& n,
-                     const isc::dns::RRType& t, const isc::dns::Section& sect) :
+                     const isc::dns::RRType& t,
+                     const isc::dns::Message::Section sect) :
     q(qry), qname(n), qclass(qry.qclass()), qtype(t), section(sect),
     op(AUTH_QUERY), state(GETANSWER), flags(0)
 {}
 
 QueryTask::QueryTask(const Query& qry, const isc::dns::Name& n, 
-                     const isc::dns::RRType& t, const isc::dns::Section& sect,
+                     const isc::dns::RRType& t,
+                     const isc::dns::Message::Section sect,
                      const Op o) :
     q(qry), qname(n), qclass(qry.qclass()), qtype(t), section(sect), op(o),
     state(GETANSWER), flags(0)
 {}
 
 QueryTask::QueryTask(const Query& qry, const isc::dns::Name& n,
-                     const isc::dns::RRType& t, const isc::dns::Section& sect,
+                     const isc::dns::RRType& t,
+                     const isc::dns::Message::Section sect,
                      const State st) :
     q(qry), qname(n), qclass(qry.qclass()), qtype(t), section(sect),
     op(AUTH_QUERY), state(st), flags(0)
 {}
 
 QueryTask::QueryTask(const Query& qry, const isc::dns::Name& n,
-                     const isc::dns::RRType& t, const isc::dns::Section& sect,
+                     const isc::dns::RRType& t,
+                     const isc::dns::Message::Section sect,
                      const Op o, const State st) :
     q(qry), qname(n), qclass(qry.qclass()), qtype(t), section(sect), op(o),
     state(st), flags(0) 
@@ -58,7 +62,7 @@
 QueryTask::QueryTask(const Query& qry, const isc::dns::Name& n, 
                      const isc::dns::RRType& t, const Op o) :
     q(qry), qname(n), qclass(qry.qclass()), qtype(t),
-    section(Section::ANSWER()), op(o), state(GETANSWER), flags(0)
+    section(Message::SECTION_ANSWER), op(o), state(GETANSWER), flags(0)
 {
     if (op != SIMPLE_QUERY) {
         isc_throw(Unexpected, "invalid constructor for this task operation");
@@ -68,7 +72,7 @@
 // A referral query doesn't need to specify section, state, or type.
 QueryTask::QueryTask(const Query& qry, const isc::dns::Name& n, const Op o) :
     q(qry), qname(n), qclass(qry.qclass()), qtype(RRType::ANY()),
-    section(Section::ANSWER()), op(o), state(GETANSWER), flags(0)
+    section(Message::SECTION_ANSWER), op(o), state(GETANSWER), flags(0)
 {
     if (op != REF_QUERY) {
         isc_throw(Unexpected, "invalid constructor for this task operation");
@@ -76,7 +80,7 @@
 }
 
 QueryTask::QueryTask(const Query& qry, const isc::dns::Name& n,
-                     const isc::dns::Section& sect, const Op o,
+                     const isc::dns::Message::Section sect, const Op o,
                      const State st) :
         q(qry), qname(n), qclass(qry.qclass()), qtype(RRType::ANY()),
         section(sect), op(o), state(st), flags(0)
@@ -93,7 +97,7 @@
     cache_(&c), message_(&m), want_additional_(true), want_dnssec_(dnssec)
 {
     // Check message formatting
-    if (message_->getRRCount(Section::QUESTION()) != 1) {
+    if (message_->getRRCount(Message::SECTION_QUESTION) != 1) {
         isc_throw(Unexpected, "malformed message: too many questions");
     }
 
@@ -105,7 +109,7 @@
     restarts_ = 0;
 
     querytasks_.push(QueryTaskPtr(new QueryTask(*this, *qname_, *qtype_,
-                                                Section::ANSWER())));
+                                                Message::SECTION_ANSWER)));
 }
 
 Query::~Query() {}

Modified: branches/trac397focused/src/lib/datasrc/query.h
==============================================================================
--- branches/trac397focused/src/lib/datasrc/query.h (original)
+++ branches/trac397focused/src/lib/datasrc/query.h Mon Dec 20 08:19:35 2010
@@ -57,7 +57,7 @@
 
     // The section of the reply into which the data should be
     // written after it has been fetched from the data source.
-    const isc::dns::Section section;
+    const isc::dns::Message::Section section;
 
     // The op field indicates the operation to be carried out by
     // this query task:
@@ -127,14 +127,18 @@
 
     // Constructors
     QueryTask(const Query& q, const isc::dns::Name& n,
-              const isc::dns::RRType& t, const isc::dns::Section& sect);
-    QueryTask(const Query& q, const isc::dns::Name& n,
-              const isc::dns::RRType& t, const isc::dns::Section& sect, Op o);
-    QueryTask(const Query& q, const isc::dns::Name& n,
-              const isc::dns::RRType& t, const isc::dns::Section& sect,
+              const isc::dns::RRType& t,
+              const isc::dns::Message::Section sect);
+    QueryTask(const Query& q, const isc::dns::Name& n,
+              const isc::dns::RRType& t,
+              const isc::dns::Message::Section sect, Op o);
+    QueryTask(const Query& q, const isc::dns::Name& n,
+              const isc::dns::RRType& t,
+              const isc::dns::Message::Section sect,
               const State st);
     QueryTask(const Query& q, const isc::dns::Name& n,
-              const isc::dns::RRType& t, const isc::dns::Section& sect,
+              const isc::dns::RRType& t,
+              const isc::dns::Message::Section sect,
               Op o, State st);
 
     // These are special constructors for particular query task types,
@@ -147,7 +151,7 @@
     QueryTask(const Query& q, const isc::dns::Name& n, Op o);
     // A glue (or noglue) query doesn't need to specify type.
     QueryTask(const Query& q, const isc::dns::Name& n,
-              const isc::dns::Section& sect, Op o, State st);
+              const isc::dns::Message::Section sect, Op o, State st);
 
     ~QueryTask();
 };

Modified: branches/trac397focused/src/lib/datasrc/static_datasrc.cc
==============================================================================
--- branches/trac397focused/src/lib/datasrc/static_datasrc.cc (original)
+++ branches/trac397focused/src/lib/datasrc/static_datasrc.cc Mon Dec 20 08:19:35 2010
@@ -79,6 +79,7 @@
     authors->addRdata(generic::TXT("JINMEI Tatuya"));
     authors->addRdata(generic::TXT("Kazunori Fujiwara"));
     authors->addRdata(generic::TXT("Michael Graff"));
+    authors->addRdata(generic::TXT("Michal Vaner"));
     authors->addRdata(generic::TXT("Naoki Kambe"));
     authors->addRdata(generic::TXT("Shane Kerr"));
     authors->addRdata(generic::TXT("Shen Tingting"));
@@ -235,18 +236,12 @@
 }
 
 DataSrc::Result
-StaticDataSrc::findPreviousName(const Name& qname UNUSED_PARAM,
-                                Name& target UNUSED_PARAM,
-                                const Name* zonename UNUSED_PARAM) const
-{
+StaticDataSrc::findPreviousName(const Name&, Name&, const Name*) const {
     return (NOT_IMPLEMENTED);
 }
 
 DataSrc::Result
-StaticDataSrc::findCoveringNSEC3(const Name& zonename UNUSED_PARAM,
-                                 string& hash UNUSED_PARAM,
-                                 RRsetList& target UNUSED_PARAM) const
-{
+StaticDataSrc::findCoveringNSEC3(const Name&, string&, RRsetList&) const {
    return (NOT_IMPLEMENTED);
 }
 
@@ -258,7 +253,7 @@
 // Static data source is "configuration less", so the \c config parameter
 // is intentionally ignored.
 DataSrc::Result
-StaticDataSrc::init(isc::data::ConstElementPtr config UNUSED_PARAM) {
+StaticDataSrc::init(isc::data::ConstElementPtr) {
     return (init());
 }
 

Modified: branches/trac397focused/src/lib/datasrc/tests/Makefile.am
==============================================================================
--- branches/trac397focused/src/lib/datasrc/tests/Makefile.am (original)
+++ branches/trac397focused/src/lib/datasrc/tests/Makefile.am Mon Dec 20 08:19:35 2010
@@ -1,5 +1,7 @@
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += -I$(top_builddir)/src/lib/dns -I$(top_srcdir)/src/lib/dns
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CPPFLAGS += $(SQLITE_CFLAGS)
 AM_CPPFLAGS += -DTEST_DATA_DIR=\"$(srcdir)/testdata\"
 
 AM_CXXFLAGS = $(B10_CXXFLAGS)
@@ -23,11 +25,13 @@
 run_unittests_SOURCES += cache_unittest.cc
 run_unittests_SOURCES += test_datasrc.h test_datasrc.cc
 run_unittests_SOURCES += rbtree_unittest.cc
+run_unittests_SOURCES += zonetable_unittest.cc
+run_unittests_SOURCES += memory_datasrc_unittest.cc
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
 run_unittests_LDADD = $(GTEST_LDADD)
 run_unittests_LDADD += $(SQLITE_LIBS)
-run_unittests_LDADD += $(top_builddir)/src/lib/datasrc/libdatasrc.la 
+run_unittests_LDADD += $(top_builddir)/src/lib/datasrc/libdatasrc.la
 run_unittests_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
 run_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.la
 run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la

Modified: branches/trac397focused/src/lib/datasrc/tests/datasrc_unittest.cc
==============================================================================
--- branches/trac397focused/src/lib/datasrc/tests/datasrc_unittest.cc (original)
+++ branches/trac397focused/src/lib/datasrc/tests/datasrc_unittest.cc Mon Dec 20 08:19:35 2010
@@ -79,7 +79,7 @@
 
 void
 performQuery(DataSrc& data_source, HotCache& cache, Message& message) {
-    message.setHeaderFlag(MessageFlag::AA());
+    message.setHeaderFlag(Message::HEADERFLAG_AA);
     message.setRcode(Rcode::NOERROR());
     Query q(message, cache, true);
     data_source.doQuery(q);
@@ -92,7 +92,7 @@
     msg.makeResponse();
     msg.setOpcode(Opcode::QUERY());
     msg.addQuestion(Question(qname, qclass, qtype));
-    msg.setHeaderFlag(MessageFlag::RD());
+    msg.setHeaderFlag(Message::HEADERFLAG_RD);
     performQuery(meta_source, cache, msg);
 }
 
@@ -102,13 +102,13 @@
             const unsigned int nscount, const unsigned int arcount)
 {
     EXPECT_EQ(rcode, message.getRcode());
-    EXPECT_EQ(qrflag, message.getHeaderFlag(MessageFlag::QR()));
-    EXPECT_EQ(aaflag, message.getHeaderFlag(MessageFlag::AA()));
-    EXPECT_EQ(rdflag, message.getHeaderFlag(MessageFlag::RD()));
-
-    EXPECT_EQ(ancount, message.getRRCount(Section::ANSWER()));
-    EXPECT_EQ(nscount, message.getRRCount(Section::AUTHORITY()));
-    EXPECT_EQ(arcount, message.getRRCount(Section::ADDITIONAL()));
+    EXPECT_EQ(qrflag, message.getHeaderFlag(Message::HEADERFLAG_QR));
+    EXPECT_EQ(aaflag, message.getHeaderFlag(Message::HEADERFLAG_AA));
+    EXPECT_EQ(rdflag, message.getHeaderFlag(Message::HEADERFLAG_RD));
+
+    EXPECT_EQ(ancount, message.getRRCount(Message::SECTION_ANSWER));
+    EXPECT_EQ(nscount, message.getRRCount(Message::SECTION_AUTHORITY));
+    EXPECT_EQ(arcount, message.getRRCount(Message::SECTION_ADDITIONAL));
 }
 
 void
@@ -117,28 +117,26 @@
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 4, 6);
 
-    RRsetIterator rit = msg.beginSection(Section::ANSWER());
+    RRsetIterator rit = msg.beginSection(Message::SECTION_ANSWER);
     RRsetPtr rrset = *rit;
     EXPECT_EQ(Name("www.example.com"), rrset->getName());
     EXPECT_EQ(RRType::A(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     RdataIteratorPtr it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("192.0.2.1", it->getCurrent().toText());
     it->next();
     EXPECT_TRUE(it->isLast());
 
     // XXX: also check ANSWER RRSIG
 
-    rit = msg.beginSection(Section::AUTHORITY());
-    rrset = *rit;
-    EXPECT_EQ(Name("example.com"), rrset->getName());
-    EXPECT_EQ(RRType::NS(), rrset->getType());
-    EXPECT_EQ(RRClass::IN(), rrset->getClass());
-
-    it = rrset->getRdataIterator();
-    it->first();
+    rit = msg.beginSection(Message::SECTION_AUTHORITY);
+    rrset = *rit;
+    EXPECT_EQ(Name("example.com"), rrset->getName());
+    EXPECT_EQ(RRType::NS(), rrset->getType());
+    EXPECT_EQ(RRClass::IN(), rrset->getClass());
+
+    it = rrset->getRdataIterator();
     EXPECT_EQ("dns01.example.com.", it->getCurrent().toText());
     it->next();
     EXPECT_EQ("dns02.example.com.", it->getCurrent().toText());
@@ -147,14 +145,13 @@
     it->next();
     EXPECT_TRUE(it->isLast());
 
-    rit = msg.beginSection(Section::ADDITIONAL());
+    rit = msg.beginSection(Message::SECTION_ADDITIONAL);
     rrset = *rit;
     EXPECT_EQ(Name("dns01.example.com"), rrset->getName());
     EXPECT_EQ(RRType::A(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("192.0.2.1", it->getCurrent().toText());
     it->next();
     EXPECT_TRUE(it->isLast());
@@ -171,9 +168,9 @@
     headerCheck(msg, Rcode::REFUSED(), true, false, true, 0, 0, 0);
 
     EXPECT_EQ(Rcode::REFUSED(), msg.getRcode());
-    EXPECT_TRUE(msg.getHeaderFlag(MessageFlag::QR()));
-    EXPECT_FALSE(msg.getHeaderFlag(MessageFlag::AA()));
-    EXPECT_TRUE(msg.getHeaderFlag(MessageFlag::RD()));
+    EXPECT_TRUE(msg.getHeaderFlag(Message::HEADERFLAG_QR));
+    EXPECT_FALSE(msg.getHeaderFlag(Message::HEADERFLAG_AA));
+    EXPECT_TRUE(msg.getHeaderFlag(Message::HEADERFLAG_RD));
 }
 
 // Query class of any should match the first data source.
@@ -186,14 +183,13 @@
                           RRType::NS());
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 0, 6);
 
-    RRsetIterator rit = msg.beginSection(Section::ANSWER());
-    RRsetPtr rrset = *rit;
-    EXPECT_EQ(Name("example.com"), rrset->getName());
-    EXPECT_EQ(RRType::NS(), rrset->getType());
-    EXPECT_EQ(RRClass::IN(), rrset->getClass());
-
-    RdataIteratorPtr it = rrset->getRdataIterator();
-    it->first();
+    RRsetIterator rit = msg.beginSection(Message::SECTION_ANSWER);
+    RRsetPtr rrset = *rit;
+    EXPECT_EQ(Name("example.com"), rrset->getName());
+    EXPECT_EQ(RRType::NS(), rrset->getType());
+    EXPECT_EQ(RRClass::IN(), rrset->getClass());
+
+    RdataIteratorPtr it = rrset->getRdataIterator();
     EXPECT_EQ("dns01.example.com.", it->getCurrent().toText());
     it->next();
     EXPECT_EQ("dns02.example.com.", it->getCurrent().toText());
@@ -209,14 +205,13 @@
                           RRType::NS());
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 0, 6);
 
-    RRsetIterator rit = msg.beginSection(Section::ANSWER());
-    RRsetPtr rrset = *rit;
-    EXPECT_EQ(Name("example.com"), rrset->getName());
-    EXPECT_EQ(RRType::NS(), rrset->getType());
-    EXPECT_EQ(RRClass::IN(), rrset->getClass());
-
-    RdataIteratorPtr it = rrset->getRdataIterator();
-    it->first();
+    RRsetIterator rit = msg.beginSection(Message::SECTION_ANSWER);
+    RRsetPtr rrset = *rit;
+    EXPECT_EQ(Name("example.com"), rrset->getName());
+    EXPECT_EQ(RRType::NS(), rrset->getType());
+    EXPECT_EQ(RRClass::IN(), rrset->getClass());
+
+    RdataIteratorPtr it = rrset->getRdataIterator();
     EXPECT_EQ("dns01.example.com.", it->getCurrent().toText());
     it->next();
     EXPECT_EQ("dns02.example.com.", it->getCurrent().toText());
@@ -230,14 +225,13 @@
                           RRType::NS());
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 0, 6);
 
-    rit = msg.beginSection(Section::ANSWER());
-    rrset = *rit;
-    EXPECT_EQ(Name("example.com"), rrset->getName());
-    EXPECT_EQ(RRType::NS(), rrset->getType());
-    EXPECT_EQ(RRClass::IN(), rrset->getClass());
-
-    it = rrset->getRdataIterator();
-    it->first();
+    rit = msg.beginSection(Message::SECTION_ANSWER);
+    rrset = *rit;
+    EXPECT_EQ(Name("example.com"), rrset->getName());
+    EXPECT_EQ(RRType::NS(), rrset->getType());
+    EXPECT_EQ(RRClass::IN(), rrset->getClass());
+
+    it = rrset->getRdataIterator();
     EXPECT_EQ("dns01.example.com.", it->getCurrent().toText());
     it->next();
     EXPECT_EQ("dns02.example.com.", it->getCurrent().toText());
@@ -252,7 +246,7 @@
                           RRType::DNSKEY());
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 4, 6);
 
-    RRsetIterator rit = msg.beginSection(Section::ANSWER());
+    RRsetIterator rit = msg.beginSection(Message::SECTION_ANSWER);
     RRsetPtr rrset = *rit;
     EXPECT_EQ(Name("example.com"), rrset->getName());
     EXPECT_EQ(RRType::DNSKEY(), rrset->getType());
@@ -267,7 +261,7 @@
                           RRType::DNSKEY());
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 4, 6);
 
-    RRsetIterator rit = msg.beginSection(Section::ANSWER());
+    RRsetIterator rit = msg.beginSection(Message::SECTION_ANSWER);
     RRsetPtr rrset = *rit;
     EXPECT_EQ(Name("example.com"), rrset->getName());
     EXPECT_EQ(RRType::DNSKEY(), rrset->getType());
@@ -276,7 +270,7 @@
     msg.clear(Message::PARSE);
     createAndProcessQuery(Name("example.com"), RRClass::IN(),
                           RRType::DNSKEY());
-    rit = msg.beginSection(Section::ANSWER());
+    rit = msg.beginSection(Message::SECTION_ANSWER);
     rrset = *rit;
     EXPECT_EQ(Name("example.com"), rrset->getName());
     EXPECT_EQ(RRType::DNSKEY(), rrset->getType());
@@ -289,7 +283,7 @@
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 0, 4, 0);
 
-    RRsetIterator rit = msg.beginSection(Section::AUTHORITY());
+    RRsetIterator rit = msg.beginSection(Message::SECTION_AUTHORITY);
     RRsetPtr rrset = *rit;
     EXPECT_EQ(Name("example.com"), rrset->getName());
     EXPECT_EQ(RRType::SOA(), rrset->getType());
@@ -301,7 +295,7 @@
 
     headerCheck(msg, Rcode::NXDOMAIN(), true, true, true, 0, 6, 0);
 
-    RRsetIterator rit = msg.beginSection(Section::AUTHORITY());
+    RRsetIterator rit = msg.beginSection(Message::SECTION_AUTHORITY);
     RRsetPtr rrset = *rit;
     EXPECT_EQ(Name("example.com"), rrset->getName());
     EXPECT_EQ(RRType::SOA(), rrset->getType());
@@ -316,9 +310,9 @@
     headerCheck(msg, Rcode::REFUSED(), true, false, true, 0, 0, 0);
 
     EXPECT_EQ(Rcode::REFUSED(), msg.getRcode());
-    EXPECT_TRUE(msg.getHeaderFlag(MessageFlag::QR()));
-    EXPECT_FALSE(msg.getHeaderFlag(MessageFlag::AA()));
-    EXPECT_TRUE(msg.getHeaderFlag(MessageFlag::RD()));
+    EXPECT_TRUE(msg.getHeaderFlag(Message::HEADERFLAG_QR));
+    EXPECT_FALSE(msg.getHeaderFlag(Message::HEADERFLAG_AA));
+    EXPECT_TRUE(msg.getHeaderFlag(Message::HEADERFLAG_RD));
 }
 
 TEST_F(DataSrcTest, Wildcard) {
@@ -327,19 +321,18 @@
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 6, 6);
 
-    RRsetIterator rit = msg.beginSection(Section::ANSWER());
+    RRsetIterator rit = msg.beginSection(Message::SECTION_ANSWER);
     RRsetPtr rrset = *rit;
     EXPECT_EQ(Name("www.wild.example.com"), rrset->getName());
     EXPECT_EQ(RRType::A(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     RdataIteratorPtr it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("192.0.2.2", it->getCurrent().toText());
     it->next();
     EXPECT_TRUE(it->isLast());
 
-    rit = msg.beginSection(Section::AUTHORITY());
+    rit = msg.beginSection(Message::SECTION_AUTHORITY);
     rrset = *rit;
     EXPECT_EQ(Name("*.wild.example.com"), rrset->getName());
     EXPECT_EQ(RRType::NSEC(), rrset->getType());
@@ -353,7 +346,6 @@
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("dns01.example.com.", it->getCurrent().toText());
     it->next();
     EXPECT_EQ("dns02.example.com.", it->getCurrent().toText());
@@ -362,14 +354,13 @@
     it->next();
     EXPECT_TRUE(it->isLast());
 
-    rit = msg.beginSection(Section::ADDITIONAL());
+    rit = msg.beginSection(Message::SECTION_ADDITIONAL);
     rrset = *rit;
     EXPECT_EQ(Name("dns01.example.com"), rrset->getName());
     EXPECT_EQ(RRType::A(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("192.0.2.1", it->getCurrent().toText());
     it->next();
     EXPECT_TRUE(it->isLast());
@@ -399,14 +390,13 @@
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 6, 6);
 
-    RRsetIterator rit = msg.beginSection(Section::ANSWER());
+    RRsetIterator rit = msg.beginSection(Message::SECTION_ANSWER);
     RRsetPtr rrset = *rit;
     EXPECT_EQ(Name("www.wild2.example.com"), rrset->getName());
     EXPECT_EQ(RRType::CNAME(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     RdataIteratorPtr it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("www.example.com.", it->getCurrent().toText());
     it->next();
     EXPECT_TRUE(it->isLast());
@@ -419,12 +409,11 @@
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("192.0.2.1", it->getCurrent().toText());
     it->next();
     EXPECT_TRUE(it->isLast());
 
-    rit = msg.beginSection(Section::AUTHORITY());
+    rit = msg.beginSection(Message::SECTION_AUTHORITY);
     rrset = *rit;
     EXPECT_EQ(Name("*.wild2.example.com"), rrset->getName());
     EXPECT_EQ(RRType::NSEC(), rrset->getType());
@@ -438,7 +427,6 @@
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("dns01.example.com.", it->getCurrent().toText());
     it->next();
     EXPECT_EQ("dns02.example.com.", it->getCurrent().toText());
@@ -447,14 +435,13 @@
     it->next();
     EXPECT_TRUE(it->isLast());
 
-    rit = msg.beginSection(Section::ADDITIONAL());
+    rit = msg.beginSection(Message::SECTION_ADDITIONAL);
     rrset = *rit;
     EXPECT_EQ(Name("dns01.example.com"), rrset->getName());
     EXPECT_EQ(RRType::A(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("192.0.2.1", it->getCurrent().toText());
     it->next();
     EXPECT_TRUE(it->isLast());
@@ -467,19 +454,18 @@
                           RRType::AAAA());
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 4, 0);
 
-    RRsetIterator rit = msg.beginSection(Section::ANSWER());
+    RRsetIterator rit = msg.beginSection(Message::SECTION_ANSWER);
     RRsetPtr rrset = *rit;
     EXPECT_EQ(Name("www.wild2.example.com"), rrset->getName());
     EXPECT_EQ(RRType::CNAME(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     RdataIteratorPtr it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("www.example.com.", it->getCurrent().toText());
     it->next();
     EXPECT_TRUE(it->isLast());
 
-    rit = msg.beginSection(Section::AUTHORITY());
+    rit = msg.beginSection(Message::SECTION_AUTHORITY);
     rrset = *rit;
     EXPECT_EQ(Name("*.wild2.example.com"), rrset->getName());
     EXPECT_EQ(RRType::NSEC(), rrset->getType());
@@ -499,19 +485,18 @@
                           RRType::A());
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 6, 0);
 
-    RRsetIterator rit = msg.beginSection(Section::ANSWER());
+    RRsetIterator rit = msg.beginSection(Message::SECTION_ANSWER);
     RRsetPtr rrset = *rit;
     EXPECT_EQ(Name("www.wild3.example.com"), rrset->getName());
     EXPECT_EQ(RRType::CNAME(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     RdataIteratorPtr it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("spork.example.com.", it->getCurrent().toText());
     it->next();
     EXPECT_TRUE(it->isLast());
 
-    rit = msg.beginSection(Section::AUTHORITY());
+    rit = msg.beginSection(Message::SECTION_AUTHORITY);
     rrset = *rit;
     EXPECT_EQ(Name("*.wild3.example.com"), rrset->getName());
     EXPECT_EQ(RRType::NSEC(), rrset->getType());
@@ -537,26 +522,24 @@
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 4, 6);
 
-    RRsetIterator rit = msg.beginSection(Section::ANSWER());
+    RRsetIterator rit = msg.beginSection(Message::SECTION_ANSWER);
     RRsetPtr rrset = *rit;
     EXPECT_EQ(Name("www.sql1.example.com"), rrset->getName());
     EXPECT_EQ(RRType::A(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     RdataIteratorPtr it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("192.0.2.2", it->getCurrent().toText());
     it->next();
     EXPECT_TRUE(it->isLast());
 
-    rit = msg.beginSection(Section::AUTHORITY());
+    rit = msg.beginSection(Message::SECTION_AUTHORITY);
     rrset = *rit;
     EXPECT_EQ(Name("sql1.example.com"), rrset->getName());
     EXPECT_EQ(RRType::NS(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("dns01.example.com.", it->getCurrent().toText());
     it->next();
     EXPECT_EQ("dns02.example.com.", it->getCurrent().toText());
@@ -565,14 +548,13 @@
     it->next();
     EXPECT_TRUE(it->isLast());
 
-    rit = msg.beginSection(Section::ADDITIONAL());
+    rit = msg.beginSection(Message::SECTION_ADDITIONAL);
     rrset = *rit;
     EXPECT_EQ(Name("dns01.example.com"), rrset->getName());
     EXPECT_EQ(RRType::A(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("192.0.2.1", it->getCurrent().toText());
     it->next();
     EXPECT_TRUE(it->isLast());
@@ -584,28 +566,26 @@
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 5, 4, 6);
 
-    RRsetIterator rit = msg.beginSection(Section::ANSWER());
+    RRsetIterator rit = msg.beginSection(Message::SECTION_ANSWER);
     RRsetPtr rrset = *rit;
     EXPECT_EQ(Name("dname.example.com"), rrset->getName());
     EXPECT_EQ(RRType::DNAME(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     RdataIteratorPtr it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("sql1.example.com.", it->getCurrent().toText());
     it->next();
     EXPECT_TRUE(it->isLast());
 
     // XXX: check CNAME and A record too
 
-    rit = msg.beginSection(Section::AUTHORITY());
+    rit = msg.beginSection(Message::SECTION_AUTHORITY);
     rrset = *rit;
     EXPECT_EQ(Name("sql1.example.com"), rrset->getName());
     EXPECT_EQ(RRType::NS(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("dns01.example.com.", it->getCurrent().toText());
     it->next();
     EXPECT_EQ("dns02.example.com.", it->getCurrent().toText());
@@ -614,14 +594,13 @@
     it->next();
     EXPECT_TRUE(it->isLast());
 
-    rit = msg.beginSection(Section::ADDITIONAL());
+    rit = msg.beginSection(Message::SECTION_ADDITIONAL);
     rrset = *rit;
     EXPECT_EQ(Name("dns01.example.com"), rrset->getName());
     EXPECT_EQ(RRType::A(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("192.0.2.1", it->getCurrent().toText());
     it->next();
     EXPECT_TRUE(it->isLast());
@@ -642,14 +621,13 @@
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 0, 0);
 
-    RRsetIterator rit = msg.beginSection(Section::ANSWER());
+    RRsetIterator rit = msg.beginSection(Message::SECTION_ANSWER);
     RRsetPtr rrset = *rit;
     EXPECT_EQ(Name("foo.example.com"), rrset->getName());
     EXPECT_EQ(RRType::CNAME(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     RdataIteratorPtr it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("cnametest.flame.org.", it->getCurrent().toText());
     it->next();
     EXPECT_TRUE(it->isLast());
@@ -661,21 +639,20 @@
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 4, 6);
 
-    RRsetIterator rit = msg.beginSection(Section::ANSWER());
+    RRsetIterator rit = msg.beginSection(Message::SECTION_ANSWER);
     RRsetPtr rrset = *rit;
     EXPECT_EQ(Name("cname-int.example.com"), rrset->getName());
     EXPECT_EQ(RRType::CNAME(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     RdataIteratorPtr it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("www.example.com.", it->getCurrent().toText());
     it->next();
     EXPECT_TRUE(it->isLast());
 
     // XXX: check a record as well
 
-    rit = msg.beginSection(Section::AUTHORITY());
+    rit = msg.beginSection(Message::SECTION_AUTHORITY);
     rrset = *rit;
     EXPECT_EQ(Name("example.com"), rrset->getName());
     EXPECT_EQ(RRType::NS(), rrset->getType());
@@ -688,19 +665,18 @@
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 4, 6);
 
-    RRsetIterator rit = msg.beginSection(Section::ANSWER());
+    RRsetIterator rit = msg.beginSection(Message::SECTION_ANSWER);
     RRsetPtr rrset = *rit;
     EXPECT_EQ(Name("cname-ext.example.com"), rrset->getName());
     EXPECT_EQ(RRType::CNAME(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     RdataIteratorPtr it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("www.sql1.example.com.", it->getCurrent().toText());
     it->next();
     EXPECT_TRUE(it->isLast());
 
-    rit = msg.beginSection(Section::AUTHORITY());
+    rit = msg.beginSection(Message::SECTION_AUTHORITY);
     rrset = *rit;
     EXPECT_EQ(Name("sql1.example.com"), rrset->getName());
     EXPECT_EQ(RRType::NS(), rrset->getType());
@@ -713,26 +689,24 @@
 
     headerCheck(msg, Rcode::NOERROR(), true, false, true, 0, 5, 2);
 
-    RRsetIterator rit = msg.beginSection(Section::AUTHORITY());
+    RRsetIterator rit = msg.beginSection(Message::SECTION_AUTHORITY);
     RRsetPtr rrset = *rit;
     EXPECT_EQ(Name("subzone.example.com."), rrset->getName());
     EXPECT_EQ(RRType::NS(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     RdataIteratorPtr it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("ns1.subzone.example.com.", it->getCurrent().toText());
     it->next();
     EXPECT_FALSE(it->isLast());
 
-    rit = msg.beginSection(Section::ADDITIONAL());
+    rit = msg.beginSection(Message::SECTION_ADDITIONAL);
     rrset = *rit;
     EXPECT_EQ(Name("ns1.subzone.example.com"), rrset->getName());
     EXPECT_EQ(RRType::A(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("192.0.2.1", it->getCurrent().toText());
     it->next();
     EXPECT_TRUE(it->isLast());
@@ -744,26 +718,24 @@
 
     headerCheck(msg, Rcode::NOERROR(), true, false, true, 0, 5, 2);
 
-    RRsetIterator rit = msg.beginSection(Section::AUTHORITY());
+    RRsetIterator rit = msg.beginSection(Message::SECTION_AUTHORITY);
     RRsetPtr rrset = *rit;
     EXPECT_EQ(Name("subzone.example.com."), rrset->getName());
     EXPECT_EQ(RRType::NS(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     RdataIteratorPtr it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("ns1.subzone.example.com.", it->getCurrent().toText());
     it->next();
     EXPECT_FALSE(it->isLast());
 
-    rit = msg.beginSection(Section::ADDITIONAL());
+    rit = msg.beginSection(Message::SECTION_ADDITIONAL);
     rrset = *rit;
     EXPECT_EQ(Name("ns1.subzone.example.com"), rrset->getName());
     EXPECT_EQ(RRType::A(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("192.0.2.1", it->getCurrent().toText());
     it->next();
     EXPECT_TRUE(it->isLast());
@@ -782,20 +754,19 @@
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 4, 6);
 
-    RRsetIterator rit = msg.beginSection(Section::ANSWER());
+    RRsetIterator rit = msg.beginSection(Message::SECTION_ANSWER);
     RRsetPtr rrset = *rit;
     EXPECT_EQ(Name("subzone.example.com."), rrset->getName());
     EXPECT_EQ(RRType::NSEC(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
-    rit = msg.beginSection(Section::AUTHORITY());
-    rrset = *rit;
-    EXPECT_EQ(Name("example.com"), rrset->getName());
-    EXPECT_EQ(RRType::NS(), rrset->getType());
-    EXPECT_EQ(RRClass::IN(), rrset->getClass());
-
-    RdataIteratorPtr it = rrset->getRdataIterator();
-    it->first();
+    rit = msg.beginSection(Message::SECTION_AUTHORITY);
+    rrset = *rit;
+    EXPECT_EQ(Name("example.com"), rrset->getName());
+    EXPECT_EQ(RRType::NS(), rrset->getType());
+    EXPECT_EQ(RRClass::IN(), rrset->getClass());
+
+    RdataIteratorPtr it = rrset->getRdataIterator();
     EXPECT_EQ("dns01.example.com.", it->getCurrent().toText());
     it->next();
     EXPECT_EQ("dns02.example.com.", it->getCurrent().toText());
@@ -810,26 +781,24 @@
                           RRType::DNAME());
 
     headerCheck(msg, Rcode::NOERROR(), true, false, true, 0, 5, 2);
-    RRsetIterator rit = msg.beginSection(Section::AUTHORITY());
+    RRsetIterator rit = msg.beginSection(Message::SECTION_AUTHORITY);
     RRsetPtr rrset = *rit;
     EXPECT_EQ(Name("subzone.example.com."), rrset->getName());
     EXPECT_EQ(RRType::NS(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     RdataIteratorPtr it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("ns1.subzone.example.com.", it->getCurrent().toText());
     it->next();
     EXPECT_FALSE(it->isLast());
 
-    rit = msg.beginSection(Section::ADDITIONAL());
+    rit = msg.beginSection(Message::SECTION_ADDITIONAL);
     rrset = *rit;
     EXPECT_EQ(Name("ns1.subzone.example.com"), rrset->getName());
     EXPECT_EQ(RRType::A(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("192.0.2.1", it->getCurrent().toText());
     it->next();
     EXPECT_TRUE(it->isLast());
@@ -841,20 +810,19 @@
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 3, 4, 6);
 
-    RRsetIterator rit = msg.beginSection(Section::ANSWER());
+    RRsetIterator rit = msg.beginSection(Message::SECTION_ANSWER);
     RRsetPtr rrset = *rit;
     EXPECT_EQ(Name("subzone.example.com."), rrset->getName());
     EXPECT_EQ(RRType::DS(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
-    rit = msg.beginSection(Section::AUTHORITY());
-    rrset = *rit;
-    EXPECT_EQ(Name("example.com"), rrset->getName());
-    EXPECT_EQ(RRType::NS(), rrset->getType());
-    EXPECT_EQ(RRClass::IN(), rrset->getClass());
-
-    RdataIteratorPtr it = rrset->getRdataIterator();
-    it->first();
+    rit = msg.beginSection(Message::SECTION_AUTHORITY);
+    rrset = *rit;
+    EXPECT_EQ(Name("example.com"), rrset->getName());
+    EXPECT_EQ(RRType::NS(), rrset->getType());
+    EXPECT_EQ(RRClass::IN(), rrset->getClass());
+
+    RdataIteratorPtr it = rrset->getRdataIterator();
     EXPECT_EQ("dns01.example.com.", it->getCurrent().toText());
     it->next();
     EXPECT_EQ("dns02.example.com.", it->getCurrent().toText());
@@ -872,7 +840,7 @@
     // one.loop.example points to two.loop.example, which points back
     // to one.loop.example, so there should be exactly two CNAME records
     // in the answer.
-    EXPECT_EQ(2, msg.getRRCount(Section::ANSWER()));
+    EXPECT_EQ(2, msg.getRRCount(Message::SECTION_ANSWER));
 }
 
 // NSEC query for the name of a zone cut for non-secure delegation.
@@ -883,38 +851,56 @@
 
     headerCheck(msg, Rcode::NOERROR(), true, false, true, 0, 1, 1);
 
-    RRsetIterator rit = msg.beginSection(Section::AUTHORITY());
+    RRsetIterator rit = msg.beginSection(Message::SECTION_AUTHORITY);
     ConstRRsetPtr rrset = *rit;
     EXPECT_EQ(Name("sub.example.org."), rrset->getName());
     EXPECT_EQ(RRType::NS(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     RdataIteratorPtr it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ(createRdata(RRType::NS(), RRClass::IN(),
                           "ns.sub.example.org.")->toText(),
               it->getCurrent().toText());
     it->next();
     EXPECT_TRUE(it->isLast());
 
-    rit = msg.beginSection(Section::ADDITIONAL());
+    rit = msg.beginSection(Message::SECTION_ADDITIONAL);
     rrset = *rit;
     EXPECT_EQ(Name("ns.sub.example.org."), rrset->getName());
     EXPECT_EQ(RRType::A(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 
     it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ(createRdata(RRType::A(), RRClass::IN(), "192.0.2.101")->toText(),
               it->getCurrent().toText());
     it->next();
     EXPECT_TRUE(it->isLast());
 }
 
-TEST_F(DataSrcTest, RootDSQuery) {
+// Test sending a DS query to root (nonsense, but it should survive)
+TEST_F(DataSrcTest, RootDSQuery1) {
     EXPECT_NO_THROW(createAndProcessQuery(Name("."), RRClass::IN(),
                                           RRType::DS()));
     headerCheck(msg, Rcode::REFUSED(), true, false, true, 0, 0, 0);
+}
+
+// The same, but when we have the root zone
+// (which triggers rfc4035 section 3.1.4.1)
+TEST_F(DataSrcTest, RootDSQuery2) {
+    // The message
+    msg.makeResponse();
+    msg.setOpcode(Opcode::QUERY());
+    msg.addQuestion(Question(Name("."), RRClass::IN(), RRType::DS()));
+    msg.setHeaderFlag(Message::HEADERFLAG_RD);
+    // Prepare the source
+    DataSrcPtr sql3_source = DataSrcPtr(new Sqlite3DataSrc);
+    ConstElementPtr sqlite_root = Element::fromJSON(
+        "{ \"database_file\": \"" TEST_DATA_DIR "/test-root.sqlite3\"}");
+    EXPECT_NO_THROW(sql3_source->init(sqlite_root));
+    // Make the query
+    EXPECT_NO_THROW(performQuery(*sql3_source, cache, msg));
+
+    headerCheck(msg, Rcode::NOERROR(), true, true, true, 0, 1, 0);
 }
 
 TEST_F(DataSrcTest, DSQueryFromCache) {
@@ -942,7 +928,7 @@
     createAndProcessQuery(Name("www.version.bind"), RRClass::CH(),
                           RRType::TXT());
     headerCheck(msg, Rcode::NXDOMAIN(), true, true, true, 0, 1, 0);
-    RRsetIterator rit = msg.beginSection(Section::AUTHORITY());
+    RRsetIterator rit = msg.beginSection(Message::SECTION_AUTHORITY);
     RRsetPtr rrset = *rit;
     EXPECT_EQ(Name("version.bind"), rrset->getName());
     EXPECT_EQ(RRType::SOA(), rrset->getType());

Modified: branches/trac397focused/src/lib/datasrc/tests/query_unittest.cc
==============================================================================
--- branches/trac397focused/src/lib/datasrc/tests/query_unittest.cc (original)
+++ branches/trac397focused/src/lib/datasrc/tests/query_unittest.cc Mon Dec 20 08:19:35 2010
@@ -38,7 +38,7 @@
             const RRType& qtype)
 {
     m.setOpcode(Opcode::QUERY());
-    m.setHeaderFlag(MessageFlag::RD());
+    m.setHeaderFlag(Message::HEADERFLAG_RD);
     m.addQuestion(Question(qname, qclass, qtype));
 }
 

Modified: branches/trac397focused/src/lib/datasrc/tests/sqlite3_unittest.cc
==============================================================================
--- branches/trac397focused/src/lib/datasrc/tests/sqlite3_unittest.cc (original)
+++ branches/trac397focused/src/lib/datasrc/tests/sqlite3_unittest.cc Mon Dec 20 08:19:35 2010
@@ -244,7 +244,6 @@
     EXPECT_EQ(expected_rrttl, rrset->getTTL());
 
     RdataIteratorPtr rdata_iterator = rrset->getRdataIterator();
-    rdata_iterator->first();
     vector<string>::const_iterator data_it = expected_data.begin();
     for (; data_it != expected_data.end(); ++data_it) {
         EXPECT_FALSE(rdata_iterator->isLast());

Modified: branches/trac397focused/src/lib/datasrc/tests/static_unittest.cc
==============================================================================
--- branches/trac397focused/src/lib/datasrc/tests/static_unittest.cc (original)
+++ branches/trac397focused/src/lib/datasrc/tests/static_unittest.cc Mon Dec 20 08:19:35 2010
@@ -63,6 +63,7 @@
         authors_data.push_back("JINMEI Tatuya");
         authors_data.push_back("Kazunori Fujiwara");
         authors_data.push_back("Michael Graff");
+        authors_data.push_back("Michal Vaner");
         authors_data.push_back("Naoki Kambe");
         authors_data.push_back("Shane Kerr");
         authors_data.push_back("Shen Tingting");
@@ -109,7 +110,6 @@
     EXPECT_EQ(rrttl, rrset->getTTL());
 
     RdataIteratorPtr rdata_iterator = rrset->getRdataIterator();
-    rdata_iterator->first();
     vector<string>::const_iterator data_it = expected_data.begin();
     for (; data_it != expected_data.end(); ++data_it) {
         EXPECT_FALSE(rdata_iterator->isLast());

Modified: branches/trac397focused/src/lib/datasrc/tests/test_datasrc.cc
==============================================================================
--- branches/trac397focused/src/lib/datasrc/tests/test_datasrc.cc (original)
+++ branches/trac397focused/src/lib/datasrc/tests/test_datasrc.cc Mon Dec 20 08:19:35 2010
@@ -307,7 +307,7 @@
 }
 
 DataSrc::Result
-TestDataSrc::init(isc::data::ConstElementPtr config UNUSED_PARAM) {
+TestDataSrc::init(isc::data::ConstElementPtr) {
     return (init());
 }
 
@@ -408,7 +408,7 @@
     RRsetPtr rrset = RRsetPtr(new RRset(source->getName(), source->getClass(),
                                         source->getType(), source->getTTL()));
     RdataIteratorPtr it = source->getRdataIterator();
-    for (it->first(); !it->isLast(); it->next()) {
+    for (; !it->isLast(); it->next()) {
         rrset->addRdata(it->getCurrent());
     }
     if (source->getRRsig()) {
@@ -623,10 +623,7 @@
 }
 
 DataSrc::Result
-TestDataSrc::findCoveringNSEC3(const Name& zonename UNUSED_PARAM,
-                               string& hash UNUSED_PARAM,
-                               RRsetList& target UNUSED_PARAM) const
-{
+TestDataSrc::findCoveringNSEC3(const Name&, string&, RRsetList&) const {
     return (NOT_IMPLEMENTED);
 }
 

Modified: branches/trac397focused/src/lib/dns/Makefile.am
==============================================================================
--- branches/trac397focused/src/lib/dns/Makefile.am (original)
+++ branches/trac397focused/src/lib/dns/Makefile.am Mon Dec 20 08:19:35 2010
@@ -1,6 +1,7 @@
 SUBDIRS = . tests python
 
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
 AM_CXXFLAGS = $(B10_CXXFLAGS)
 
 CLEANFILES = *.gcno *.gcda
@@ -12,6 +13,8 @@
 
 # TODO: double-check that this is the only way
 # NOTE: when an rdata file is added, please also add to this list:
+EXTRA_DIST += rdata/any_255/tsig_250.cc
+EXTRA_DIST += rdata/any_255/tsig_250.h
 EXTRA_DIST += rdata/in_1/aaaa_28.cc
 EXTRA_DIST += rdata/in_1/aaaa_28.h
 EXTRA_DIST += rdata/in_1/a_1.cc
@@ -66,6 +69,7 @@
 libdns___la_SOURCES += edns.h edns.cc
 libdns___la_SOURCES += exceptions.h exceptions.cc
 libdns___la_SOURCES += util/hex.h
+libdns___la_SOURCES += masterload.h masterload.cc
 libdns___la_SOURCES += message.h message.cc
 libdns___la_SOURCES += messagerenderer.h messagerenderer.cc
 libdns___la_SOURCES += name.h name.cc
@@ -80,7 +84,7 @@
 libdns___la_SOURCES += rrtype.cc
 libdns___la_SOURCES += question.h question.cc
 libdns___la_SOURCES += util/sha1.h util/sha1.cc
-libdns___la_SOURCES += tsig.h tsig.cc
+libdns___la_SOURCES += tsigkey.h tsigkey.cc
 
 nodist_libdns___la_SOURCES = rdataclass.cc rrclass.h rrtype.h
 nodist_libdns___la_SOURCES += rrparamregistry.cc
@@ -95,11 +99,13 @@
 libdns___include_HEADERS = \
 	buffer.h \
 	dnssectime.h \
+	edns.h \
 	exceptions.h \
 	message.h \
 	messagerenderer.h \
 	name.h \
 	question.h \
+	rcode.h \
 	rdata.h \
 	rdataclass.h \
 	rrclass.h \
@@ -108,7 +114,7 @@
 	rrsetlist.h \
 	rrttl.h \
 	rrtype.h \
-	tsig.h
+	tsigkey.h
 # Purposely not installing these headers:
 # util/*.h: used only internally, and not actually DNS specific
 # rrclass-placeholder.h

Modified: branches/trac397focused/src/lib/dns/edns.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/edns.cc (original)
+++ branches/trac397focused/src/lib/dns/edns.cc Mon Dec 20 08:19:35 2010
@@ -74,7 +74,7 @@
 }
 
 EDNS::EDNS(const Name& name, const RRClass& rrclass, const RRType& rrtype,
-           const RRTTL& ttl, const Rdata& rdata UNUSED_PARAM) :
+           const RRTTL& ttl, const Rdata&) :
     version_((ttl.getValue() & VERSION_MASK) >> VERSION_SHIFT)
 {
     if (rrtype != RRType::OPT()) {
@@ -152,7 +152,7 @@
 EDNS*
 createEDNSFromRR(const Name& name, const RRClass& rrclass,
                  const RRType& rrtype, const RRTTL& ttl,
-                 const Rdata& rdata UNUSED_PARAM,
+                 const Rdata& rdata,
                  uint8_t& extended_rcode)
 {
     // Create a new EDNS object first for exception guarantee.

Modified: branches/trac397focused/src/lib/dns/message.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/message.cc (original)
+++ branches/trac397focused/src/lib/dns/message.cc Mon Dec 20 08:19:35 2010
@@ -44,32 +44,42 @@
 
 using namespace std;
 using namespace boost;
-using namespace isc::dns;
 using namespace isc::dns::rdata;
 
 namespace isc {
 namespace dns {
 
 namespace {
-typedef uint16_t flags_t;
-
 // protocol constants
 const size_t HEADERLEN = 12;
-
-const flags_t FLAG_QR = 0x8000;
-const flags_t FLAG_AA = 0x0400;
-const flags_t FLAG_TC = 0x0200;
-const flags_t FLAG_RD = 0x0100;
-const flags_t FLAG_RA = 0x0080;
-const flags_t FLAG_AD = 0x0020;
-const flags_t FLAG_CD = 0x0010;
 
 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);
+
+// This diagram shows the wire-format representation of the 2nd 16 bits of
+// the DNS header section, which contain all defined flag bits.
+//
+//    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+//    |QR|   Opcode  |AA|TC|RD|RA|  |AD|CD|   RCODE   |
+//    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+//      1  0  0  0| 0  1  1  1| 1  0  1  1| 0  0  0  0|
+//         0x8         0x7         0xb         0x0
+//
+// This mask covers all the flag bits, and those bits only.
+// Note: we reject a "flag" the is not covered by this mask in some of the
+// public methods.  This means our current definition is not fully extendable;
+// applications cannot introduce a new flag bit temporarily without modifying
+// the source code.
+const unsigned int HEADERFLAG_MASK = 0x87b0;
+
+// This is a set of flag bits that should be preserved when building a reply
+// from a request.
+// Note: we assume the specific definition of HEADERFLAG_xx.  We may change
+// the definition in future, in which case we need to adjust this definition,
+// too (see also the description about the Message::HeaderFlag type).
+const uint16_t MESSAGE_REPLYPRESERVE = (Message::HEADERFLAG_RD |
+                                        Message::HEADERFLAG_CD);
 
 const char *sectiontext[] = {
     "QUESTION",
@@ -77,15 +87,6 @@
     "AUTHORITY",
     "ADDITIONAL"
 };
-}
-
-namespace {
-inline unsigned int
-sectionCodeToId(const Section& section) {
-    unsigned int code = section.getCode();
-    assert(code > 0);
-    return (section.getCode() - 1);
-}
 }
 
 class MessageImpl {
@@ -105,13 +106,13 @@
     const Opcode* opcode_;
     Opcode opcode_placeholder_;
 
-    flags_t flags_;
+    uint16_t flags_;            // wire-format representation of header flags.
 
     bool header_parsed_;
-    static const unsigned int SECTION_MAX = 4; // TODO: revisit this design
-    int counts_[SECTION_MAX];   // TODO: revisit this definition
+    static const unsigned int NUM_SECTIONS = 4; // TODO: revisit this design
+    int counts_[NUM_SECTIONS];   // TODO: revisit this definition
     vector<QuestionPtr> questions_;
-    vector<RRsetPtr> rrsets_[SECTION_MAX];
+    vector<RRsetPtr> rrsets_[NUM_SECTIONS];
     ConstEDNSPtr edns_;
 
 #ifdef notyet
@@ -123,7 +124,7 @@
     void setOpcode(const Opcode& opcode);
     void setRcode(const Rcode& rcode);
     int parseQuestion(InputBuffer& buffer);
-    int parseSection(const Section& section, InputBuffer& buffer);
+    int parseSection(const Message::Section section, InputBuffer& buffer);
 };
 
 MessageImpl::MessageImpl(Message::Mode mode) :
@@ -142,15 +143,15 @@
     opcode_ = NULL;
     edns_ = EDNSPtr();
 
-    for (int i = 0; i < SECTION_MAX; ++i) {
+    for (int i = 0; i < NUM_SECTIONS; ++i) {
         counts_[i] = 0;
     }
 
     header_parsed_ = false;
     questions_.clear();
-    rrsets_[sectionCodeToId(Section::ANSWER())].clear();
-    rrsets_[sectionCodeToId(Section::AUTHORITY())].clear();
-    rrsets_[sectionCodeToId(Section::ADDITIONAL())].clear();
+    rrsets_[Message::SECTION_ANSWER].clear();
+    rrsets_[Message::SECTION_AUTHORITY].clear();
+    rrsets_[Message::SECTION_ADDITIONAL].clear();
 }
 
 void
@@ -174,26 +175,31 @@
 }
 
 bool
-Message::getHeaderFlag(const MessageFlag& flag) const {
-    return ((impl_->flags_ & flag.getBit()) != 0);
-}
-
-void
-Message::setHeaderFlag(const MessageFlag& flag) {
+Message::getHeaderFlag(const HeaderFlag flag) const {
+    if (flag == 0 || (flag & ~HEADERFLAG_MASK) != 0) {
+        isc_throw(InvalidParameter,
+                  "Message::getHeaderFlag:: Invalid flag is specified: " <<
+                  flag);
+    }
+    return ((impl_->flags_ & flag) != 0);
+}
+
+void
+Message::setHeaderFlag(const HeaderFlag flag, const bool on) {
     if (impl_->mode_ != Message::RENDER) {
         isc_throw(InvalidMessageOperation,
                   "setHeaderFlag performed in non-render mode");
     }
-    impl_->flags_ |= flag.getBit();
-}
-
-void
-Message::clearHeaderFlag(const MessageFlag& flag) {
-    if (impl_->mode_ != Message::RENDER) {
-        isc_throw(InvalidMessageOperation,
-                  "clearHeaderFlag performed in non-render mode");
-    }
-    impl_->flags_ &= ~flag.getBit();
+    if (flag == 0 || (flag & ~HEADERFLAG_MASK) != 0) {
+        isc_throw(InvalidParameter,
+                  "Message::getHeaderFlag:: Invalid flag is specified: " <<
+                  flag);
+    }
+    if (on) {
+        impl_->flags_ |= flag;
+    } else {
+        impl_->flags_ &= ~flag;
+    }
 }
 
 qid_t
@@ -259,35 +265,46 @@
 }
 
 unsigned int
-Message::getRRCount(const Section& section) const {
-    return (impl_->counts_[section.getCode()]);
-}
-
-void
-Message::addRRset(const Section& section, RRsetPtr rrset, const bool sign) {
+Message::getRRCount(const Section section) const {
+    if (section >= MessageImpl::NUM_SECTIONS) {
+        isc_throw(OutOfRange, "Invalid message section: " << section);
+    }
+    return (impl_->counts_[section]);
+}
+
+void
+Message::addRRset(const Section section, RRsetPtr rrset, const bool sign) {
     if (impl_->mode_ != Message::RENDER) {
         isc_throw(InvalidMessageOperation,
                   "addRRset performed in non-render mode");
     }
-
-    impl_->rrsets_[sectionCodeToId(section)].push_back(rrset);
-    impl_->counts_[section.getCode()] += rrset->getRdataCount();
+    if (section >= MessageImpl::NUM_SECTIONS) {
+        isc_throw(OutOfRange, "Invalid message section: " << section);
+    }
+
+    impl_->rrsets_[section].push_back(rrset);
+    impl_->counts_[section] += rrset->getRdataCount();
 
     RRsetPtr sp = rrset->getRRsig();
     if (sign && sp != NULL) {
-        impl_->rrsets_[sectionCodeToId(section)].push_back(sp);
-        impl_->counts_[section.getCode()] += sp->getRdataCount();
+        impl_->rrsets_[section].push_back(sp);
+        impl_->counts_[section] += sp->getRdataCount();
     }
 }
 
 bool
-Message::hasRRset(const Section& section, RRsetPtr rrset) {
-    BOOST_FOREACH(RRsetPtr r, impl_->rrsets_[sectionCodeToId(section)]) {
-        if (r->getType() == rrset->getType() &&
-            r->getName() == rrset->getName())
-        {
+Message::hasRRset(const Section section, const Name& name,
+                  const RRClass& rrclass, const RRType& rrtype)
+{
+    if (section >= MessageImpl::NUM_SECTIONS) {
+        isc_throw(OutOfRange, "Invalid message section: " << section);
+    }
+
+    BOOST_FOREACH(ConstRRsetPtr r, impl_->rrsets_[section]) {
+        if (r->getClass() == rrclass &&
+            r->getType() == rrtype &&
+            r->getName() == name) {
             return (true);
-
         }
     }
 
@@ -302,7 +319,7 @@
     }
 
     impl_->questions_.push_back(question);
-    ++impl_->counts_[Section::QUESTION().getCode()];
+    ++impl_->counts_[SECTION_QUESTION];
 }
 
 void
@@ -366,24 +383,24 @@
     uint16_t ancount = 0;
     if (!renderer.isTruncated()) {
         ancount =
-            for_each(impl_->rrsets_[sectionCodeToId(Section::ANSWER())].begin(),
-                     impl_->rrsets_[sectionCodeToId(Section::ANSWER())].end(),
+            for_each(impl_->rrsets_[SECTION_ANSWER].begin(),
+                     impl_->rrsets_[SECTION_ANSWER].end(),
                      RenderSection<RRsetPtr>(renderer, true)).getTotalCount();
     }
     uint16_t nscount = 0;
     if (!renderer.isTruncated()) {
         nscount =
-            for_each(impl_->rrsets_[sectionCodeToId(Section::AUTHORITY())].begin(),
-                     impl_->rrsets_[sectionCodeToId(Section::AUTHORITY())].end(),
+            for_each(impl_->rrsets_[SECTION_AUTHORITY].begin(),
+                     impl_->rrsets_[SECTION_AUTHORITY].end(),
                      RenderSection<RRsetPtr>(renderer, true)).getTotalCount();
     }
     uint16_t arcount = 0;
     if (renderer.isTruncated()) {
-        setHeaderFlag(MessageFlag::TC());
+        setHeaderFlag(HEADERFLAG_TC, true);
     } else {
         arcount =
-            for_each(impl_->rrsets_[sectionCodeToId(Section::ADDITIONAL())].begin(),
-                     impl_->rrsets_[sectionCodeToId(Section::ADDITIONAL())].end(),
+            for_each(impl_->rrsets_[SECTION_ADDITIONAL].begin(),
+                     impl_->rrsets_[SECTION_ADDITIONAL].end(),
                      RenderSection<RRsetPtr>(renderer, false)).getTotalCount();
     }
 
@@ -406,10 +423,10 @@
     // in rrsets_[] or questions_ if truncation occurred or an EDNS OPT RR
     // was inserted.  This is not good, and we should revisit the entire
     // design.
-    impl_->counts_[Section::QUESTION().getCode()] = qdcount;
-    impl_->counts_[Section::ANSWER().getCode()] = ancount;
-    impl_->counts_[Section::AUTHORITY().getCode()] = nscount;
-    impl_->counts_[Section::ADDITIONAL().getCode()] = arcount;
+    impl_->counts_[SECTION_QUESTION] = qdcount;
+    impl_->counts_[SECTION_ANSWER] = ancount;
+    impl_->counts_[SECTION_AUTHORITY] = nscount;
+    impl_->counts_[SECTION_ADDITIONAL] = arcount;
 
     // TBD: TSIG, SIG(0) etc.
 
@@ -421,7 +438,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_->flags_ & FLAG_MASK);
+    codes_and_flags |= (impl_->flags_ & HEADERFLAG_MASK);
     renderer.writeUint16At(codes_and_flags, header_pos);
     header_pos += sizeof(uint16_t);
     // XXX: should avoid repeated pattern (TODO)
@@ -451,11 +468,11 @@
     const uint16_t codes_and_flags = buffer.readUint16();
     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();
-    impl_->counts_[Section::AUTHORITY().getCode()] = buffer.readUint16();
-    impl_->counts_[Section::ADDITIONAL().getCode()] = buffer.readUint16();
+    impl_->flags_ = (codes_and_flags & HEADERFLAG_MASK);
+    impl_->counts_[SECTION_QUESTION] = buffer.readUint16();
+    impl_->counts_[SECTION_ANSWER] = buffer.readUint16();
+    impl_->counts_[SECTION_AUTHORITY] = buffer.readUint16();
+    impl_->counts_[SECTION_ADDITIONAL] = buffer.readUint16();
 
     impl_->header_parsed_ = true;
 }
@@ -471,14 +488,13 @@
         parseHeader(buffer);
     }
 
-    impl_->counts_[Section::QUESTION().getCode()] =
-        impl_->parseQuestion(buffer);
-    impl_->counts_[Section::ANSWER().getCode()] =
-        impl_->parseSection(Section::ANSWER(), buffer);
-    impl_->counts_[Section::AUTHORITY().getCode()] =
-        impl_->parseSection(Section::AUTHORITY(), buffer);
-    impl_->counts_[Section::ADDITIONAL().getCode()] =
-        impl_->parseSection(Section::ADDITIONAL(), buffer);
+    impl_->counts_[SECTION_QUESTION] = impl_->parseQuestion(buffer);
+    impl_->counts_[SECTION_ANSWER] =
+        impl_->parseSection(SECTION_ANSWER, buffer);
+    impl_->counts_[SECTION_AUTHORITY] =
+        impl_->parseSection(SECTION_AUTHORITY, buffer);
+    impl_->counts_[SECTION_ADDITIONAL] =
+        impl_->parseSection(SECTION_ADDITIONAL, buffer);
 }
 
 int
@@ -486,7 +502,7 @@
     unsigned int added = 0;
 
     for (unsigned int count = 0;
-         count < counts_[Section::QUESTION().getCode()];
+         count < counts_[Message::SECTION_QUESTION];
          ++count) {
         const Name name(buffer);
 
@@ -498,9 +514,9 @@
         const RRType rrtype(buffer.readUint16());
         const RRClass rrclass(buffer.readUint16());
 
-        // XXX: need a duplicate check.  We might also want to have an optimized
-        // algorithm that requires the question section contain exactly one
-        // RR.
+        // XXX: need a duplicate check.  We might also want to have an
+        // optimized algorithm that requires the question section contain
+        // exactly one RR.
 
         questions_.push_back(QuestionPtr(new Question(name, rrclass, rrtype)));
         ++added;
@@ -553,16 +569,20 @@
 // logic to that class; processing logic dependent on parse context
 // is hardcoded here.
 int
-MessageImpl::parseSection(const Section& section, InputBuffer& buffer) {
+MessageImpl::parseSection(const Message::Section section,
+                          InputBuffer& buffer)
+{
+    assert(section < MessageImpl::NUM_SECTIONS);
+
     unsigned int added = 0;
 
-    for (unsigned int count = 0; count < counts_[section.getCode()]; ++count) {
+    for (unsigned int count = 0; count < counts_[section]; ++count) {
         const Name name(buffer);
 
         // buffer must store at least RR TYPE, RR CLASS, TTL, and RDLEN.
         if ((buffer.getLength() - buffer.getPosition()) <
             3 * sizeof(uint16_t) + sizeof(uint32_t)) {
-            isc_throw(DNSMessageFORMERR, sectiontext[section.getCode()] <<
+            isc_throw(DNSMessageFORMERR, sectiontext[section] <<
                       " section too short: " <<
                       (buffer.getLength() - buffer.getPosition()) << " bytes");
         }
@@ -574,7 +594,7 @@
         ConstRdataPtr rdata = createRdata(rrtype, rrclass, buffer, rdlen);
 
         if (rrtype == RRType::OPT()) {
-            if (section != Section::ADDITIONAL()) {
+            if (section != Message::SECTION_ADDITIONAL) {
                 isc_throw(DNSMessageFORMERR,
                           "EDNS OPT RR found in an invalid section");
             }
@@ -589,17 +609,16 @@
             continue;
         } else {
             vector<RRsetPtr>::iterator it =
-                find_if(rrsets_[sectionCodeToId(section)].begin(),
-                        rrsets_[sectionCodeToId(section)].end(),
+                find_if(rrsets_[section].begin(), rrsets_[section].end(),
                         MatchRR(name, rrtype, rrclass));
-            if (it != rrsets_[sectionCodeToId(section)].end()) {
+            if (it != rrsets_[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);
+                rrsets_[section].push_back(rrset);
             }
             ++added;
         }
@@ -611,15 +630,15 @@
 namespace {
 template <typename T>
 struct SectionFormatter {
-    SectionFormatter(const Section& section, string& output) :
+    SectionFormatter(const Message::Section section, string& output) :
         section_(section), output_(output) {}
     void operator()(const T& entry) {
-        if (section_ == Section::QUESTION()) {
+        if (section_ == Message::SECTION_QUESTION) {
             output_ += ";";
         }
         output_ += entry->toText();
     }
-    const Section& section_;
+    const Message::Section section_;
     string& output_;
 };
 }
@@ -642,30 +661,37 @@
     s += ", status: " + impl_->rcode_->toText();
     s += ", id: " + boost::lexical_cast<string>(impl_->qid_);
     s += "\n;; flags: ";
-    if (getHeaderFlag(MessageFlag::QR()))
+    if (getHeaderFlag(HEADERFLAG_QR)) {
         s += "qr ";
-    if (getHeaderFlag(MessageFlag::AA()))
+    }
+    if (getHeaderFlag(HEADERFLAG_AA)) {
         s += "aa ";
-    if (getHeaderFlag(MessageFlag::TC()))
+    }
+    if (getHeaderFlag(HEADERFLAG_TC)) {
         s += "tc ";
-    if (getHeaderFlag(MessageFlag::RD()))
+    }
+    if (getHeaderFlag(HEADERFLAG_RD)) {
         s += "rd ";
-    if (getHeaderFlag(MessageFlag::RA()))
+    }
+    if (getHeaderFlag(HEADERFLAG_RA)) {
         s += "ra ";
-    if (getHeaderFlag(MessageFlag::AD()))
+    }
+    if (getHeaderFlag(HEADERFLAG_AD)) {
         s += "ad ";
-    if (getHeaderFlag(MessageFlag::CD()))
+    }
+    if (getHeaderFlag(HEADERFLAG_CD)) {
         s += "cd ";
+    }
 
     // for simplicity, don't consider the update case for now
     s += "; QUESTION: " +
-        lexical_cast<string>(impl_->counts_[Section::QUESTION().getCode()]);
+        lexical_cast<string>(impl_->counts_[SECTION_QUESTION]);
     s += ", ANSWER: " +
-        lexical_cast<string>(impl_->counts_[Section::ANSWER().getCode()]);
+        lexical_cast<string>(impl_->counts_[SECTION_ANSWER]);
     s += ", AUTHORITY: " +
-        lexical_cast<string>(impl_->counts_[Section::AUTHORITY().getCode()]);
-
-    unsigned int arcount = impl_->counts_[Section::ADDITIONAL().getCode()];
+        lexical_cast<string>(impl_->counts_[SECTION_AUTHORITY]);
+
+    unsigned int arcount = impl_->counts_[SECTION_ADDITIONAL];
     if (impl_->edns_ != NULL) {
         ++arcount;
     }
@@ -678,31 +704,31 @@
 
     if (!impl_->questions_.empty()) {
         s += "\n;; " +
-            string(sectiontext[Section::QUESTION().getCode()]) + " SECTION:\n";
+            string(sectiontext[SECTION_QUESTION]) + " SECTION:\n";
         for_each(impl_->questions_.begin(), impl_->questions_.end(),
-                 SectionFormatter<QuestionPtr>(Section::QUESTION(), s));
-    }
-    if (!impl_->rrsets_[sectionCodeToId(Section::ANSWER())].empty()) {
+                 SectionFormatter<QuestionPtr>(SECTION_QUESTION, s));
+    }
+    if (!impl_->rrsets_[SECTION_ANSWER].empty()) {
         s += "\n;; " +
-            string(sectiontext[Section::ANSWER().getCode()]) + " SECTION:\n";
-        for_each(impl_->rrsets_[sectionCodeToId(Section::ANSWER())].begin(),
-                 impl_->rrsets_[sectionCodeToId(Section::ANSWER())].end(),
-                 SectionFormatter<RRsetPtr>(Section::ANSWER(), s));
-    }
-    if (!impl_->rrsets_[sectionCodeToId(Section::AUTHORITY())].empty()) {
+            string(sectiontext[SECTION_ANSWER]) + " SECTION:\n";
+        for_each(impl_->rrsets_[SECTION_ANSWER].begin(),
+                 impl_->rrsets_[SECTION_ANSWER].end(),
+                 SectionFormatter<RRsetPtr>(SECTION_ANSWER, s));
+    }
+    if (!impl_->rrsets_[SECTION_AUTHORITY].empty()) {
         s += "\n;; " +
-            string(sectiontext[Section::AUTHORITY().getCode()]) + " SECTION:\n";
-        for_each(impl_->rrsets_[sectionCodeToId(Section::AUTHORITY())].begin(),
-                 impl_->rrsets_[sectionCodeToId(Section::AUTHORITY())].end(),
-                 SectionFormatter<RRsetPtr>(Section::AUTHORITY(), s));
-    }
-    if (!impl_->rrsets_[sectionCodeToId(Section::ADDITIONAL())].empty()) {
+            string(sectiontext[SECTION_AUTHORITY]) + " SECTION:\n";
+        for_each(impl_->rrsets_[SECTION_AUTHORITY].begin(),
+                 impl_->rrsets_[SECTION_AUTHORITY].end(),
+                 SectionFormatter<RRsetPtr>(SECTION_AUTHORITY, s));
+    }
+    if (!impl_->rrsets_[SECTION_ADDITIONAL].empty()) {
         s += "\n;; " +
-            string(sectiontext[Section::ADDITIONAL().getCode()]) +
+            string(sectiontext[SECTION_ADDITIONAL]) +
             " SECTION:\n";
-        for_each(impl_->rrsets_[sectionCodeToId(Section::ADDITIONAL())].begin(),
-                 impl_->rrsets_[sectionCodeToId(Section::ADDITIONAL())].end(),
-                 SectionFormatter<RRsetPtr>(Section::ADDITIONAL(), s));
+        for_each(impl_->rrsets_[SECTION_ADDITIONAL].begin(),
+                 impl_->rrsets_[SECTION_ADDITIONAL].end(),
+                 SectionFormatter<RRsetPtr>(SECTION_ADDITIONAL, s));
     }
 
     return (s);
@@ -725,14 +751,14 @@
 
     impl_->edns_ = EDNSPtr();
     impl_->flags_ &= MESSAGE_REPLYPRESERVE;
-    setHeaderFlag(MessageFlag::QR());
-
-    impl_->rrsets_[sectionCodeToId(Section::ANSWER())].clear();
-    impl_->counts_[Section::ANSWER().getCode()] = 0;
-    impl_->rrsets_[sectionCodeToId(Section::AUTHORITY())].clear();
-    impl_->counts_[Section::AUTHORITY().getCode()] = 0;
-    impl_->rrsets_[sectionCodeToId(Section::ADDITIONAL())].clear();
-    impl_->counts_[Section::ADDITIONAL().getCode()] = 0;
+    setHeaderFlag(HEADERFLAG_QR, true);
+
+    impl_->rrsets_[SECTION_ANSWER].clear();
+    impl_->counts_[SECTION_ANSWER] = 0;
+    impl_->rrsets_[SECTION_AUTHORITY].clear();
+    impl_->counts_[SECTION_AUTHORITY] = 0;
+    impl_->rrsets_[SECTION_ADDITIONAL].clear();
+    impl_->counts_[SECTION_ADDITIONAL] = 0;
 }
 
 ///
@@ -840,33 +866,34 @@
 /// RRsets iterators
 ///
 const SectionIterator<RRsetPtr>
-Message::beginSection(const Section& section) const {
-    if (section == Section::QUESTION()) {
+Message::beginSection(const Section section) const {
+    if (section >= MessageImpl::NUM_SECTIONS) {
+        isc_throw(OutOfRange, "Invalid message section: " << section);
+    }
+    if (section == SECTION_QUESTION) {
         isc_throw(InvalidMessageSection,
                   "RRset iterator is requested for question");
     }
 
-    return (RRsetIterator(
-                RRsetIteratorImpl(
-                    impl_->rrsets_[sectionCodeToId(section)].begin())));
+    return (RRsetIterator(RRsetIteratorImpl(impl_->rrsets_[section].begin())));
 }
 
 const SectionIterator<RRsetPtr>
-Message::endSection(const Section& section) const {
-    if (section == Section::QUESTION()) {
+Message::endSection(const Section section) const {
+    if (section >= MessageImpl::NUM_SECTIONS) {
+        isc_throw(OutOfRange, "Invalid message section: " << section);
+    }
+    if (section == SECTION_QUESTION) {
         isc_throw(InvalidMessageSection,
                   "RRset iterator is requested for question");
     }
 
-    return (RRsetIterator(
-                RRsetIteratorImpl(
-                    impl_->rrsets_[sectionCodeToId(section)].end())));
+    return (RRsetIterator(RRsetIteratorImpl(impl_->rrsets_[section].end())));
 }
 
 ostream&
 operator<<(ostream& os, const Message& message) {
     return (os << message.toText());
 }
-
 } // end of namespace dns
 } // end of namespace isc

Modified: branches/trac397focused/src/lib/dns/message.h
==============================================================================
--- branches/trac397focused/src/lib/dns/message.h (original)
+++ branches/trac397focused/src/lib/dns/message.h Mon Dec 20 08:19:35 2010
@@ -87,133 +87,6 @@
 
 template <typename T>
 struct SectionIteratorImpl;
-
-/// \brief The \c MessageFlag class objects represent standard flag bits
-/// of the header section of DNS messages.
-///
-/// Constant objects are defined for standard flags.
-class MessageFlag {
-public:
-    /// \brief Returns the corresponding bit of the MessageFlag.
-    ///
-    /// Note: this value is intended to be used for rendering or parsing
-    /// low level wire-format data.  Applications should use abstract
-    /// interfaces.  This also means the interface is not well sophisticated,
-    /// and we should revisit the design.
-    uint16_t getBit() const { return (flagbit_); }
-    static const MessageFlag& QR();
-    static const MessageFlag& AA();
-    static const MessageFlag& TC();
-    static const MessageFlag& RD();
-    static const MessageFlag& RA();
-    static const MessageFlag& AD();
-    static const MessageFlag& CD();
-private:
-    MessageFlag(uint16_t flagbit) : flagbit_(flagbit) {}
-    uint16_t flagbit_;
-};
-
-inline const MessageFlag&
-MessageFlag::QR() {
-    static MessageFlag f(0x8000);
-    return (f);
-}
-
-inline const MessageFlag&
-MessageFlag::AA() {
-    static MessageFlag f(0x0400);
-    return (f);
-}
-
-inline const MessageFlag&
-MessageFlag::TC() {
-    static MessageFlag f(0x0200);
-    return (f);
-}
-
-inline const MessageFlag&
-MessageFlag::RD() {
-    static MessageFlag f(0x0100);
-    return (f);
-}
-
-inline const MessageFlag&
-MessageFlag::RA() {
-    static MessageFlag f(0x0080);
-    return (f);
-}
-
-inline const MessageFlag&
-MessageFlag::AD() {
-    static MessageFlag f(0x0020);
-    return (f);
-}
-
-inline const MessageFlag&
-MessageFlag::CD() {
-    static MessageFlag f(0x0010);
-    return (f);
-}
-
-/// \brief The \c Section class objects represent DNS message sections such
-/// as the header, question, or answer.
-///
-/// Note: this class doesn't seem to be very useful.  We should probably
-/// revisit this design.
-///
-/// Note: whether or not it's represented as a class, we'll need a way
-/// to represent more advanced sections such as those used in dynamic updates.
-/// This is a TODO item.
-///
-/// Constant objects are defined for standard flags.
-class Section {
-public:
-    /// \brief Returns the relative position of the \c Section in DNS messages.
-    unsigned int getCode() const { return (code_); }
-    bool operator==(const Section& other) const
-        { return (code_ == other.code_); }
-    bool operator!=(const Section& other) const
-        { return (code_ != other.code_); }
-
-    static const Section& QUESTION();
-    static const Section& ANSWER();
-    static const Section& AUTHORITY();
-    static const Section& ADDITIONAL();
-private:
-    enum {
-        SECTION_QUESTION = 0,
-        SECTION_ANSWER = 1,
-        SECTION_AUTHORITY = 2,
-        SECTION_ADDITIONAL = 3
-    };
-
-    Section(int code) : code_(code) {}
-    unsigned int code_;
-};
-
-inline const Section&
-Section::QUESTION() {
-    static Section s(SECTION_QUESTION);
-    return (s);
-}
-
-inline const Section&
-Section::ANSWER() {
-    static Section s(SECTION_ANSWER);
-    return (s);
-}
-
-inline const Section&
-Section::AUTHORITY() {
-    static Section s(SECTION_AUTHORITY);
-    return (s);
-}
-
-inline const Section&
-Section::ADDITIONAL() {
-    static Section s(SECTION_ADDITIONAL);
-    return (s);
-}
 
 /// \c SectionIterator is a templated class to provide standard-compatible
 /// iterators for Questions and RRsets for a given DNS message section.
@@ -274,19 +147,109 @@
 ///   of RR in the message.
 class Message {
 public:
+    /// Constants to specify the operation mode of the \c Message.
     enum Mode {
-        PARSE = 0,
-        RENDER = 1
+        PARSE = 0,              ///< Parse mode (handling an incoming message)
+        RENDER = 1              ///< Render mode (building an outgoing message)
     };
 
+    /// \brief Constants for flag bit fields of a DNS message header.
+    ///
+    /// Only the defined constants are valid where a header flag is required
+    /// in this library (e.g., in \c Message::setHeaderFlag()).
+    /// Since these are enum constants, however, invalid value could be passed
+    /// via casting without an error at compilation time.
+    /// It is generally the callee's responsibility to check and reject invalid
+    /// values.
+    /// Of course, applications shouldn't pass invalid values even if the
+    /// callee does not perform proper validation; the result in such usage
+    /// is undefined.
+    ///
+    /// In the current implementation, the defined values happen to be
+    /// a 16-bit integer with one bit being set corresponding to the
+    /// specified flag in the second 16 bits of the DNS Header section
+    /// in order to make the internal implementation simpler.
+    /// For example, \c HEADERFLAG_QR is defined to be 0x8000 as the QR
+    /// bit is the most significant bit of the 2nd 16 bits of the header.
+    /// However, applications should not assume this coincidence and
+    /// must solely use the enum representations.
+    /// Any usage based on the assumption of the underlying values is invalid
+    /// and the result is undefined.
+    ///
+    /// Likewise, bit wise operations such as AND or OR on the flag values
+    /// are invalid and are not guaranteed to work, even if it could compile
+    /// with casting.
+    /// For example, the following code will compile:
+    /// \code const uint16_t combined_flags =
+    ///           static_cast<uint16_t>(Message::HEADERFLAG_AA) |
+    ///           static_cast<uint16_t>(Message::HEADERFLAG_CD);
+    /// message->setHeaderFlag(static_cast<Message::HeaderFlag>(combined_flags));
+    /// \endcode
+    /// and (with the current definition) happens to work as if it were
+    /// validly written as follows:
+    /// \code message->setHeaderFlag(Message::HEADERFLAG_AA);
+    /// message->setHeaderFlag(Message::HEADERFLAG_CD);
+    /// \endcode
+    /// But the former notation is invalid and may not work in future versions.
+    /// We did not try to prohibit such usage at compilation time, e.g., by
+    /// introducing a separately defined class considering the balance
+    /// between the complexity and advantage, but hopefully the cast notation
+    /// is sufficiently ugly to prevent proliferation of the usage.
+    enum HeaderFlag {
+        HEADERFLAG_QR = 0x8000, ///< Query (if cleared) or response (if set)
+        HEADERFLAG_AA = 0x0400, ///< Authoritative answer
+        HEADERFLAG_TC = 0x0200, ///< Truncation
+        HEADERFLAG_RD = 0x0100, ///< Recursion desired
+        HEADERFLAG_RA = 0x0080, ///< Recursion available
+        HEADERFLAG_AD = 0x0020, ///< DNSSEC checking disabled (RFC4035)
+        HEADERFLAG_CD = 0x0010  ///< Authentic %data (RFC4035)
+    };
+
+    /// \brief Constants to specify sections of a DNS message.
+    ///
+    /// The sections are those defined in RFC 1035 excluding the Header
+    /// section; the fields of the Header section are accessed via specific
+    /// methods of the \c Message class (e.g., \c getQid()).
+    ///
+    /// <b>Open Design Issue:</b>
+    /// In the current implementation the values for the constants are
+    /// sorted in the order of appearance in DNS messages, i.e.,
+    /// from %Question to Additional.
+    /// So, for example,
+    /// code <code>section >= Message::SECTION_AUTHORITY</code> can be
+    /// used to do something in or after the Authority section.
+    /// This would be convenient, but it is not clear if it's really a good
+    /// idea to rely on relationship between the underlying values of enum
+    /// constants.  At the moment, applications are discouraged to rely on
+    /// this implementation detail.  We will see if such usage is sufficiently
+    /// common to officially support it.
+    ///
+    /// Note also that since we don't define \c operator++ for this enum,
+    /// the following code intending to iterate over all sections will
+    /// \b not compile:
+    /// \code for (Section s; s <= SECTION_ADDITIONAL; ++s) { // ++s undefined
+    ///     // do something
+    /// } \endcode
+    /// This is intentional at this moment, and we'll see if we need to allow
+    /// that as we have more experiences with this library.
+    ///
+    /// <b>Future Extension:</b> We'll probably also define constants for
+    /// the section names used in dynamic updates in future versions.
+    enum Section {
+        SECTION_QUESTION = 0,   ///< %Question section
+        SECTION_ANSWER = 1,     ///< Answer section
+        SECTION_AUTHORITY = 2,  ///< Authority section
+        SECTION_ADDITIONAL = 3  ///< Additional section
+    };
+
     ///
     /// \name Constructors and Destructor
     ///
-    /// Note: The copy constructor and the assignment operator are intentionally
-    /// defined as private.  The intended use case wouldn't require copies of
-    /// a \c Message object; once created, it would normally be expected to
-    /// be reused, changing the mode from \c PARSE to \c RENDER, and vice
-    /// versa.
+    /// Note: The copy constructor and the assignment operator are
+    /// intentionally defined as private.
+    /// The intended use case wouldn't require copies of a \c Message object;
+    /// once created, it would normally be expected to be reused, changing the
+    /// mode from \c PARSE to \c RENDER, and vice versa.
     //@{
 public:
     /// \brief The constructor.
@@ -301,26 +264,51 @@
 public:
     /// \brief Return whether the specified header flag bit is set in the
     /// header section.
-    bool getHeaderFlag(const MessageFlag& flag) const;
-
-    /// \brief Set the specified header flag bit is set in the header section.
-    ///
-    /// Only allowed in the \c RENDER mode.
-    void setHeaderFlag(const MessageFlag& flag);
-
-    /// \brief Clear the specified header flag bit is set in the header section.
-    ///
-    /// Only allowed in the \c RENDER mode.
-    /// Note: it may make more sense to integrate this method into \c
-    /// \c setHeaderFlag() with an additional argument.
-    void clearHeaderFlag(const MessageFlag& flag);
+    ///
+    /// This method is basically exception free, but if
+    /// \c flag is not a valid constant of the \c HeaderFlag type,
+    /// an exception of class \c InvalidParameter will be thrown.
+    ///
+    /// \param flag The header flag constant to test.
+    /// \return \c true if the specified flag is set; otherwise \c false.
+    bool getHeaderFlag(const HeaderFlag flag) const;
+
+    /// \brief Set or clear the specified header flag bit in the header
+    /// section.
+    ///
+    /// The optional parameter \c on indicates the operation mode,
+    /// set or clear; if it's \c true the corresponding flag will be set;
+    /// otherwise the flag will be cleared.
+    /// In either case the original state of the flag does not affect the
+    /// operation; for example, if a flag is already set and the "set"
+    /// operation is attempted, it effectively results in no operation.
+    ///
+    /// The parameter \c on can be omitted, in which case a value of \c true
+    /// (i.e., set operation) will be assumed.
+    /// This is based on the observation that the flag would have to be set
+    /// in the vast majority of the cases where an application needs to
+    /// use this method.
+    ///
+    /// This method is only allowed in the \c RENDER mode;
+    /// if the \c Message is in other mode, an exception of class
+    /// InvalidMessageOperation will be thrown.
+    ///
+    /// If \c flag is not a valid constant of the \c HeaderFlag type,
+    /// an exception of class \c InvalidParameter will be thrown.
+    ///
+    /// \param flag The header flag constant to set or clear.
+    /// \param on If \c true the flag will be set; otherwise the flag will be
+    /// cleared.
+    void setHeaderFlag(const HeaderFlag flag, const bool on = true);
 
     /// \brief Return the query ID given in the header section of the message.
     qid_t getQid() const;
 
     /// \brief Set the query ID of the header section of the message.
     ///
-    /// Only allowed in the \c RENDER mode.
+    /// This method is only allowed in the \c RENDER mode;
+    /// if the \c Message is in other mode, an exception of class
+    /// InvalidMessageOperation will be thrown.
     void setQid(qid_t qid);
 
     /// \brief Return the Response Code of the message.
@@ -338,7 +326,9 @@
 
     /// \brief Set the Response Code of the message.
     ///
-    /// Only allowed in the \c RENDER mode.
+    /// This method is only allowed in the \c RENDER mode;
+    /// if the \c Message is in other mode, an exception of class
+    /// InvalidMessageOperation will be thrown.
     ///
     /// If the specified code is an EDNS extended RCODE, an EDNS OPT RR will be
     /// included in the message.
@@ -354,7 +344,9 @@
 
     /// \brief Set the OPCODE of the header section of the message.
     ///
-    /// Only allowed in the \c RENDER mode.
+    /// This method is only allowed in the \c RENDER mode;
+    /// if the \c Message is in other mode, an exception of class
+    /// InvalidMessageOperation will be thrown.
     void setOpcode(const Opcode& opcode);
 
     /// \brief Return, if any, the EDNS associated with the message.
@@ -367,15 +359,38 @@
 
     /// \brief Set EDNS for the message.
     ///
-    /// Only allowed in the \c RENDER mode; otherwise an exception of class
-    /// \c InvalidMessageOperation will be thrown.
+    /// This method is only allowed in the \c RENDER mode;
+    /// if the \c Message is in other mode, an exception of class
+    /// 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;
+    ///
+    /// In the \c PARSE mode, the returned value may not be identical to
+    /// the actual number of RRs of the incoming message that is parsed.
+    /// The \c Message class handles some "meta" RRs such as EDNS OPT RR
+    /// separately.  This method doesn't include such RRs.
+    /// Also, a future version of the parser will detect and unify duplicate
+    /// RRs (which should be rare in practice though), in which case
+    /// the stored RRs in the \c Message object will be fewer than the RRs
+    /// originally contained in the incoming message.
+    ///
+    /// Likewise, in the \c RENDER mode, even if \c EDNS is set in the
+    /// \c Message, this method doesn't count the corresponding OPT RR
+    /// in the Additional section.
+    ///
+    /// This method is basically exception free, but if
+    /// \c section is not a valid constant of the \c Section type,
+    /// an exception of class \c OutOfRange will be thrown.
+    ///
+    /// \param section The section in the message where RRs should be
+    /// counted.
+    /// \return The number of RRs stored in the specified section of the
+    /// message.
+    unsigned int getRRCount(const Section section) const;
 
     /// \brief Return an iterator corresponding to the beginning of the
     /// Question section of the message.
@@ -387,15 +402,23 @@
 
     /// \brief Return an iterator corresponding to the beginning of the
     /// given section (other than Question) of the message.
-    const RRsetIterator beginSection(const Section& section) const;
+    ///
+    /// \c section must be a valid constant of the \c Section type;
+    /// otherwise, an exception of class \c OutOfRange will be thrown.
+    const RRsetIterator beginSection(const Section section) const;
 
     /// \brief Return an iterator corresponding to the end of the
     /// given section (other than Question) of the message.
-    const RRsetIterator endSection(const Section& section) const;
+    ///
+    /// \c section must be a valid constant of the \c Section type;
+    /// otherwise, an exception of class \c OutOfRange will be thrown.
+    const RRsetIterator endSection(const Section section) const;
 
     /// \brief Add a (pointer like object of) Question to the message.
     ///
-    /// Only allowed in the \c RENDER mode.
+    /// This method is only allowed in the \c RENDER mode;
+    /// if the \c Message is in other mode, an exception of class
+    /// InvalidMessageOperation will be thrown.
     void addQuestion(QuestionPtr question);
 
     /// \brief Add a (pointer like object of) Question to the message.
@@ -406,7 +429,9 @@
     /// form may be more intuitive and may make more sense for performance
     /// insensitive applications.
     ///
-    /// Only allowed in the \c RENDER mode.
+    /// This method is only allowed in the \c RENDER mode;
+    /// if the \c Message is in other mode, an exception of class
+    /// InvalidMessageOperation will be thrown.
     void addQuestion(const Question& question);
 
     /// \brief Add a (pointer like object of) RRset to the given section
@@ -415,23 +440,34 @@
     /// This interface takes into account the RRSIG possibly attached to
     /// \c rrset.  This interface design needs to be revisited later.
     ///
-    /// Only allowed in the \c RENDER mode.
-    ///
-    /// Note that addRRset() does not currently check for duplicate
+    /// This method is only allowed in the \c RENDER mode;
+    /// if the \c Message is in other mode, an exception of class
+    /// InvalidMessageOperation will be thrown.
+    /// \c section must be a valid constant of the \c Section type;
+    /// otherwise, an exception of class \c OutOfRange will be thrown.
+    ///
+    /// Note that \c addRRset() does not currently check for duplicate
     /// data before inserting RRsets.  The caller is responsible for
-    /// checking for these (see hasRRset() below).
-    void addRRset(const Section& section, RRsetPtr rrset, bool sign = false);
+    /// checking for these (see \c hasRRset() below).
+    void addRRset(const Section section, RRsetPtr rrset, bool sign = false);
 
     /// \brief Determine whether the given section already has an RRset
-    /// matching the name and type of this one
-    bool hasRRset(const Section& section, RRsetPtr rrset);
+    /// matching the given name, RR class and RR type.
+    ///
+    /// \c section must be a valid constant of the \c Section type;
+    /// otherwise, an exception of class \c OutOfRange will be thrown.
+    ///
+    /// This should probably be extended to be a "find" method that returns
+    /// a matching RRset if found.
+    bool hasRRset(const Section section, const Name& name,
+                  const RRClass& rrclass, const RRType& rrtype);
 
     // The following methods are not currently implemented.
     //void removeQuestion(QuestionPtr question);
-    //void removeRRset(const Section& section, RRsetPtr rrset);
+    //void removeRRset(const Section section, RRsetPtr rrset);
     // notyet:
-    //void addRR(const Section& section, const RR& rr);
-    //void removeRR(const Section& section, const RR& rr);
+    //void addRR(const Section section, const RR& rr);
+    //void removeRR(const Section section, const RR& rr);
 
     /// \brief Clear the message content (if any) and reinitialize it in the
     /// specified mode.
@@ -475,9 +511,6 @@
     ///
     /// With EDNS the maximum size can be increased per message.
     static const uint16_t DEFAULT_MAX_UDPSIZE = 512;
-
-    /// \brief The highest EDNS version this implementation supports.
-    static const uint8_t EDNS_SUPPORTED_VERSION = 0;
     //@}
 
 private:

Modified: branches/trac397focused/src/lib/dns/python/Makefile.am
==============================================================================
--- branches/trac397focused/src/lib/dns/python/Makefile.am (original)
+++ branches/trac397focused/src/lib/dns/python/Makefile.am Mon Dec 20 08:19:35 2010
@@ -1,6 +1,7 @@
 SUBDIRS = . tests
 
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
 AM_CXXFLAGS = $(B10_CXXFLAGS)
 
 pyexec_LTLIBRARIES = pydnspp.la
@@ -23,6 +24,7 @@
 EXTRA_DIST += rrttl_python.cc
 EXTRA_DIST += rdata_python.cc
 EXTRA_DIST += rrtype_python.cc
+EXTRA_DIST += tsigkey_python.cc
 
 # Python prefers .so, while some OSes (specifically MacOS) use a different
 # suffix for dynamic objects.  -module is necessary to work this around.

Modified: branches/trac397focused/src/lib/dns/python/message_python.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/python/message_python.cc (original)
+++ branches/trac397focused/src/lib/dns/python/message_python.cc Mon Dec 20 08:19:35 2010
@@ -14,6 +14,7 @@
 
 // $Id$
 
+#include <exceptions/exceptions.h>
 #include <dns/message.h>
 using namespace isc::dns;
 
@@ -35,340 +36,9 @@
 // and static wrappers around the methods we export), a list of methods,
 // and a type description
 
-
-//
-// MessageFlag
-//
-class s_MessageFlag : public PyObject {
-public:
-    const MessageFlag* messageflag;
-};
-
-static int MessageFlag_init(s_MessageFlag* self, PyObject* args);
-static void MessageFlag_destroy(s_MessageFlag* self);
-
-static PyObject* MessageFlag_getBit(s_MessageFlag* self);
-static PyObject* MessageFlag_QR(s_MessageFlag* self);
-static PyObject* MessageFlag_AA(s_MessageFlag* self);
-static PyObject* MessageFlag_TC(s_MessageFlag* self);
-static PyObject* MessageFlag_RD(s_MessageFlag* self);
-static PyObject* MessageFlag_RA(s_MessageFlag* self);
-static PyObject* MessageFlag_AD(s_MessageFlag* self);
-static PyObject* MessageFlag_CD(s_MessageFlag* self);
-
-static PyMethodDef MessageFlag_methods[] = {
-    { "get_bit", reinterpret_cast<PyCFunction>(MessageFlag_getBit), METH_NOARGS, "Returns the flag bit" },
-    { "QR", reinterpret_cast<PyCFunction>(MessageFlag_QR), METH_NOARGS | METH_STATIC, "Creates a QR MessageFlag" },
-    { "AA", reinterpret_cast<PyCFunction>(MessageFlag_AA), METH_NOARGS | METH_STATIC, "Creates a AA MessageFlag" },
-    { "TC", reinterpret_cast<PyCFunction>(MessageFlag_TC), METH_NOARGS | METH_STATIC, "Creates a TC MessageFlag" },
-    { "RD", reinterpret_cast<PyCFunction>(MessageFlag_RD), METH_NOARGS | METH_STATIC, "Creates a RD MessageFlag" },
-    { "RA", reinterpret_cast<PyCFunction>(MessageFlag_RA), METH_NOARGS | METH_STATIC, "Creates a RA MessageFlag" },
-    { "AD", reinterpret_cast<PyCFunction>(MessageFlag_AD), METH_NOARGS | METH_STATIC, "Creates a AD MessageFlag" },
-    { "CD", reinterpret_cast<PyCFunction>(MessageFlag_CD), METH_NOARGS | METH_STATIC, "Creates a CD MessageFlag" },
-    { NULL, NULL, 0, NULL }
-};
-
-static PyTypeObject messageflag_type = {
-    PyVarObject_HEAD_INIT(NULL, 0)
-    "pydnspp.MessageFlag",
-    sizeof(s_MessageFlag),              // tp_basicsize
-    0,                                  // tp_itemsize
-    (destructor)MessageFlag_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
-    NULL,                               // tp_str
-    NULL,                               // tp_getattro
-    NULL,                               // tp_setattro
-    NULL,                               // tp_as_buffer
-    Py_TPFLAGS_DEFAULT,                 // tp_flags
-    "The MessageFlag class objects represent standard "
-    "flag bits of the header section of DNS messages.",
-    NULL,                               // tp_traverse
-    NULL,                               // tp_clear
-    NULL,                               // tp_richcompare
-    0,                                  // tp_weaklistoffset
-    NULL,                               // tp_iter
-    NULL,                               // tp_iternext
-    MessageFlag_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)MessageFlag_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
-MessageFlag_init(s_MessageFlag* self UNUSED_PARAM,
-                 PyObject* args UNUSED_PARAM)
-{
-    PyErr_SetString(PyExc_NotImplementedError,
-                    "MessageFlag can't be built directly");
-    return (-1);
-}
-
-static void
-MessageFlag_destroy(s_MessageFlag* self) {
-    // We only use the consts from MessageFlag, so don't
-    // delete self->messageflag here
-    self->messageflag = NULL;
-    Py_TYPE(self)->tp_free(self);
-}
-
-static PyObject*
-MessageFlag_getBit(s_MessageFlag* self) {
-    return (Py_BuildValue("I", self->messageflag->getBit()));
-}
-
-static PyObject*
-MessageFlag_createStatic(const MessageFlag& flag) {
-    s_MessageFlag* ret = PyObject_New(s_MessageFlag, &messageflag_type);
-    if (ret != NULL) {
-        ret->messageflag = &flag;
-    }
-    return (ret);
-}
-
-static PyObject*
-MessageFlag_QR(s_MessageFlag* self UNUSED_PARAM) {
-    return (MessageFlag_createStatic(MessageFlag::QR()));
-}
-
-static PyObject*
-MessageFlag_AA(s_MessageFlag* self UNUSED_PARAM) {
-    return (MessageFlag_createStatic(MessageFlag::AA()));
-}
-
-static PyObject*
-MessageFlag_TC(s_MessageFlag* self UNUSED_PARAM) {
-    return (MessageFlag_createStatic(MessageFlag::TC()));
-}
-
-static PyObject*
-MessageFlag_RD(s_MessageFlag* self UNUSED_PARAM) {
-    return (MessageFlag_createStatic(MessageFlag::RD()));
-}
-
-static PyObject*
-MessageFlag_RA(s_MessageFlag* self UNUSED_PARAM) {
-    return (MessageFlag_createStatic(MessageFlag::RA()));
-}
-
-static PyObject*
-MessageFlag_AD(s_MessageFlag* self UNUSED_PARAM) {
-    return (MessageFlag_createStatic(MessageFlag::AD()));
-}
-
-static PyObject*
-MessageFlag_CD(s_MessageFlag* self UNUSED_PARAM) {
-    return (MessageFlag_createStatic(MessageFlag::CD()));
-}
-
-//
-// End of MessageFlag wrapper
-//
-
 //
 // Section
 //
-
-// TODO: iterator?
-
-class s_Section : public PyObject {
-public:
-    const Section* section;
-};
-
-static int Section_init(s_Section* self, PyObject* args);
-static void Section_destroy(s_Section* self);
-
-static PyObject* Section_getCode(s_Section* self);
-static PyObject* Section_QUESTION(s_Section* self);
-static PyObject* Section_ANSWER(s_Section* self);
-static PyObject* Section_AUTHORITY(s_Section* self);
-static PyObject* Section_ADDITIONAL(s_Section* self);
-static PyObject* Section_richcmp(s_Section* self, s_Section* other, int op);
-
-static PyMethodDef Section_methods[] = {
-    { "get_code", reinterpret_cast<PyCFunction>(Section_getCode), METH_NOARGS, "Returns the code value" },
-    { "QUESTION", reinterpret_cast<PyCFunction>(Section_QUESTION), METH_NOARGS | METH_STATIC, "Creates a QUESTION Section" },
-    { "ANSWER", reinterpret_cast<PyCFunction>(Section_ANSWER), METH_NOARGS | METH_STATIC, "Creates an ANSWER Section" },
-    { "AUTHORITY", reinterpret_cast<PyCFunction>(Section_AUTHORITY), METH_NOARGS | METH_STATIC, "Creates an AUTHORITY Section" },
-    { "ADDITIONAL", reinterpret_cast<PyCFunction>(Section_ADDITIONAL), METH_NOARGS | METH_STATIC, "Creates an ADDITIONAL Section" },
-    { NULL, NULL, 0, NULL }
-};
-
-static PyTypeObject section_type = {
-    PyVarObject_HEAD_INIT(NULL, 0)
-    "pydnspp.Section",
-    sizeof(s_Section),                  // tp_basicsize
-    0,                                  // tp_itemsize
-    (destructor)Section_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
-    NULL,                               // tp_str
-    NULL,                               // tp_getattro
-    NULL,                               // tp_setattro
-    NULL,                               // tp_as_buffer
-    Py_TPFLAGS_DEFAULT,                 // tp_flags
-    "The Section class objects represent DNS message sections such "
-    "as the header, question, or answer.",
-    NULL,                               // tp_traverse
-    NULL,                               // tp_clear
-    (richcmpfunc)Section_richcmp,       // tp_richcompare
-    0,                                  // tp_weaklistoffset
-    NULL,                               // tp_iter
-    NULL,                               // tp_iternext
-    Section_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)Section_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
-Section_init(s_Section* self UNUSED_PARAM,
-             PyObject* args UNUSED_PARAM)
-{
-    PyErr_SetString(PyExc_NotImplementedError,
-                    "Section can't be built directly");
-    return (-1);
-}
-
-static void
-Section_destroy(s_Section* self) {
-    // We only use the consts from Section, so don't
-    // delete self->section here
-    self->section = NULL;
-    Py_TYPE(self)->tp_free(self);
-}
-
-static PyObject*
-Section_getCode(s_Section* self) {
-    return (Py_BuildValue("I", self->section->getCode()));
-}
-
-static PyObject*
-Section_createStatic(const Section& section) {
-    s_Section* ret = PyObject_New(s_Section, &section_type);
-    if (ret != NULL) {
-        ret->section = §ion;
-    }
-    return (ret);
-}
-
-
-static PyObject*
-Section_QUESTION(s_Section* self UNUSED_PARAM) {
-    return (Section_createStatic(Section::QUESTION()));
-}
-
-static PyObject*
-Section_ANSWER(s_Section* self UNUSED_PARAM) {
-    return (Section_createStatic(Section::ANSWER()));
-}
-
-static PyObject*
-Section_AUTHORITY(s_Section* self UNUSED_PARAM) {
-    return (Section_createStatic(Section::AUTHORITY()));
-}
-
-static PyObject*
-Section_ADDITIONAL(s_Section* self UNUSED_PARAM) {
-    return (Section_createStatic(Section::ADDITIONAL()));
-}
-
-static PyObject* 
-Section_richcmp(s_Section* self, s_Section* 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; Section");
-        return (NULL);
-        break;
-    case Py_LE:
-        PyErr_SetString(PyExc_TypeError, "Unorderable type; Section");
-        return (NULL);
-        break;
-    case Py_EQ:
-        c = (*self->section == *other->section);
-        break;
-    case Py_NE:
-        c = (*self->section != *other->section);
-        break;
-    case Py_GT:
-        PyErr_SetString(PyExc_TypeError, "Unorderable type; Section");
-        return (NULL);
-        break;
-    case Py_GE:
-        PyErr_SetString(PyExc_TypeError, "Unorderable type; Section");
-        return (NULL);
-        break;
-    }
-    if (c)
-        Py_RETURN_TRUE;
-    else
-        Py_RETURN_FALSE;
-}
-
-//
-// End of Section wrapper
-//
-
-
 
 //
 // Message
@@ -391,7 +61,6 @@
 
 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_getQid(s_Message* self);
 static PyObject* Message_setQid(s_Message* self, PyObject* args);
 static PyObject* Message_getRcode(s_Message* self);
@@ -425,15 +94,13 @@
 // 3. Argument type
 // 4. Documentation
 static PyMethodDef Message_methods[] = {
-    { "get_header_flag", reinterpret_cast<PyCFunction>(Message_getHeaderFlag), METH_VARARGS,
+    { "get_header_flag", reinterpret_cast<PyCFunction>(Message_getHeaderFlag),
+      METH_VARARGS,
       "Return whether the specified header flag bit is set in the "
       "header section. Takes a MessageFlag object as the only argument." },
-    { "set_header_flag", reinterpret_cast<PyCFunction>(Message_setHeaderFlag), METH_VARARGS,
+    { "set_header_flag",
+      reinterpret_cast<PyCFunction>(Message_setHeaderFlag), METH_VARARGS,
       "Sets the specified header flag bit to 1. The message must be in "
-      "RENDER mode. If not, an InvalidMessageOperation is raised. "
-      "Takes a MessageFlag object as the only argument." },
-    { "clear_header_flag", reinterpret_cast<PyCFunction>(Message_clearHeaderFlag), METH_VARARGS, 
-      "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." },
     { "get_qid", reinterpret_cast<PyCFunction>(Message_getQid), METH_NOARGS,
@@ -562,8 +229,6 @@
 static int
 Message_init(s_Message* self, PyObject* args) {
     unsigned int i;
-    // The constructor argument can be a string ("IN"), an integer (1),
-    // or a sequence of numbers between 0 and 255 (wire code)
     
     if (PyArg_ParseTuple(args, "I", &i)) {
         PyErr_Clear();
@@ -593,12 +258,16 @@
 
 static PyObject*
 Message_getHeaderFlag(s_Message* self, PyObject* args) {
-    s_MessageFlag* messageflag;
-    if (!PyArg_ParseTuple(args, "O!", &messageflag_type, &messageflag)) {
-        return (NULL);
-    }
-    
-    if (self->message->getHeaderFlag(*messageflag->messageflag)) {
+    unsigned int messageflag;
+    if (!PyArg_ParseTuple(args, "I", &messageflag)) {
+        PyErr_Clear();
+        PyErr_SetString(PyExc_TypeError,
+                        "no valid type in get_header_flag argument");
+        return (NULL);
+    }
+
+    if (self->message->getHeaderFlag(
+            static_cast<Message::HeaderFlag>(messageflag))) {
         Py_RETURN_TRUE;
     } else {
         Py_RETURN_FALSE;
@@ -607,38 +276,33 @@
 
 static PyObject*
 Message_setHeaderFlag(s_Message* self, PyObject* args) {
-    s_MessageFlag* messageflag;
-    if (!PyArg_ParseTuple(args, "O!", &messageflag_type, &messageflag)) {
-        return (NULL);
-    }
-
-    try {
-        self->message->setHeaderFlag(*messageflag->messageflag);
+    int messageflag;
+    PyObject *on = Py_True;
+
+    if (!PyArg_ParseTuple(args, "i|O!", &messageflag, &PyBool_Type, &on)) {
+        PyErr_Clear();
+        PyErr_SetString(PyExc_TypeError,
+                        "no valid type in set_header_flag argument");
+        return (NULL);
+    }
+    if (messageflag < 0) {
+        PyErr_SetString(PyExc_TypeError, "invalid Message header flag");
+        return (NULL);
+    }
+
+    try {
+        self->message->setHeaderFlag(
+            static_cast<Message::HeaderFlag>(messageflag), on == Py_True);
         Py_RETURN_NONE;
     } catch (const InvalidMessageOperation& imo) {
         PyErr_Clear();
         PyErr_SetString(po_InvalidMessageOperation, imo.what());
         return (NULL);
-    }
-}
-
-static PyObject*
-Message_clearHeaderFlag(s_Message* self, PyObject* args) {
-    s_MessageFlag* messageflag;
-    if (!PyArg_ParseTuple(args, "O!", &messageflag_type, &messageflag)) {
-        return (NULL);
-    }
-
-    try {
-        self->message->clearHeaderFlag(*messageflag->messageflag);
-        Py_RETURN_NONE;
-    } catch (const InvalidMessageOperation& imo) {
-        PyErr_Clear();
-        PyErr_SetString(po_InvalidMessageOperation, imo.what());
-        return (NULL);
-    }
-
-    Py_RETURN_NONE;
+    } catch (const isc::InvalidParameter& ip) {
+        PyErr_Clear();
+        PyErr_SetString(po_InvalidParameter, ip.what());
+        return (NULL);
+    }
 }
 
 static PyObject*
@@ -774,58 +438,107 @@
 
 static PyObject*
 Message_getRRCount(s_Message* self, PyObject* args) {
-    s_Section *section;
-    if (!PyArg_ParseTuple(args, "O!", &section_type, &section)) {
-        return (NULL);
-    }
-    return (Py_BuildValue("I", self->message->getRRCount(*section->section)));
+    unsigned int section;
+    if (!PyArg_ParseTuple(args, "I", &section)) {
+        PyErr_Clear();
+        PyErr_SetString(PyExc_TypeError,
+                        "no valid type in get_rr_count argument");
+        return (NULL);
+    }
+    try {
+        return (Py_BuildValue("I", self->message->getRRCount(
+                                  static_cast<Message::Section>(section))));
+    } catch (const isc::OutOfRange& ex) {
+        PyErr_SetString(PyExc_OverflowError, ex.what());
+        return (NULL);
+    }
 }
 
 // TODO use direct iterators for these? (or simply lists for now?)
 static PyObject*
 Message_getQuestion(s_Message* self) {
+    QuestionIterator qi, qi_end;
+    try {
+        qi = self->message->beginQuestion();
+        qi_end = self->message->endQuestion();
+    } catch (const InvalidMessageSection& ex) {
+        PyErr_SetString(po_InvalidMessageSection, ex.what());
+        return (NULL);
+    } catch (...) {
+        PyErr_SetString(po_IscException,
+                        "Unexpected exception in getting section iterators");
+        return (NULL);
+    }
+
     PyObject* list = PyList_New(0);
-    
-    for (QuestionIterator qi = self->message->beginQuestion();
-         qi != self->message->endQuestion();
-         ++qi) {
-        s_Question *question = static_cast<s_Question*>(question_type.tp_alloc(&question_type, 0));
-        if (question != NULL) {
-            question->question = *qi;
-            if (question->question == NULL)
-              {
-                Py_DECREF(question);
-                return (NULL);
-              }
-        }
-        PyList_Append(list, question);
+    if (list == NULL) {
+        return (NULL);
+    }
+
+    for (; qi != qi_end; ++qi) {
+        s_Question *question = static_cast<s_Question*>(
+            question_type.tp_alloc(&question_type, 0));
+        if (question == NULL) {
+            Py_DECREF(question);
+            Py_DECREF(list);
+            return (NULL);
+        }
+        question->question = *qi;
+        if (PyList_Append(list, question) == -1) {
+            Py_DECREF(question);
+            Py_DECREF(list);
+            return (NULL);
+        }
+        Py_DECREF(question);
     }
     return (list);
 }
 
 static PyObject*
 Message_getSection(s_Message* self, PyObject* args) {
-    s_Section *section;
-    if (!PyArg_ParseTuple(args, "O!", &section_type, &section)) {
-        return (NULL);
-    }
+    unsigned int section;
+    if (!PyArg_ParseTuple(args, "I", &section)) {
+        PyErr_Clear();
+        PyErr_SetString(PyExc_TypeError,
+                        "no valid type in get_section argument");
+        return (NULL);
+    }
+    RRsetIterator rrsi, rrsi_end;
+    try {
+        rrsi = self->message->beginSection(
+            static_cast<Message::Section>(section));
+        rrsi_end = self->message->endSection(
+            static_cast<Message::Section>(section));
+    } catch (const isc::OutOfRange& ex) {
+        PyErr_SetString(PyExc_OverflowError, ex.what());
+        return (NULL);
+    } catch (const InvalidMessageSection& ex) {
+        PyErr_SetString(po_InvalidMessageSection, ex.what());
+        return (NULL);
+    } catch (...) {
+        PyErr_SetString(po_IscException,
+                        "Unexpected exception in getting section iterators");
+        return (NULL);
+    }
+
     PyObject* list = PyList_New(0);
-    
-    for (RRsetIterator rrsi = self->message->beginSection(*section->section);
-         rrsi != self->message->endSection(*section->section);
-         ++rrsi) {
-
-        s_RRset *rrset = static_cast<s_RRset*>(rrset_type.tp_alloc(&rrset_type, 0));
-        if (rrset != NULL) {
-            rrset->rrset = *rrsi;
-            if (rrset->rrset == NULL)
-              {
+    if (list == NULL) {
+        return (NULL);
+    }
+    for (; rrsi != rrsi_end; ++rrsi) {
+        s_RRset *rrset = static_cast<s_RRset*>(
+            rrset_type.tp_alloc(&rrset_type, 0));
+        if (rrset == NULL) {
                 Py_DECREF(rrset);
                 Py_DECREF(list);
                 return (NULL);
-              }
-        }
-        PyList_Append(list, rrset);
+        }
+        rrset->rrset = *rrsi;
+        if (PyList_Append(list, rrset) == -1) {
+                Py_DECREF(rrset);
+                Py_DECREF(list);
+                return (NULL);
+        }
         // PyList_Append increases refcount, so we remove ours since
         // we don't need it anymore
         Py_DECREF(rrset);
@@ -854,33 +567,33 @@
 static PyObject*
 Message_addRRset(s_Message* self, PyObject* args) {
     PyObject *sign = Py_False;
-    s_Section* section;
+    unsigned int section;
     s_RRset* rrset;
-    if (!PyArg_ParseTuple(args, "O!O!|O!", &section_type, &section,
-                                           &rrset_type, &rrset,
-                                           &PyBool_Type, &sign)) {
-        return (NULL);
-    }
-
-    try {
-        if (sign == Py_True) {
-            self->message->addRRset(*section->section, rrset->rrset, true);
-        } else {
-            self->message->addRRset(*section->section, rrset->rrset, false);
-        }
+    if (!PyArg_ParseTuple(args, "IO!|O!", &section, &rrset_type, &rrset,
+                          &PyBool_Type, &sign)) {
+        return (NULL);
+    }
+
+    try {
+        self->message->addRRset(static_cast<Message::Section>(section),
+                                rrset->rrset, sign == Py_True);
         Py_RETURN_NONE;
     } catch (const InvalidMessageOperation& imo) {
         PyErr_SetString(po_InvalidMessageOperation, imo.what());
         return (NULL);
+    } catch (const isc::OutOfRange& ex) {
+        PyErr_SetString(PyExc_OverflowError, ex.what());
+        return (NULL);
+    } catch (...) {
+        PyErr_SetString(po_IscException,
+                        "Unexpected exception in adding RRset");
+        return (NULL);
     }
 }
 
 static PyObject*
 Message_clear(s_Message* self, PyObject* args) {
     unsigned int i;
-    // The constructor argument can be a string ("IN"), an integer (1),
-    // or a sequence of numbers between 0 and 255 (wire code)
-
     if (PyArg_ParseTuple(args, "I", &i)) {
         PyErr_Clear();
         if (i == Message::PARSE) {
@@ -890,7 +603,8 @@
             self->message->clear(Message::RENDER);
             Py_RETURN_NONE;
         } else {
-            PyErr_SetString(PyExc_TypeError, "Message mode must be Message.PARSE or Message.RENDER");
+            PyErr_SetString(PyExc_TypeError,
+                            "Message mode must be Message.PARSE or Message.RENDER");
             return (NULL);
         }
     } else {
@@ -979,62 +693,64 @@
 // Module Initialization, all statics are initialized here
 bool
 initModulePart_Message(PyObject* mod) {
-    
-    // add methods to class
-    if (PyType_Ready(&messageflag_type) < 0) {
-        return (false);
-    }
-    Py_INCREF(&messageflag_type);
-    PyModule_AddObject(mod, "MessageFlag",
-                       reinterpret_cast<PyObject*>(&messageflag_type));
-
-    
-    if (PyType_Ready(&opcode_type) < 0) {
-        return (false);
-    }
-    Py_INCREF(&opcode_type);
-    PyModule_AddObject(mod, "Opcode",
-                       reinterpret_cast<PyObject*>(&opcode_type));
-
-    if (PyType_Ready(&rcode_type) < 0) {
-        return (false);
-    }
-    Py_INCREF(&rcode_type);
-    PyModule_AddObject(mod, "Rcode",
-                       reinterpret_cast<PyObject*>(&rcode_type));
-
-    if (PyType_Ready(&section_type) < 0) {
-        return (false);
-    }
-    Py_INCREF(&section_type);
-    PyModule_AddObject(mod, "Section",
-                       reinterpret_cast<PyObject*>(&section_type));
-
-    
     if (PyType_Ready(&message_type) < 0) {
         return (false);
     }
+    Py_INCREF(&message_type);
     
     // Class variables
     // These are added to the tp_dict of the type object
     //
-    addClassVariable(message_type, "PARSE", Py_BuildValue("I", Message::PARSE));
-    addClassVariable(message_type, "RENDER", Py_BuildValue("I", Message::RENDER));
-    addClassVariable(message_type, "DEFAULT_MAX_UDPSIZE", Py_BuildValue("I", Message::DEFAULT_MAX_UDPSIZE));
+    addClassVariable(message_type, "PARSE",
+                     Py_BuildValue("I", Message::PARSE));
+    addClassVariable(message_type, "RENDER",
+                     Py_BuildValue("I", Message::RENDER));
+
+    addClassVariable(message_type, "HEADERFLAG_QR",
+                     Py_BuildValue("I", Message::HEADERFLAG_QR));
+    addClassVariable(message_type, "HEADERFLAG_AA",
+                     Py_BuildValue("I", Message::HEADERFLAG_AA));
+    addClassVariable(message_type, "HEADERFLAG_TC",
+                     Py_BuildValue("I", Message::HEADERFLAG_TC));
+    addClassVariable(message_type, "HEADERFLAG_RD",
+                     Py_BuildValue("I", Message::HEADERFLAG_RD));
+    addClassVariable(message_type, "HEADERFLAG_RA",
+                     Py_BuildValue("I", Message::HEADERFLAG_RA));
+    addClassVariable(message_type, "HEADERFLAG_AD",
+                     Py_BuildValue("I", Message::HEADERFLAG_AD));
+    addClassVariable(message_type, "HEADERFLAG_CD",
+                     Py_BuildValue("I", Message::HEADERFLAG_CD));
+
+    addClassVariable(message_type, "SECTION_QUESTION",
+                     Py_BuildValue("I", Message::SECTION_QUESTION));
+    addClassVariable(message_type, "SECTION_ANSWER",
+                     Py_BuildValue("I", Message::SECTION_ANSWER));
+    addClassVariable(message_type, "SECTION_AUTHORITY",
+                     Py_BuildValue("I", Message::SECTION_AUTHORITY));
+    addClassVariable(message_type, "SECTION_ADDITIONAL",
+                     Py_BuildValue("I", Message::SECTION_ADDITIONAL));
+
+    addClassVariable(message_type, "DEFAULT_MAX_UDPSIZE",
+                     Py_BuildValue("I", Message::DEFAULT_MAX_UDPSIZE));
 
     /* Class-specific exceptions */
-    po_MessageTooShort = PyErr_NewException("pydnspp.MessageTooShort", NULL, NULL);
+    po_MessageTooShort = PyErr_NewException("pydnspp.MessageTooShort", NULL,
+                                            NULL);
     PyModule_AddObject(mod, "MessageTooShort", po_MessageTooShort);
-    po_InvalidMessageSection = PyErr_NewException("pydnspp.InvalidMessageSection", NULL, NULL);
+    po_InvalidMessageSection =
+        PyErr_NewException("pydnspp.InvalidMessageSection", NULL, NULL);
     PyModule_AddObject(mod, "InvalidMessageSection", po_InvalidMessageSection);
-    po_InvalidMessageOperation = PyErr_NewException("pydnspp.InvalidMessageOperation", NULL, NULL);
-    PyModule_AddObject(mod, "InvalidMessageOperation", po_InvalidMessageOperation);
-    po_InvalidMessageUDPSize = PyErr_NewException("pydnspp.InvalidMessageUDPSize", NULL, NULL);
+    po_InvalidMessageOperation =
+        PyErr_NewException("pydnspp.InvalidMessageOperation", NULL, NULL);
+    PyModule_AddObject(mod, "InvalidMessageOperation",
+                       po_InvalidMessageOperation);
+    po_InvalidMessageUDPSize =
+        PyErr_NewException("pydnspp.InvalidMessageUDPSize", NULL, NULL);
     PyModule_AddObject(mod, "InvalidMessageUDPSize", po_InvalidMessageUDPSize);
-    po_DNSMessageBADVERS = PyErr_NewException("pydnspp.DNSMessageBADVERS", NULL, NULL);
+    po_DNSMessageBADVERS = PyErr_NewException("pydnspp.DNSMessageBADVERS",
+                                              NULL, NULL);
     PyModule_AddObject(mod, "DNSMessageBADVERS", po_DNSMessageBADVERS);
 
-    Py_INCREF(&message_type);
     PyModule_AddObject(mod, "Message",
                        reinterpret_cast<PyObject*>(&message_type));
 

Modified: branches/trac397focused/src/lib/dns/python/name_python.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/python/name_python.cc (original)
+++ branches/trac397focused/src/lib/dns/python/name_python.cc Mon Dec 20 08:19:35 2010
@@ -50,7 +50,7 @@
     isc::dns::NameComparisonResult* ncr;
 };
 
-static int NameComparisonResult_init(s_NameComparisonResult* self UNUSED_PARAM, PyObject* args UNUSED_PARAM);
+static int NameComparisonResult_init(s_NameComparisonResult*, PyObject*);
 static void NameComparisonResult_destroy(s_NameComparisonResult* self);
 static PyObject* NameComparisonResult_getOrder(s_NameComparisonResult* self);
 static PyObject* NameComparisonResult_getCommonLabels(s_NameComparisonResult* self);
@@ -123,9 +123,7 @@
 };
 
 static int
-NameComparisonResult_init(s_NameComparisonResult* self UNUSED_PARAM,
-                          PyObject* args UNUSED_PARAM)
-{
+NameComparisonResult_init(s_NameComparisonResult*, PyObject*) {
     PyErr_SetString(PyExc_NotImplementedError,
                     "NameComparisonResult can't be built directly");
     return (-1);

Modified: branches/trac397focused/src/lib/dns/python/opcode_python.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/python/opcode_python.cc (original)
+++ branches/trac397focused/src/lib/dns/python/opcode_python.cc Mon Dec 20 08:19:35 2010
@@ -220,82 +220,82 @@
 }
 
 PyObject*
-Opcode_QUERY(const s_Opcode* self UNUSED_PARAM) {
+Opcode_QUERY(const s_Opcode*) {
     return (Opcode_createStatic(Opcode::QUERY()));
 }
 
 PyObject*
-Opcode_IQUERY(const s_Opcode* self UNUSED_PARAM) {
+Opcode_IQUERY(const s_Opcode*) {
     return (Opcode_createStatic(Opcode::IQUERY()));
 }
 
 PyObject*
-Opcode_STATUS(const s_Opcode* self UNUSED_PARAM) {
+Opcode_STATUS(const s_Opcode*) {
     return (Opcode_createStatic(Opcode::STATUS()));
 }
 
 PyObject*
-Opcode_RESERVED3(const s_Opcode* self UNUSED_PARAM) {
+Opcode_RESERVED3(const s_Opcode*) {
     return (Opcode_createStatic(Opcode::RESERVED3()));
 }
 
 PyObject*
-Opcode_NOTIFY(const s_Opcode* self UNUSED_PARAM) {
+Opcode_NOTIFY(const s_Opcode*) {
     return (Opcode_createStatic(Opcode::NOTIFY()));
 }
 
 PyObject*
-Opcode_UPDATE(const s_Opcode* self UNUSED_PARAM) {
+Opcode_UPDATE(const s_Opcode*) {
     return (Opcode_createStatic(Opcode::UPDATE()));
 }
 
 PyObject*
-Opcode_RESERVED6(const s_Opcode* self UNUSED_PARAM) {
+Opcode_RESERVED6(const s_Opcode*) {
     return (Opcode_createStatic(Opcode::RESERVED6()));
 }
 
 PyObject*
-Opcode_RESERVED7(const s_Opcode* self UNUSED_PARAM) {
+Opcode_RESERVED7(const s_Opcode*) {
     return (Opcode_createStatic(Opcode::RESERVED7()));
 }
 
 PyObject*
-Opcode_RESERVED8(const s_Opcode* self UNUSED_PARAM) {
+Opcode_RESERVED8(const s_Opcode*) {
     return (Opcode_createStatic(Opcode::RESERVED8()));
 }
 
 PyObject*
-Opcode_RESERVED9(const s_Opcode* self UNUSED_PARAM) {
+Opcode_RESERVED9(const s_Opcode*) {
     return (Opcode_createStatic(Opcode::RESERVED9()));
 }
 
 PyObject*
-Opcode_RESERVED10(const s_Opcode* self UNUSED_PARAM) {
+Opcode_RESERVED10(const s_Opcode*) {
     return (Opcode_createStatic(Opcode::RESERVED10()));
 }
 
 PyObject*
-Opcode_RESERVED11(const s_Opcode* self UNUSED_PARAM) {
+Opcode_RESERVED11(const s_Opcode*) {
     return (Opcode_createStatic(Opcode::RESERVED11()));
 }
 
 PyObject*
-Opcode_RESERVED12(const s_Opcode* self UNUSED_PARAM) {
+Opcode_RESERVED12(const s_Opcode*) {
     return (Opcode_createStatic(Opcode::RESERVED12()));
 }
 
 PyObject*
-Opcode_RESERVED13(const s_Opcode* self UNUSED_PARAM) {
+Opcode_RESERVED13(const s_Opcode*) {
     return (Opcode_createStatic(Opcode::RESERVED13()));
 }
 
 PyObject*
-Opcode_RESERVED14(const s_Opcode* self UNUSED_PARAM) {
+Opcode_RESERVED14(const s_Opcode*) {
     return (Opcode_createStatic(Opcode::RESERVED14()));
 }
 
 PyObject*
-Opcode_RESERVED15(const s_Opcode* self UNUSED_PARAM) {
+Opcode_RESERVED15(const s_Opcode*) {
     return (Opcode_createStatic(Opcode::RESERVED15()));
 }
 

Modified: branches/trac397focused/src/lib/dns/python/pydnspp.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/python/pydnspp.cc (original)
+++ branches/trac397focused/src/lib/dns/python/pydnspp.cc Mon Dec 20 08:19:35 2010
@@ -57,6 +57,7 @@
 #include <dns/python/rrset_python.cc>          // needs Rdata, RRTTL
 #include <dns/python/question_python.cc>       // needs RRClass, RRType, RRTTL,
                                                // Name
+#include <dns/python/tsigkey_python.cc>        // needs Name
 #include <dns/python/opcode_python.cc>
 #include <dns/python/rcode_python.cc>
 #include <dns/python/edns_python.cc>           // needs Messagerenderer, Rcode
@@ -146,6 +147,14 @@
         return (NULL);
     }
 
+    if (!initModulePart_TSIGKey(mod)) {
+        return (NULL);
+    }
+
+    if (!initModulePart_TSIGKeyRing(mod)) {
+        return (NULL);
+    }
+
     return (mod);
 }
 

Modified: branches/trac397focused/src/lib/dns/python/rcode_python.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/python/rcode_python.cc (original)
+++ branches/trac397focused/src/lib/dns/python/rcode_python.cc Mon Dec 20 08:19:35 2010
@@ -254,87 +254,87 @@
 }
 
 PyObject*
-Rcode_NOERROR(const s_Rcode* self UNUSED_PARAM) {
+Rcode_NOERROR(const s_Rcode*) {
     return (Rcode_createStatic(Rcode::NOERROR()));
 }
 
 PyObject*
-Rcode_FORMERR(const s_Rcode* self UNUSED_PARAM) {
+Rcode_FORMERR(const s_Rcode*) {
     return (Rcode_createStatic(Rcode::FORMERR()));
 }
 
 PyObject*
-Rcode_SERVFAIL(const s_Rcode* self UNUSED_PARAM) {
+Rcode_SERVFAIL(const s_Rcode*) {
     return (Rcode_createStatic(Rcode::SERVFAIL()));
 }
 
 PyObject*
-Rcode_NXDOMAIN(const s_Rcode* self UNUSED_PARAM) {
+Rcode_NXDOMAIN(const s_Rcode*) {
     return (Rcode_createStatic(Rcode::NXDOMAIN()));
 }
 
 PyObject*
-Rcode_NOTIMP(const s_Rcode* self UNUSED_PARAM) {
+Rcode_NOTIMP(const s_Rcode*) {
     return (Rcode_createStatic(Rcode::NOTIMP()));
 }
 
 PyObject*
-Rcode_REFUSED(const s_Rcode* self UNUSED_PARAM) {
+Rcode_REFUSED(const s_Rcode*) {
     return (Rcode_createStatic(Rcode::REFUSED()));
 }
 
 PyObject*
-Rcode_YXDOMAIN(const s_Rcode* self UNUSED_PARAM) {
+Rcode_YXDOMAIN(const s_Rcode*) {
     return (Rcode_createStatic(Rcode::YXDOMAIN()));
 }
 
 PyObject*
-Rcode_YXRRSET(const s_Rcode* self UNUSED_PARAM) {
+Rcode_YXRRSET(const s_Rcode*) {
     return (Rcode_createStatic(Rcode::YXRRSET()));
 }
 
 PyObject*
-Rcode_NXRRSET(const s_Rcode* self UNUSED_PARAM) {
+Rcode_NXRRSET(const s_Rcode*) {
     return (Rcode_createStatic(Rcode::NXRRSET()));
 }
 
 PyObject*
-Rcode_NOTAUTH(const s_Rcode* self UNUSED_PARAM) {
+Rcode_NOTAUTH(const s_Rcode*) {
     return (Rcode_createStatic(Rcode::NOTAUTH()));
 }
 
 PyObject*
-Rcode_NOTZONE(const s_Rcode* self UNUSED_PARAM) {
+Rcode_NOTZONE(const s_Rcode*) {
     return (Rcode_createStatic(Rcode::NOTZONE()));
 }
 
 PyObject*
-Rcode_RESERVED11(const s_Rcode* self UNUSED_PARAM) {
+Rcode_RESERVED11(const s_Rcode*) {
     return (Rcode_createStatic(Rcode::RESERVED11()));
 }
 
 PyObject*
-Rcode_RESERVED12(const s_Rcode* self UNUSED_PARAM) {
+Rcode_RESERVED12(const s_Rcode*) {
     return (Rcode_createStatic(Rcode::RESERVED12()));
 }
 
 PyObject*
-Rcode_RESERVED13(const s_Rcode* self UNUSED_PARAM) {
+Rcode_RESERVED13(const s_Rcode*) {
     return (Rcode_createStatic(Rcode::RESERVED13()));
 }
 
 PyObject*
-Rcode_RESERVED14(const s_Rcode* self UNUSED_PARAM) {
+Rcode_RESERVED14(const s_Rcode*) {
     return (Rcode_createStatic(Rcode::RESERVED14()));
 }
 
 PyObject*
-Rcode_RESERVED15(const s_Rcode* self UNUSED_PARAM) {
+Rcode_RESERVED15(const s_Rcode*) {
     return (Rcode_createStatic(Rcode::RESERVED15()));
 }
 
 PyObject*
-Rcode_BADVERS(const s_Rcode* self UNUSED_PARAM) {
+Rcode_BADVERS(const s_Rcode*) {
     return (Rcode_createStatic(Rcode::BADVERS()));
 }
 

Modified: branches/trac397focused/src/lib/dns/python/rrclass_python.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/python/rrclass_python.cc (original)
+++ branches/trac397focused/src/lib/dns/python/rrclass_python.cc Mon Dec 20 08:19:35 2010
@@ -306,23 +306,23 @@
     return (ret);
 }
 
-static PyObject* RRClass_IN(s_RRClass *self UNUSED_PARAM) {
+static PyObject* RRClass_IN(s_RRClass*) {
     return (RRClass_createStatic(RRClass::IN()));
 }
 
-static PyObject* RRClass_CH(s_RRClass *self UNUSED_PARAM) {
+static PyObject* RRClass_CH(s_RRClass*) {
     return (RRClass_createStatic(RRClass::CH()));
 }
 
-static PyObject* RRClass_HS(s_RRClass *self UNUSED_PARAM) {
+static PyObject* RRClass_HS(s_RRClass*) {
     return (RRClass_createStatic(RRClass::HS()));
 }
 
-static PyObject* RRClass_NONE(s_RRClass *self UNUSED_PARAM) {
+static PyObject* RRClass_NONE(s_RRClass*) {
     return (RRClass_createStatic(RRClass::NONE()));
 }
 
-static PyObject* RRClass_ANY(s_RRClass *self UNUSED_PARAM) {
+static PyObject* RRClass_ANY(s_RRClass*) {
     return (RRClass_createStatic(RRClass::ANY()));
 }
 // end of RRClass

Modified: branches/trac397focused/src/lib/dns/python/rrset_python.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/python/rrset_python.cc (original)
+++ branches/trac397focused/src/lib/dns/python/rrset_python.cc Mon Dec 20 08:19:35 2010
@@ -158,7 +158,7 @@
 };
 
 static int
-RRset_init(s_RRset* self, PyObject* args UNUSED_PARAM) {
+RRset_init(s_RRset* self, PyObject* args) {
     s_Name* name;
     s_RRClass* rrclass;
     s_RRType* rrtype;
@@ -355,7 +355,7 @@
 
     RdataIteratorPtr it = self->rrset->getRdataIterator();
 
-    for (it->first(); !it->isLast(); it->next()) {
+    for (; !it->isLast(); it->next()) {
         s_Rdata *rds = static_cast<s_Rdata*>(rdata_type.tp_alloc(&rdata_type, 0));
         if (rds != NULL) {
             // hmz them iterators/shared_ptrs and private constructors

Modified: branches/trac397focused/src/lib/dns/python/rrtype_python.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/python/rrtype_python.cc (original)
+++ branches/trac397focused/src/lib/dns/python/rrtype_python.cc Mon Dec 20 08:19:35 2010
@@ -344,97 +344,97 @@
 }
 
 static PyObject*
-RRType_NSEC3PARAM(s_RRType *self UNUSED_PARAM) {
+RRType_NSEC3PARAM(s_RRType*) {
     return (RRType_createStatic(RRType::NSEC3PARAM()));
 }
 
 static PyObject*
-RRType_DNAME(s_RRType *self UNUSED_PARAM) {
+RRType_DNAME(s_RRType*) {
     return (RRType_createStatic(RRType::DNAME()));
 }
 
 static PyObject*
-RRType_PTR(s_RRType *self UNUSED_PARAM) {
+RRType_PTR(s_RRType*) {
     return (RRType_createStatic(RRType::PTR()));
 }
 
 static PyObject*
-RRType_MX(s_RRType *self UNUSED_PARAM) {
+RRType_MX(s_RRType*) {
     return (RRType_createStatic(RRType::MX()));
 }
 
 static PyObject*
-RRType_DNSKEY(s_RRType *self UNUSED_PARAM) {
+RRType_DNSKEY(s_RRType*) {
     return (RRType_createStatic(RRType::DNSKEY()));
 }
 
 static PyObject*
-RRType_TXT(s_RRType *self UNUSED_PARAM) {
+RRType_TXT(s_RRType*) {
     return (RRType_createStatic(RRType::TXT()));
 }
 
 static PyObject*
-RRType_RRSIG(s_RRType *self UNUSED_PARAM) {
+RRType_RRSIG(s_RRType*) {
     return (RRType_createStatic(RRType::RRSIG()));
 }
 
 static PyObject*
-RRType_NSEC(s_RRType *self UNUSED_PARAM) {
+RRType_NSEC(s_RRType*) {
     return (RRType_createStatic(RRType::NSEC()));
 }
 
 static PyObject*
-RRType_AAAA(s_RRType *self UNUSED_PARAM) {
+RRType_AAAA(s_RRType*) {
     return (RRType_createStatic(RRType::AAAA()));
 }
 
 static PyObject*
-RRType_DS(s_RRType *self UNUSED_PARAM) {
+RRType_DS(s_RRType*) {
     return (RRType_createStatic(RRType::DS()));
 }
 
 static PyObject*
-RRType_OPT(s_RRType *self UNUSED_PARAM) {
+RRType_OPT(s_RRType*) {
     return (RRType_createStatic(RRType::OPT()));
 }
 
 static PyObject*
-RRType_A(s_RRType *self UNUSED_PARAM) {
+RRType_A(s_RRType*) {
     return (RRType_createStatic(RRType::A()));
 }
 
 static PyObject*
-RRType_NS(s_RRType *self UNUSED_PARAM) {
+RRType_NS(s_RRType*) {
     return (RRType_createStatic(RRType::NS()));
 }
 
 static PyObject*
-RRType_CNAME(s_RRType *self UNUSED_PARAM) {
+RRType_CNAME(s_RRType*) {
     return (RRType_createStatic(RRType::CNAME()));
 }
 
 static PyObject*
-RRType_SOA(s_RRType *self UNUSED_PARAM) {
+RRType_SOA(s_RRType*) {
     return (RRType_createStatic(RRType::SOA()));
 }
 
 static PyObject*
-RRType_NSEC3(s_RRType *self UNUSED_PARAM) {
+RRType_NSEC3(s_RRType*) {
     return (RRType_createStatic(RRType::NSEC3()));
 }
 
 static PyObject*
-RRType_IXFR(s_RRType *self UNUSED_PARAM) {
+RRType_IXFR(s_RRType*) {
     return (RRType_createStatic(RRType::IXFR()));
 }
 
 static PyObject*
-RRType_AXFR(s_RRType *self UNUSED_PARAM) {
+RRType_AXFR(s_RRType*) {
     return (RRType_createStatic(RRType::AXFR()));
 }
 
 static PyObject*
-RRType_ANY(s_RRType *self UNUSED_PARAM) {
+RRType_ANY(s_RRType*) {
     return (RRType_createStatic(RRType::ANY()));
 }
 

Modified: branches/trac397focused/src/lib/dns/python/tests/Makefile.am
==============================================================================
--- branches/trac397focused/src/lib/dns/python/tests/Makefile.am (original)
+++ branches/trac397focused/src/lib/dns/python/tests/Makefile.am Mon Dec 20 08:19:35 2010
@@ -10,6 +10,7 @@
 PYTESTS += rrset_python_test.py
 PYTESTS += rrttl_python_test.py
 PYTESTS += rrtype_python_test.py
+PYTESTS += tsigkey_python_test.py
 
 EXTRA_DIST = $(PYTESTS)
 EXTRA_DIST += testutil.py

Modified: branches/trac397focused/src/lib/dns/python/tests/message_python_test.py
==============================================================================
--- branches/trac397focused/src/lib/dns/python/tests/message_python_test.py (original)
+++ branches/trac397focused/src/lib/dns/python/tests/message_python_test.py Mon Dec 20 08:19:35 2010
@@ -22,61 +22,6 @@
 from pydnspp import *
 from testutil import *
 
-class MessageFlagTest(unittest.TestCase):
-    def test_init(self):
-        self.assertRaises(NotImplementedError, MessageFlag)
-
-    def test_get_bit(self):
-        self.assertEqual(0x8000, MessageFlag.QR().get_bit())
-        self.assertEqual(0x0400, MessageFlag.AA().get_bit())
-        self.assertEqual(0x0200, MessageFlag.TC().get_bit())
-        self.assertEqual(0x0100, MessageFlag.RD().get_bit())
-        self.assertEqual(0x0080, MessageFlag.RA().get_bit())
-        self.assertEqual(0x0020, MessageFlag.AD().get_bit())
-        self.assertEqual(0x0010, MessageFlag.CD().get_bit())
-
-class SectionTest(unittest.TestCase):
-
-    def test_init(self):
-        self.assertRaises(NotImplementedError, Section)
-
-    def test_get_code(self):
-        self.assertEqual(0, Section.QUESTION().get_code())
-        self.assertEqual(1, Section.ANSWER().get_code())
-        self.assertEqual(2, Section.AUTHORITY().get_code())
-        self.assertEqual(3, Section.ADDITIONAL().get_code())
-
-    def test_richcmp(self):
-        s1 = Section.QUESTION()
-        s2 = Section.ANSWER()
-        s3 = Section.ANSWER()
-        self.assertTrue(s2 == s3)
-        self.assertTrue(s1 != s2)
-        self.assertFalse(s1 == s2)
-        self.assertFalse(s1 == 1)
-        # can't use assertRaises here...
-        try:
-            s1 < s2
-            self.fail("operation that should have raised an error unexpectedly succeeded")
-        except Exception as err:
-            self.assertEqual(TypeError, type(err))
-        try:
-            s1 <= s2
-            self.fail("operation that should have raised an error unexpectedly succeeded")
-        except Exception as err:
-            self.assertEqual(TypeError, type(err))
-        try:
-            s1 > s2
-            self.fail("operation that should have raised an error unexpectedly succeeded")
-        except Exception as err:
-            self.assertEqual(TypeError, type(err))
-        try:
-            s1 >= s2
-            self.fail("operation that should have raised an error unexpectedly succeeded")
-        except Exception as err:
-            self.assertEqual(TypeError, type(err))
-        
-
 # helper functions for tests taken from c++ unittests
 if "TESTDATA_PATH" in os.environ:
     testdata_path = os.environ["TESTDATA_PATH"]
@@ -105,15 +50,16 @@
     message_render.set_qid(0x1035)
     message_render.set_opcode(Opcode.QUERY())
     message_render.set_rcode(Rcode.NOERROR())
-    message_render.set_header_flag(MessageFlag.QR())
-    message_render.set_header_flag(MessageFlag.RD())
-    message_render.set_header_flag(MessageFlag.AA())
-    message_render.add_question(Question(Name("test.example.com"), RRClass("IN"), RRType("A")))
+    message_render.set_header_flag(Message.HEADERFLAG_QR)
+    message_render.set_header_flag(Message.HEADERFLAG_RD)
+    message_render.set_header_flag(Message.HEADERFLAG_AA)
+    message_render.add_question(Question(Name("test.example.com"),
+                                         RRClass("IN"), RRType("A")))
     rrset = RRset(Name("test.example.com"), RRClass("IN"),
                                         RRType("A"), RRTTL(3600))
     rrset.add_rdata(Rdata(RRType("A"), RRClass("IN"), "192.0.2.1"))
     rrset.add_rdata(Rdata(RRType("A"), RRClass("IN"), "192.0.2.2"))
-    message_render.add_rrset(Section.ANSWER(), rrset)
+    message_render.add_rrset(Message.SECTION_ANSWER, rrset)
     return message_render
 
 
@@ -122,29 +68,56 @@
     def setUp(self):
         self.p = Message(Message.PARSE)
         self.r = Message(Message.RENDER)
-        
+
+        self.rrset_a = RRset(Name("example.com"), RRClass("IN"), RRType("A"),
+                             RRTTL(3600))
+        self.rrset_a.add_rdata(Rdata(RRType("A"), RRClass("IN"), "192.0.2.1"))
+        self.rrset_a.add_rdata(Rdata(RRType("A"), RRClass("IN"), "192.0.2.2"))
+
+        self.rrset_aaaa = RRset(Name("example.com"), RRClass("IN"),
+                                RRType("AAAA"), RRTTL(3600))
+        self.rrset_aaaa.add_rdata(Rdata(RRType("AAAA"), RRClass("IN"),
+                                        "2001:db8::134"))
+
+        self.bogus_section = Message.SECTION_ADDITIONAL + 1
+
     def test_init(self):
         self.assertRaises(TypeError, Message, 3)
         self.assertRaises(TypeError, Message, "wrong")
 
-    def test_get_header_flag(self):
+    def test_header_flag(self): # set and get methods
         self.assertRaises(TypeError, self.p.get_header_flag, "wrong")
-        self.assertFalse(self.p.get_header_flag(MessageFlag.AA()))
-
-    def test_set_clear_header_flag(self):
         self.assertRaises(TypeError, self.r.set_header_flag, "wrong")
-        self.assertRaises(TypeError, self.r.clear_header_flag, "wrong")
-
-        self.assertFalse(self.r.get_header_flag(MessageFlag.AA()))
-        self.r.set_header_flag(MessageFlag.AA())
-        self.assertTrue(self.r.get_header_flag(MessageFlag.AA()))
-        self.r.clear_header_flag(MessageFlag.AA())
-        self.assertFalse(self.r.get_header_flag(MessageFlag.AA()))
-
-        self.assertRaises(InvalidMessageOperation,
-                          self.p.set_header_flag, MessageFlag.AA())
-        self.assertRaises(InvalidMessageOperation,
-                          self.p.clear_header_flag, MessageFlag.AA())
+
+        self.assertFalse(self.r.get_header_flag(Message.HEADERFLAG_QR))
+        self.assertFalse(self.r.get_header_flag(Message.HEADERFLAG_AA))
+        self.assertFalse(self.r.get_header_flag(Message.HEADERFLAG_TC))
+        self.assertFalse(self.r.get_header_flag(Message.HEADERFLAG_RD))
+        self.assertFalse(self.r.get_header_flag(Message.HEADERFLAG_RA))
+        self.assertFalse(self.r.get_header_flag(Message.HEADERFLAG_AD))
+        self.assertFalse(self.r.get_header_flag(Message.HEADERFLAG_CD))
+
+        self.r.set_header_flag(Message.HEADERFLAG_QR)
+        self.assertTrue(self.r.get_header_flag(Message.HEADERFLAG_QR))
+
+        self.r.set_header_flag(Message.HEADERFLAG_AA, True)
+        self.assertTrue(self.r.get_header_flag(Message.HEADERFLAG_AA))
+
+        self.r.set_header_flag(Message.HEADERFLAG_AA, False)
+        self.assertFalse(self.r.get_header_flag(Message.HEADERFLAG_AA))
+
+        self.assertRaises(InvalidParameter, self.r.set_header_flag, 0)
+        self.assertRaises(InvalidParameter, self.r.set_header_flag, 0x7000)
+        self.assertRaises(InvalidParameter, self.r.set_header_flag, 0x0800)
+        self.assertRaises(InvalidParameter, self.r.set_header_flag, 0x10000)
+        self.assertRaises(TypeError, self.r.set_header_flag, 0x80000000)
+        # this would cause overflow and result in a "valid" flag
+        self.assertRaises(TypeError, self.r.set_header_flag,
+                          Message.HEADERFLAG_AA | 0x100000000)
+        self.assertRaises(TypeError, self.r.set_header_flag, -1)
+
+        self.assertRaises(InvalidMessageOperation,
+                          self.p.set_header_flag, Message.HEADERFLAG_AA)
 
     def test_set_qid(self):
         self.assertRaises(TypeError, self.r.set_qid, "wrong")
@@ -195,52 +168,77 @@
         self.r.set_edns(edns)
         self.assertEqual(1024, self.r.get_edns().get_udp_size())
 
+    def test_get_rr_count(self):
+        # counts also tested in add_section
+        self.assertEqual(0, self.r.get_rr_count(Message.SECTION_QUESTION))
+        self.assertEqual(0, self.r.get_rr_count(Message.SECTION_ANSWER))
+        self.assertEqual(0, self.r.get_rr_count(Message.SECTION_AUTHORITY))
+        self.assertEqual(0, self.r.get_rr_count(Message.SECTION_ADDITIONAL))
+
+        self.r.add_question(Question(Name("example.com"), RRClass("IN"),
+                                     RRType("A")))
+        self.assertEqual(1, self.r.get_rr_count(Message.SECTION_QUESTION))
+
+        self.r.add_rrset(Message.SECTION_ANSWER, self.rrset_a)
+        self.assertEqual(2, self.r.get_rr_count(Message.SECTION_ANSWER))
+
+        factoryFromFile(self.p, "message_fromWire11.wire")
+        self.assertEqual(1, self.r.get_rr_count(Message.SECTION_QUESTION))
+        self.assertEqual(0, self.r.get_rr_count(Message.SECTION_ADDITIONAL))
+
+        self.assertRaises(OverflowError, self.r.get_rr_count,
+                          self.bogus_section)
+        self.assertRaises(TypeError, self.r.get_rr_count, "wrong")
+
     def test_get_section(self):
         self.assertRaises(TypeError, self.r.get_section, "wrong")
 
-        rrset = RRset(Name("example.com"), RRClass("IN"), RRType("A"), RRTTL(3600))
-        rrset.add_rdata(Rdata(RRType("A"), RRClass("IN"), "192.0.2.1"))
-        rrset.add_rdata(Rdata(RRType("A"), RRClass("IN"), "192.0.2.2"))
-        section_rrset = [rrset]
+        section_rrset = [self.rrset_a]
 
         self.assertRaises(InvalidMessageOperation, self.p.add_rrset,
-                          Section.ANSWER(), rrset)
+                          Message.SECTION_ANSWER, self.rrset_a)
         
-        self.assertFalse(compare_rrset_list(section_rrset, self.r.get_section(Section.ANSWER())))
-        self.assertEqual(0, self.r.get_rr_count(Section.ANSWER()))
-        self.r.add_rrset(Section.ANSWER(), rrset)
-        self.assertTrue(compare_rrset_list(section_rrset, self.r.get_section(Section.ANSWER())))
-        self.assertEqual(2, self.r.get_rr_count(Section.ANSWER()))
-
-        self.assertFalse(compare_rrset_list(section_rrset, self.r.get_section(Section.AUTHORITY())))
-        self.assertEqual(0, self.r.get_rr_count(Section.AUTHORITY()))
-        self.r.add_rrset(Section.AUTHORITY(), rrset)
-        self.assertTrue(compare_rrset_list(section_rrset, self.r.get_section(Section.AUTHORITY())))
-        self.assertEqual(2, self.r.get_rr_count(Section.AUTHORITY()))
-
-        self.assertFalse(compare_rrset_list(section_rrset, self.r.get_section(Section.ADDITIONAL())))
-        self.assertEqual(0, self.r.get_rr_count(Section.ADDITIONAL()))
-        self.r.add_rrset(Section.ADDITIONAL(), rrset)
-        self.assertTrue(compare_rrset_list(section_rrset, self.r.get_section(Section.ADDITIONAL())))
-        self.assertEqual(2, self.r.get_rr_count(Section.ADDITIONAL()))
-
-    def test_get_rr_count(self):
-        self.assertRaises(TypeError, self.r.get_rr_count, "wrong")
-        # counts also tested in add_section
+        self.assertFalse(compare_rrset_list(section_rrset, self.r.get_section(Message.SECTION_ANSWER)))
+        self.assertEqual(0, self.r.get_rr_count(Message.SECTION_ANSWER))
+        self.r.add_rrset(Message.SECTION_ANSWER, self.rrset_a)
+        self.assertTrue(compare_rrset_list(section_rrset, self.r.get_section(Message.SECTION_ANSWER)))
+        self.assertEqual(2, self.r.get_rr_count(Message.SECTION_ANSWER))
+
+        self.assertFalse(compare_rrset_list(section_rrset, self.r.get_section(Message.SECTION_AUTHORITY)))
+        self.assertEqual(0, self.r.get_rr_count(Message.SECTION_AUTHORITY))
+        self.r.add_rrset(Message.SECTION_AUTHORITY, self.rrset_a)
+        self.assertTrue(compare_rrset_list(section_rrset, self.r.get_section(Message.SECTION_AUTHORITY)))
+        self.assertEqual(2, self.r.get_rr_count(Message.SECTION_AUTHORITY))
+
+        self.assertFalse(compare_rrset_list(section_rrset, self.r.get_section(Message.SECTION_ADDITIONAL)))
+        self.assertEqual(0, self.r.get_rr_count(Message.SECTION_ADDITIONAL))
+        self.r.add_rrset(Message.SECTION_ADDITIONAL, self.rrset_a)
+        self.assertTrue(compare_rrset_list(section_rrset, self.r.get_section(Message.SECTION_ADDITIONAL)))
+        self.assertEqual(2, self.r.get_rr_count(Message.SECTION_ADDITIONAL))
 
     def test_add_question(self):
         self.assertRaises(TypeError, self.r.add_question, "wrong", "wrong")
         q = Question(Name("example.com"), RRClass("IN"), RRType("A"))
         qs = [q]
         self.assertFalse(compare_rrset_list(qs, self.r.get_question()))
-        self.assertEqual(0, self.r.get_rr_count(Section.QUESTION()))
+        self.assertEqual(0, self.r.get_rr_count(Message.SECTION_QUESTION))
         self.r.add_question(q)
         self.assertTrue(compare_rrset_list(qs, self.r.get_question()))
-        self.assertEqual(1, self.r.get_rr_count(Section.QUESTION()))
+        self.assertEqual(1, self.r.get_rr_count(Message.SECTION_QUESTION))
 
     def test_add_rrset(self):
         self.assertRaises(TypeError, self.r.add_rrset, "wrong")
-        # actual addition already tested in get_section
+        self.assertRaises(TypeError, self.r.add_rrset)
+
+        # we can currently only test the no-sign case.
+        self.r.add_rrset(Message.SECTION_ANSWER, self.rrset_a)
+        self.assertEqual(2, self.r.get_rr_count(Message.SECTION_ANSWER))
+
+    def test_bad_add_rrset(self):
+        self.assertRaises(InvalidMessageOperation, self.p.add_rrset,
+                          Message.SECTION_ANSWER, self.rrset_a)
+        self.assertRaises(OverflowError, self.r.add_rrset,
+                          self.bogus_section, self.rrset_a)
 
     def test_clear(self):
         self.assertEqual(None, self.r.clear(Message.PARSE))
@@ -308,22 +306,22 @@
         self.assertEqual(0x1035, message_parse.get_qid())
         self.assertEqual(Opcode.QUERY(), message_parse.get_opcode())
         self.assertEqual(Rcode.NOERROR(), message_parse.get_rcode())
-        self.assertTrue(message_parse.get_header_flag(MessageFlag.QR()))
-        self.assertTrue(message_parse.get_header_flag(MessageFlag.RD()))
-        self.assertTrue(message_parse.get_header_flag(MessageFlag.AA()))
+        self.assertTrue(message_parse.get_header_flag(Message.HEADERFLAG_QR))
+        self.assertTrue(message_parse.get_header_flag(Message.HEADERFLAG_RD))
+        self.assertTrue(message_parse.get_header_flag(Message.HEADERFLAG_AA))
     
         #QuestionPtr q = *message_parse.beginQuestion()
         q = message_parse.get_question()[0]
         self.assertEqual(test_name, q.get_name())
         self.assertEqual(RRType("A"), q.get_type())
         self.assertEqual(RRClass("IN"), q.get_class())
-        self.assertEqual(1, message_parse.get_rr_count(Section.QUESTION()))
-        self.assertEqual(2, message_parse.get_rr_count(Section.ANSWER()))
-        self.assertEqual(0, message_parse.get_rr_count(Section.AUTHORITY()))
-        self.assertEqual(0, message_parse.get_rr_count(Section.ADDITIONAL()))
-    
-        #RRsetPtr rrset = *message_parse.beginSection(Section.ANSWER())
-        rrset = message_parse.get_section(Section.ANSWER())[0]
+        self.assertEqual(1, message_parse.get_rr_count(Message.SECTION_QUESTION))
+        self.assertEqual(2, message_parse.get_rr_count(Message.SECTION_ANSWER))
+        self.assertEqual(0, message_parse.get_rr_count(Message.SECTION_AUTHORITY))
+        self.assertEqual(0, message_parse.get_rr_count(Message.SECTION_ADDITIONAL))
+    
+        #RRsetPtr rrset = *message_parse.beginSection(Message.SECTION_ANSWER)
+        rrset = message_parse.get_section(Message.SECTION_ANSWER)[0]
         self.assertEqual(test_name, rrset.get_name())
         self.assertEqual(RRType("A"), rrset.get_type())
         self.assertEqual(RRClass("IN"), rrset.get_class())

Modified: branches/trac397focused/src/lib/dns/python/tests/messagerenderer_python_test.py
==============================================================================
--- branches/trac397focused/src/lib/dns/python/tests/messagerenderer_python_test.py (original)
+++ branches/trac397focused/src/lib/dns/python/tests/messagerenderer_python_test.py Mon Dec 20 08:19:35 2010
@@ -38,15 +38,15 @@
         self.message1 = message
         message = Message(Message.RENDER)
         message.set_qid(123)
-        message.set_header_flag(MessageFlag.AA())
-        message.set_header_flag(MessageFlag.QR())
+        message.set_header_flag(Message.HEADERFLAG_AA, True)
+        message.set_header_flag(Message.HEADERFLAG_QR, True)
         message.set_opcode(Opcode.QUERY())
         message.set_rcode(Rcode.NOERROR())
         message.add_question(Question(name, c, t))
         rrset = RRset(name, c, t, ttl)
         rrset.add_rdata(Rdata(t, c, "192.0.2.98"))
         rrset.add_rdata(Rdata(t, c, "192.0.2.99"))
-        message.add_rrset(Section.AUTHORITY(), rrset)
+        message.add_rrset(Message.SECTION_AUTHORITY, rrset)
         self.message2 = message
 
         self.renderer1 = MessageRenderer()

Modified: branches/trac397focused/src/lib/dns/rdata/ch_3/a_1.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/rdata/ch_3/a_1.cc (original)
+++ branches/trac397focused/src/lib/dns/rdata/ch_3/a_1.cc Mon Dec 20 08:19:35 2010
@@ -14,8 +14,6 @@
 
 // $Id$
 
-#include <config.h>             // for UNUSED_PARAM
-
 #include <string>
 
 #include <exceptions/exceptions.h>
@@ -30,25 +28,25 @@
 // BEGIN_ISC_NAMESPACE
 // BEGIN_RDATA_NAMESPACE
 
-A::A(const string& addrstr UNUSED_PARAM) {
+A::A(const string&) {
     // TBD
 }
 
-A::A(InputBuffer& buffer UNUSED_PARAM, size_t rdata_len UNUSED_PARAM) {
+A::A(InputBuffer&, size_t) {
     // TBD
 }
 
-A::A(const A& source UNUSED_PARAM) : Rdata() {
+A::A(const A&) : Rdata() {
     // TBD
 }
 
 void
-A::toWire(OutputBuffer& buffer UNUSED_PARAM) const {
+A::toWire(OutputBuffer&) const {
     // TBD
 }
 
 void
-A::toWire(MessageRenderer& renderer UNUSED_PARAM) const {
+A::toWire(MessageRenderer&) const {
     // TBD
 }
 
@@ -59,7 +57,7 @@
 }
 
 int
-A::compare(const Rdata& other UNUSED_PARAM) const {
+A::compare(const Rdata&) const {
     return (0);                 // dummy.  TBD
 }
 

Modified: branches/trac397focused/src/lib/dns/rdata/generic/cname_5.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/rdata/generic/cname_5.cc (original)
+++ branches/trac397focused/src/lib/dns/rdata/generic/cname_5.cc Mon Dec 20 08:19:35 2010
@@ -33,7 +33,7 @@
     cname_(namestr)
 {}
 
-CNAME::CNAME(InputBuffer& buffer, size_t rdata_len UNUSED_PARAM) :
+CNAME::CNAME(InputBuffer& buffer, size_t) :
     Rdata(), cname_(buffer)
 {
     // we don't need rdata_len for parsing.  if necessary, the caller will

Modified: branches/trac397focused/src/lib/dns/rdata/generic/dname_39.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/rdata/generic/dname_39.cc (original)
+++ branches/trac397focused/src/lib/dns/rdata/generic/dname_39.cc Mon Dec 20 08:19:35 2010
@@ -33,7 +33,7 @@
     dname_(namestr)
 {}
 
-DNAME::DNAME(InputBuffer& buffer, size_t rdata_len UNUSED_PARAM) :
+DNAME::DNAME(InputBuffer& buffer, size_t) :
     dname_(buffer)
 {
     // we don't need rdata_len for parsing.  if necessary, the caller will

Modified: branches/trac397focused/src/lib/dns/rdata/generic/mx_15.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/rdata/generic/mx_15.cc (original)
+++ branches/trac397focused/src/lib/dns/rdata/generic/mx_15.cc Mon Dec 20 08:19:35 2010
@@ -34,7 +34,7 @@
 // BEGIN_ISC_NAMESPACE
 // BEGIN_RDATA_NAMESPACE
 
-MX::MX(InputBuffer& buffer, size_t rdata_len UNUSED_PARAM) :
+MX::MX(InputBuffer& buffer, size_t) :
     preference_(buffer.readUint16()), mxname_(buffer)
 {
     // we don't need rdata_len for parsing.  if necessary, the caller will

Modified: branches/trac397focused/src/lib/dns/rdata/generic/ns_2.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/rdata/generic/ns_2.cc (original)
+++ branches/trac397focused/src/lib/dns/rdata/generic/ns_2.cc Mon Dec 20 08:19:35 2010
@@ -33,7 +33,7 @@
     nsname_(namestr)
 {}
 
-NS::NS(InputBuffer& buffer, size_t rdata_len UNUSED_PARAM) :
+NS::NS(InputBuffer& buffer, size_t) :
     nsname_(buffer)
 {
     // we don't need rdata_len for parsing.  if necessary, the caller will

Modified: branches/trac397focused/src/lib/dns/rdata/generic/opt_41.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/rdata/generic/opt_41.cc (original)
+++ branches/trac397focused/src/lib/dns/rdata/generic/opt_41.cc Mon Dec 20 08:19:35 2010
@@ -28,7 +28,7 @@
 // BEGIN_ISC_NAMESPACE
 // BEGIN_RDATA_NAMESPACE
 
-OPT::OPT(const string& type_str UNUSED_PARAM) {
+OPT::OPT(const string&) {
     isc_throw(InvalidRdataText, "OPT RR cannot be constructed from text");
 }
 
@@ -43,7 +43,7 @@
     buffer.setPosition(buffer.getPosition() + rdata_len);
 }
 
-OPT::OPT(const OPT& source UNUSED_PARAM) : Rdata() {
+OPT::OPT(const OPT&) : Rdata() {
     // there's nothing to copy in this simple implementation.
 }
 
@@ -53,19 +53,20 @@
 }
 
 void
-OPT::toWire(OutputBuffer& buffer UNUSED_PARAM) const {
+OPT::toWire(OutputBuffer&) const {
     // nothing to do, as this simple version doesn't support any options.
 }
 
 void
-OPT::toWire(MessageRenderer& renderer UNUSED_PARAM) const {
+OPT::toWire(MessageRenderer&) const {
     // nothing to do, as this simple version doesn't support any options.
 }
 
 int
 OPT::compare(const Rdata& other) const {
     //const OPT& other_opt = dynamic_cast<const OPT&>(other);
-    dynamic_cast<const OPT&>(other); // right now we don't need other_opt
+    // right now we don't need other_opt:
+    static_cast<void>(dynamic_cast<const OPT&>(other));
 
     return (0);
 }

Modified: branches/trac397focused/src/lib/dns/rdata/generic/ptr_12.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/rdata/generic/ptr_12.cc (original)
+++ branches/trac397focused/src/lib/dns/rdata/generic/ptr_12.cc Mon Dec 20 08:19:35 2010
@@ -33,7 +33,7 @@
     ptr_name_(type_str)
 {}
 
-PTR::PTR(InputBuffer& buffer, size_t rdata_len UNUSED_PARAM) :
+PTR::PTR(InputBuffer& buffer, size_t) :
     ptr_name_(buffer)
 {
     // we don't need rdata_len for parsing.  if necessary, the caller will

Modified: branches/trac397focused/src/lib/dns/rdata/generic/soa_6.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/rdata/generic/soa_6.cc (original)
+++ branches/trac397focused/src/lib/dns/rdata/generic/soa_6.cc Mon Dec 20 08:19:35 2010
@@ -34,7 +34,7 @@
 // BEGIN_ISC_NAMESPACE
 // BEGIN_RDATA_NAMESPACE
 
-SOA::SOA(InputBuffer& buffer, size_t rdata_len UNUSED_PARAM) :
+SOA::SOA(InputBuffer& buffer, size_t) :
     mname_(buffer), rname_(buffer)
 {
     // we don't need rdata_len for parsing.  if necessary, the caller will

Modified: branches/trac397focused/src/lib/dns/rdata/hs_4/a_1.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/rdata/hs_4/a_1.cc (original)
+++ branches/trac397focused/src/lib/dns/rdata/hs_4/a_1.cc Mon Dec 20 08:19:35 2010
@@ -14,8 +14,6 @@
 
 // $Id$
 
-#include <config.h>             // for UNUSED_PARAM
-
 #include <string>
 
 #include <exceptions/exceptions.h>
@@ -30,25 +28,25 @@
 // BEGIN_ISC_NAMESPACE
 // BEGIN_RDATA_NAMESPACE
 
-A::A(const string& addrstr UNUSED_PARAM) {
+A::A(const string&) {
     // TBD
 }
 
-A::A(InputBuffer& buffer UNUSED_PARAM, size_t rdata_len UNUSED_PARAM) {
+A::A(InputBuffer&, size_t) {
     // TBD
 }
 
-A::A(const A& source UNUSED_PARAM) : Rdata() {
+A::A(const A&) : Rdata() {
     // TBD
 }
 
 void
-A::toWire(OutputBuffer& buffer UNUSED_PARAM) const {
+A::toWire(OutputBuffer&) const {
     // TBD
 }
 
 void
-A::toWire(MessageRenderer& renderer UNUSED_PARAM) const {
+A::toWire(MessageRenderer&) const {
     // TBD
 }
 
@@ -59,7 +57,7 @@
 }
 
 int
-A::compare(const Rdata& other UNUSED_PARAM) const {
+A::compare(const Rdata&) const {
     return (0);                 // dummy.  TBD
 }
 

Modified: branches/trac397focused/src/lib/dns/rrclass-placeholder.h
==============================================================================
--- branches/trac397focused/src/lib/dns/rrclass-placeholder.h (original)
+++ branches/trac397focused/src/lib/dns/rrclass-placeholder.h Mon Dec 20 08:19:35 2010
@@ -244,14 +244,12 @@
     // END_WELL_KNOWN_CLASS_DECLARATIONS
     
     static const RRClass& NONE();
-    static const RRClass& ANY();
 
 private:
     // \brief Meta-classes
     enum {
         RRCLASS_RESERVED0 = 0,
-        RRCLASS_NONE = 254,
-        RRCLASS_ANY = 255
+        RRCLASS_NONE = 254
     };
     uint16_t classcode_;
 };
@@ -262,13 +260,6 @@
 inline const RRClass&
 RRClass::NONE() {
     static RRClass rrclass(RRCLASS_NONE);
-
-    return (rrclass);
-}
-
-inline const RRClass&
-RRClass::ANY() {
-    static RRClass rrclass(RRCLASS_ANY);
 
     return (rrclass);
 }

Modified: branches/trac397focused/src/lib/dns/rrset.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/rrset.cc (original)
+++ branches/trac397focused/src/lib/dns/rrset.cc Mon Dec 20 08:19:35 2010
@@ -44,7 +44,6 @@
     string s;
     RdataIteratorPtr it = getRdataIterator();
 
-    it->first();
     if (it->isLast()) {
         isc_throw(EmptyRRset, "ToText() is attempted for an empty RRset");
     }
@@ -66,7 +65,6 @@
     unsigned int n = 0;
     RdataIteratorPtr it = rrset.getRdataIterator();
 
-    it->first();
     if (it->isLast()) {
         isc_throw(EmptyRRset, "ToWire() is attempted for an empty RRset");
     }
@@ -224,7 +222,8 @@
     BasicRdataIterator() {}
 public:
     BasicRdataIterator(const std::vector<rdata::ConstRdataPtr>& datavector) :
-        datavector_(&datavector) {}
+        datavector_(&datavector), it_(datavector_->begin())
+    {}
     ~BasicRdataIterator() {}
     virtual void first() { it_ = datavector_->begin(); }
     virtual void next() { ++it_; }

Modified: branches/trac397focused/src/lib/dns/rrset.h
==============================================================================
--- branches/trac397focused/src/lib/dns/rrset.h (original)
+++ branches/trac397focused/src/lib/dns/rrset.h Mon Dec 20 08:19:35 2010
@@ -148,7 +148,7 @@
 ///      "sort" and "search(find)" method?
 ///   - what about comparing two RRsets of the same type?  If we need this,
 ///     should it compare rdata's as a set or as a list (i.e. compare
-///     each %rdata one by one or as a whole)?  c.f. NLnet Labs' ldns
+///     each rdata one by one or as a whole)?  c.f. NLnet Labs' ldns
 ///     (http://www.nlnetlabs.nl/projects/ldns/doc/index.html)
 ///     has \c ldns_rr_list_compare(), which takes the latter approach
 ///     (seemingly assuming the caller sorts the lists beforehand).
@@ -357,7 +357,7 @@
     /// \endcode
     ///
     /// This method is more strictly typed than the pointer version:
-    /// If \c %rdata does not refer to the appropriate derived
+    /// If \c rdata does not refer to the appropriate derived
     /// \c Rdata class
     /// for the \c RRType for this \c RRset, it throws an exception of class
     /// \c std::bad_cast.
@@ -385,6 +385,10 @@
     /// \brief Return an iterator to go through all RDATA stored in the
     /// \c RRset.
     ///
+    /// The rdata cursor of the returned iterator will point to the first
+    /// RDATA, that is, it effectively calls \c RdataIterator::first()
+    /// internally.
+    ///
     /// Using the design pattern terminology, \c getRdataIterator()
     /// is an example of a <em>factory method</em>.
     ///
@@ -417,10 +421,10 @@
 /// The RDATA objects stored in the \c RRset are considered to form
 /// a unidirectional list from the \c RdataIterator point of view (while
 /// the actual implementation in the derived \c RRset may not use a list).
-/// We call this unidirectional list the <em>%rdata list</em>.
+/// We call this unidirectional list the <em>rdata list</em>.
 ///
 /// An \c RdataIterator object internally (and conceptually) holds a
-/// <em>%rdata cursor</em>, which points to a specific item of the %rdata list.
+/// <em>rdata cursor</em>, which points to a specific item of the rdata list.
 ///
 /// Note about design choice: as is clear from the interface, \c RdataIterator
 /// is not compatible with the standard iterator classes.
@@ -458,29 +462,29 @@
     //@}
 
 public:
-    /// \brief Move the %rdata cursor to the first RDATA in the %rdata list
+    /// \brief Move the rdata cursor to the first RDATA in the rdata list
     /// (if any).
     ///
     /// This method can safely be called multiple times, even after moving
-    /// the %rdata cursor forward by the \c next() method.
+    /// the rdata cursor forward by the \c next() method.
     ///
     /// This method should never throw an exception.
     virtual void first() = 0;
 
-    /// \brief Move the %rdata cursor to the next RDATA in the %rdata list
+    /// \brief Move the rdata cursor to the next RDATA in the rdata list
     /// (if any).
     ///
     /// This method should never throw an exception.
     virtual void next() = 0;
 
-    /// \brief Return the current \c Rdata corresponding to the %rdata cursor.
+    /// \brief Return the current \c Rdata corresponding to the rdata cursor.
     ///
     /// \return A reference to an \c rdata::::Rdata object corresponding
-    /// to the %rdata cursor.
+    /// to the rdata cursor.
     virtual const rdata::Rdata& getCurrent() const = 0;
 
-    /// \brief Return true iff the %rdata cursor has reached the end of the
-    /// %rdata list.
+    /// \brief Return true iff the rdata cursor has reached the end of the
+    /// rdata list.
     ///
     /// Once this method returns \c true, the behavior of any subsequent
     /// call to \c next() or \c getCurrent() is undefined.
@@ -489,8 +493,8 @@
     ///
     /// This method should never throw an exception.
     ///
-    /// \return \c true if the %rdata cursor has reached the end of the
-    /// %rdata list; otherwise \c false.
+    /// \return \c true if the rdata cursor has reached the end of the
+    /// rdata list; otherwise \c false.
     virtual bool isLast() const = 0;
 };
 

Modified: branches/trac397focused/src/lib/dns/tests/Makefile.am
==============================================================================
--- branches/trac397focused/src/lib/dns/tests/Makefile.am (original)
+++ branches/trac397focused/src/lib/dns/tests/Makefile.am Mon Dec 20 08:19:35 2010
@@ -1,6 +1,7 @@
 SUBDIRS = testdata .
 
 AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
 AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
 AM_CPPFLAGS += -DTEST_DATA_SRCDIR=\"$(srcdir)/testdata\"
 AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/lib/dns/tests/testdata\"
@@ -37,15 +38,17 @@
 run_unittests_SOURCES += rdata_nsec3_unittest.cc
 run_unittests_SOURCES += rdata_nsec3param_unittest.cc
 run_unittests_SOURCES += rdata_rrsig_unittest.cc
+run_unittests_SOURCES += rdata_tsig_unittest.cc
 run_unittests_SOURCES += rrset_unittest.cc rrsetlist_unittest.cc
 run_unittests_SOURCES += question_unittest.cc
 run_unittests_SOURCES += rrparamregistry_unittest.cc
+run_unittests_SOURCES += masterload_unittest.cc
 run_unittests_SOURCES += message_unittest.cc
 run_unittests_SOURCES += base32hex_unittest.cc
 run_unittests_SOURCES += base64_unittest.cc
 run_unittests_SOURCES += hex_unittest.cc
 run_unittests_SOURCES += sha1_unittest.cc
-run_unittests_SOURCES += tsig_unittest.cc
+run_unittests_SOURCES += tsigkey_unittest.cc
 run_unittests_SOURCES += run_unittests.cc
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)

Modified: branches/trac397focused/src/lib/dns/tests/message_unittest.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/tests/message_unittest.cc (original)
+++ branches/trac397focused/src/lib/dns/tests/message_unittest.cc Mon Dec 20 08:19:35 2010
@@ -35,6 +35,7 @@
 
 using isc::UnitTestUtil;
 using namespace std;
+using namespace isc;
 using namespace isc::dns;
 using namespace isc::dns::rdata;
 
@@ -51,24 +52,45 @@
 //
 
 const uint16_t Message::DEFAULT_MAX_UDPSIZE;
+const Name test_name("test.example.com");
 
 namespace {
 class MessageTest : public ::testing::Test {
 protected:
     MessageTest() : obuffer(0), renderer(obuffer),
                     message_parse(Message::PARSE),
-                    message_render(Message::RENDER)
-    {}
+                    message_render(Message::RENDER),
+                    bogus_section(static_cast<Message::Section>(
+                                      Message::SECTION_ADDITIONAL + 1))
+    {
+        rrset_a = RRsetPtr(new RRset(test_name, RRClass::IN(),
+                                     RRType::A(), RRTTL(3600)));
+        rrset_a->addRdata(in::A("192.0.2.1"));
+        rrset_a->addRdata(in::A("192.0.2.2"));
+
+        rrset_aaaa = RRsetPtr(new RRset(test_name, RRClass::IN(),
+                                        RRType::AAAA(), RRTTL(3600)));
+        rrset_aaaa->addRdata(in::AAAA("2001:db8::1234"));
+
+        rrset_rrsig = RRsetPtr(new RRset(test_name, RRClass::IN(),
+                                        RRType::RRSIG(), RRTTL(3600)));
+        rrset_rrsig->addRdata(generic::RRSIG("AAAA 5 3 7200 20100322084538 "
+                                             "20100220084538 1 example.com "
+                                             "FAKEFAKEFAKEFAKE"));
+        rrset_aaaa->addRRsig(rrset_rrsig);
+    }
     
     static Question factoryFromFile(const char* datafile);
     OutputBuffer obuffer;
     MessageRenderer renderer;
     Message message_parse;
     Message message_render;
+    const Message::Section bogus_section;
+    RRsetPtr rrset_a;           // A RRset with two RDATAs
+    RRsetPtr rrset_aaaa;        // AAAA RRset with one RDATA with RRSIG
+    RRsetPtr rrset_rrsig;       // RRSIG for the AAAA RRset
     static void factoryFromFile(Message& message, const char* datafile);
 };
-
-const Name test_name("test.example.com");
 
 void
 MessageTest::factoryFromFile(Message& message, const char* datafile) {
@@ -77,6 +99,52 @@
 
     InputBuffer buffer(&data[0], data.size());
     message.fromWire(buffer);
+}
+
+TEST_F(MessageTest, headerFlag) {
+    // by default no flag is set
+    EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_QR));
+    EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_AA));
+    EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_TC));
+    EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_RD));
+    EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_RA));
+    EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_AD));
+    EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_CD));
+
+    // set operation: by default it will be on
+    message_render.setHeaderFlag(Message::HEADERFLAG_QR);
+    EXPECT_TRUE(message_render.getHeaderFlag(Message::HEADERFLAG_QR));
+
+    // it can be set to on explicitly, too
+    message_render.setHeaderFlag(Message::HEADERFLAG_AA, true);
+    EXPECT_TRUE(message_render.getHeaderFlag(Message::HEADERFLAG_AA));
+
+    // the bit can also be cleared
+    message_render.setHeaderFlag(Message::HEADERFLAG_AA, false);
+    EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_AA));
+
+    // Invalid flag values
+    EXPECT_THROW(message_render.setHeaderFlag(
+                     static_cast<Message::HeaderFlag>(0)), InvalidParameter);
+    EXPECT_THROW(message_render.setHeaderFlag(
+                     static_cast<Message::HeaderFlag>(0x7000)),
+                 InvalidParameter);
+    EXPECT_THROW(message_render.setHeaderFlag(
+                     static_cast<Message::HeaderFlag>(0x0800)),
+                 InvalidParameter);
+    EXPECT_THROW(message_render.setHeaderFlag(
+                     static_cast<Message::HeaderFlag>(0x0040)),
+                 InvalidParameter);
+    EXPECT_THROW(message_render.setHeaderFlag(
+                     static_cast<Message::HeaderFlag>(0x10000)),
+                 InvalidParameter);
+    EXPECT_THROW(message_render.setHeaderFlag(
+                     static_cast<Message::HeaderFlag>(0x80000000)),
+                 InvalidParameter);
+
+    // set operation isn't allowed in the parse mode.
+    EXPECT_THROW(message_parse.setHeaderFlag(Message::HEADERFLAG_QR),
+                 InvalidMessageOperation);
 }
 
 TEST_F(MessageTest, getEDNS) {
@@ -99,32 +167,132 @@
     EXPECT_EQ(edns, message_render.getEDNS());
 }
 
+TEST_F(MessageTest, getRRCount) {
+    // by default all counters should be 0
+    EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_QUESTION));
+    EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_ANSWER));
+    EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_AUTHORITY));
+    EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_ADDITIONAL));
+
+    message_render.addQuestion(Question(Name("test.example.com"),
+                                        RRClass::IN(), RRType::A()));
+    EXPECT_EQ(1, message_render.getRRCount(Message::SECTION_QUESTION));
+
+    // rrset_a contains two RRs
+    message_render.addRRset(Message::SECTION_ANSWER, rrset_a);
+    EXPECT_EQ(2, message_render.getRRCount(Message::SECTION_ANSWER));
+
+    // parse a message containing a Question and EDNS OPT RR.
+    // OPT shouldn't be counted as normal RR, so result of getRRCount
+    // shouldn't change.
+    factoryFromFile(message_parse, "message_fromWire11.wire");
+    EXPECT_EQ(1, message_render.getRRCount(Message::SECTION_QUESTION));
+    EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_ADDITIONAL));
+
+    // out-of-band section ID
+    EXPECT_THROW(message_parse.getRRCount(bogus_section), OutOfRange);
+}
+
+TEST_F(MessageTest, addRRset) {
+    // default case
+    message_render.addRRset(Message::SECTION_ANSWER, rrset_a);
+    EXPECT_EQ(rrset_a,
+              *message_render.beginSection(Message::SECTION_ANSWER));
+    EXPECT_EQ(2, message_render.getRRCount(Message::SECTION_ANSWER));
+
+    // signed RRset, default case
+    message_render.clear(Message::RENDER);
+    message_render.addRRset(Message::SECTION_ANSWER, rrset_aaaa);
+    EXPECT_EQ(rrset_aaaa,
+              *message_render.beginSection(Message::SECTION_ANSWER));
+    EXPECT_EQ(1, message_render.getRRCount(Message::SECTION_ANSWER));
+
+    // signed RRset, add with the RRSIG.  getRRCount() should return 2
+    message_render.clear(Message::RENDER);
+    message_render.addRRset(Message::SECTION_ANSWER, rrset_aaaa, true);
+    EXPECT_EQ(rrset_aaaa,
+              *message_render.beginSection(Message::SECTION_ANSWER));
+    EXPECT_EQ(2, message_render.getRRCount(Message::SECTION_ANSWER));
+
+    // signed RRset, add explicitly without RRSIG.
+    message_render.clear(Message::RENDER);
+    message_render.addRRset(Message::SECTION_ANSWER, rrset_aaaa, false);
+    EXPECT_EQ(rrset_aaaa,
+              *message_render.beginSection(Message::SECTION_ANSWER));
+    EXPECT_EQ(1, message_render.getRRCount(Message::SECTION_ANSWER));
+}
+
+TEST_F(MessageTest, badAddRRset) {
+    // addRRset() isn't allowed in the parse mode.
+    EXPECT_THROW(message_parse.addRRset(Message::SECTION_ANSWER,
+                                        rrset_a), InvalidMessageOperation);
+    // out-of-band section ID
+    EXPECT_THROW(message_render.addRRset(bogus_section, rrset_a), OutOfRange);
+}
+
+TEST_F(MessageTest, hasRRset) {
+    message_render.addRRset(Message::SECTION_ANSWER, rrset_a);
+    EXPECT_TRUE(message_render.hasRRset(Message::SECTION_ANSWER, test_name,
+                                        RRClass::IN(), RRType::A()));
+    // section doesn't match
+    EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ADDITIONAL, test_name,
+                                         RRClass::IN(), RRType::A()));
+    // name doesn't match
+    EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER,
+                                         Name("nomatch.example"),
+                                         RRClass::IN(), RRType::A()));
+    // RR class doesn't match
+    EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER, test_name,
+                                        RRClass::CH(), RRType::A()));
+    // RR type doesn't match
+    EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER, test_name,
+                                        RRClass::IN(), RRType::AAAA()));
+
+    // out-of-band section ID
+    EXPECT_THROW(message_render.hasRRset(bogus_section, test_name,
+                                         RRClass::IN(), RRType::A()),
+                 OutOfRange);
+}
+
+TEST_F(MessageTest, badBeginSection) {
+    // valid cases are tested via other tests
+    EXPECT_THROW(message_render.beginSection(Message::SECTION_QUESTION),
+                 InvalidMessageSection);
+    EXPECT_THROW(message_render.beginSection(bogus_section), OutOfRange);
+}
+
+TEST_F(MessageTest, badEndSection) {
+    // valid cases are tested via other tests
+    EXPECT_THROW(message_render.endSection(Message::SECTION_QUESTION),
+                 InvalidMessageSection);
+    EXPECT_THROW(message_render.endSection(bogus_section), OutOfRange);
+}
+
 TEST_F(MessageTest, fromWire) {
     factoryFromFile(message_parse, "message_fromWire1");
     EXPECT_EQ(0x1035, message_parse.getQid());
     EXPECT_EQ(Opcode::QUERY(), message_parse.getOpcode());
     EXPECT_EQ(Rcode::NOERROR(), message_parse.getRcode());
-    EXPECT_TRUE(message_parse.getHeaderFlag(MessageFlag::QR()));
-    EXPECT_TRUE(message_parse.getHeaderFlag(MessageFlag::RD()));
-    EXPECT_TRUE(message_parse.getHeaderFlag(MessageFlag::AA()));
+    EXPECT_TRUE(message_parse.getHeaderFlag(Message::HEADERFLAG_QR));
+    EXPECT_TRUE(message_parse.getHeaderFlag(Message::HEADERFLAG_RD));
+    EXPECT_TRUE(message_parse.getHeaderFlag(Message::HEADERFLAG_AA));
 
     QuestionPtr q = *message_parse.beginQuestion();
     EXPECT_EQ(test_name, q->getName());
     EXPECT_EQ(RRType::A(), q->getType());
     EXPECT_EQ(RRClass::IN(), q->getClass());
-    EXPECT_EQ(1, message_parse.getRRCount(Section::QUESTION()));
-    EXPECT_EQ(2, message_parse.getRRCount(Section::ANSWER()));
-    EXPECT_EQ(0, message_parse.getRRCount(Section::AUTHORITY()));
-    EXPECT_EQ(0, message_parse.getRRCount(Section::ADDITIONAL()));
-
-    RRsetPtr rrset = *message_parse.beginSection(Section::ANSWER());
+    EXPECT_EQ(1, message_parse.getRRCount(Message::SECTION_QUESTION));
+    EXPECT_EQ(2, message_parse.getRRCount(Message::SECTION_ANSWER));
+    EXPECT_EQ(0, message_parse.getRRCount(Message::SECTION_AUTHORITY));
+    EXPECT_EQ(0, message_parse.getRRCount(Message::SECTION_ADDITIONAL));
+
+    RRsetPtr rrset = *message_parse.beginSection(Message::SECTION_ANSWER);
     EXPECT_EQ(test_name, rrset->getName());
     EXPECT_EQ(RRType::A(), rrset->getType());
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
     // TTL should be 3600, even though that of the 2nd RR is 7200
     EXPECT_EQ(RRTTL(3600), rrset->getTTL());
     RdataIteratorPtr it = rrset->getRdataIterator();
-    it->first();
     EXPECT_EQ("192.0.2.1", it->getCurrent().toText());
     it->next();
     EXPECT_EQ("192.0.2.2", it->getCurrent().toText());
@@ -157,21 +325,17 @@
     message_render.setQid(0x1035);
     message_render.setOpcode(Opcode::QUERY());
     message_render.setRcode(Rcode::NOERROR());
-    message_render.setHeaderFlag(MessageFlag::QR());
-    message_render.setHeaderFlag(MessageFlag::RD());
-    message_render.setHeaderFlag(MessageFlag::AA());
+    message_render.setHeaderFlag(Message::HEADERFLAG_QR, true);
+    message_render.setHeaderFlag(Message::HEADERFLAG_RD, true);
+    message_render.setHeaderFlag(Message::HEADERFLAG_AA, true);
     message_render.addQuestion(Question(Name("test.example.com"), RRClass::IN(),
                                         RRType::A()));
-    RRsetPtr rrset = RRsetPtr(new RRset(Name("test.example.com"), RRClass::IN(),
-                                        RRType::A(), RRTTL(3600)));
-    rrset->addRdata(in::A("192.0.2.1"));
-    rrset->addRdata(in::A("192.0.2.2"));
-    message_render.addRRset(Section::ANSWER(), rrset);
-
-    EXPECT_EQ(1, message_render.getRRCount(Section::QUESTION()));
-    EXPECT_EQ(2, message_render.getRRCount(Section::ANSWER()));
-    EXPECT_EQ(0, message_render.getRRCount(Section::AUTHORITY()));
-    EXPECT_EQ(0, message_render.getRRCount(Section::ADDITIONAL()));
+    message_render.addRRset(Message::SECTION_ANSWER, rrset_a);
+
+    EXPECT_EQ(1, message_render.getRRCount(Message::SECTION_QUESTION));
+    EXPECT_EQ(2, message_render.getRRCount(Message::SECTION_ANSWER));
+    EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_AUTHORITY));
+    EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_ADDITIONAL));
 
     message_render.toWire(renderer);
     vector<unsigned char> data;

Modified: branches/trac397focused/src/lib/dns/tests/name_unittest.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/tests/name_unittest.cc (original)
+++ branches/trac397focused/src/lib/dns/tests/name_unittest.cc Mon Dec 20 08:19:35 2010
@@ -348,8 +348,8 @@
 
     UnitTestUtil::readWireData(string("01610376697803636f6d00"), data);
     Name("a.vix.com.").toWire(buffer);
-    EXPECT_EQ(true, buffer.getLength() == data.size() &&
-              memcmp(buffer.getData(), &data[0], data.size()) == 0);
+    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, &data[0], data.size(),
+                        buffer.getData(), buffer.getLength());
 }
 
 //
@@ -363,8 +363,8 @@
 
     UnitTestUtil::readWireData(string("01610376697803636f6d00"), data);
     Name("a.vix.com.").toWire(renderer);
-    EXPECT_EQ(true, buffer.getLength() == data.size() &&
-              memcmp(buffer.getData(), &data[0], data.size()) == 0);
+    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, &data[0], data.size(),
+                        buffer.getData(), buffer.getLength());
 }
 
 //
@@ -434,9 +434,9 @@
 }
 
 TEST_F(NameTest, isWildcard) {
-    EXPECT_EQ(false, example_name.isWildcard());
-    EXPECT_EQ(true, Name("*.a.example.com").isWildcard());
-    EXPECT_EQ(false, Name("a.*.example.com").isWildcard());
+    EXPECT_FALSE(example_name.isWildcard());
+    EXPECT_TRUE(Name("*.a.example.com").isWildcard());
+    EXPECT_FALSE(Name("a.*.example.com").isWildcard());
 }
 
 TEST_F(NameTest, concatenate) {

Modified: branches/trac397focused/src/lib/dns/tests/rdata_ns_unittest.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/tests/rdata_ns_unittest.cc (original)
+++ branches/trac397focused/src/lib/dns/tests/rdata_ns_unittest.cc Mon Dec 20 08:19:35 2010
@@ -112,7 +112,7 @@
 TEST_F(Rdata_NS_Test, compare) {
     generic::NS small("a.example");
     generic::NS large("example");
-    EXPECT_EQ(true, Name("a.example") > Name("example"));
+    EXPECT_TRUE(Name("a.example") > Name("example"));
     EXPECT_GT(0, small.compare(large));
 }
 

Modified: branches/trac397focused/src/lib/dns/tests/rdata_ptr_unittest.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/tests/rdata_ptr_unittest.cc (original)
+++ branches/trac397focused/src/lib/dns/tests/rdata_ptr_unittest.cc Mon Dec 20 08:19:35 2010
@@ -116,7 +116,7 @@
 TEST_F(Rdata_PTR_Test, compare) {
     generic::PTR small("a.example");
     generic::PTR large("example");
-    EXPECT_EQ(true, Name("a.example") > Name("example"));
+    EXPECT_TRUE(Name("a.example") > Name("example"));
     EXPECT_GT(0, small.compare(large));
 }
 

Modified: branches/trac397focused/src/lib/dns/tests/rdata_unittest.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/tests/rdata_unittest.cc (original)
+++ branches/trac397focused/src/lib/dns/tests/rdata_unittest.cc Mon Dec 20 08:19:35 2010
@@ -283,7 +283,7 @@
 
     // Check the case where the order is different from the owner name
     // comparison:
-    EXPECT_EQ(true, small > large);
+    EXPECT_TRUE(small > large);
     EXPECT_EQ(-1, compareNames(small, large));
     EXPECT_EQ(1, compareNames(large, small));
 

Modified: branches/trac397focused/src/lib/dns/tests/rrset_unittest.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/tests/rrset_unittest.cc (original)
+++ branches/trac397focused/src/lib/dns/tests/rrset_unittest.cc Mon Dec 20 08:19:35 2010
@@ -117,8 +117,7 @@
 addRdataTestCommon(const RRset& rrset) {
     EXPECT_EQ(2, rrset.getRdataCount());
 
-    RdataIteratorPtr it = rrset.getRdataIterator();
-    it->first();
+    RdataIteratorPtr it = rrset.getRdataIterator(); // cursor is set to the 1st
     EXPECT_FALSE(it->isLast());
     EXPECT_EQ(0, it->getCurrent().compare(in::A("192.0.2.1")));
     it->next();
@@ -156,7 +155,6 @@
 TEST_F(RRsetTest, iterator) {
     // Iterator for an empty RRset.
     RdataIteratorPtr it = rrset_a_empty.getRdataIterator();
-    it->first();
     EXPECT_TRUE(it->isLast());
 
     // Normal case (already tested, but do it again just in case)

Modified: branches/trac397focused/src/lib/dns/tests/rrsetlist_unittest.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/tests/rrsetlist_unittest.cc (original)
+++ branches/trac397focused/src/lib/dns/tests/rrsetlist_unittest.cc Mon Dec 20 08:19:35 2010
@@ -150,7 +150,6 @@
 
     RdataIteratorPtr it =
         list.findRRset(RRType::A(), RRClass::IN())->getRdataIterator();
-    it->first();
     EXPECT_FALSE(it->isLast());
     EXPECT_EQ("192.0.2.1", it->getCurrent().toText());
 }

Modified: branches/trac397focused/src/lib/dns/tests/testdata/Makefile.am
==============================================================================
--- branches/trac397focused/src/lib/dns/tests/testdata/Makefile.am (original)
+++ branches/trac397focused/src/lib/dns/tests/testdata/Makefile.am Mon Dec 20 08:19:35 2010
@@ -12,12 +12,21 @@
 BUILT_SOURCES += rdata_soa_toWireUncompressed.wire
 BUILT_SOURCES +=  rdata_txt_fromWire2.wire rdata_txt_fromWire3.wire
 BUILT_SOURCES += rdata_txt_fromWire4.wire rdata_txt_fromWire5.wire
+BUILT_SOURCES += rdata_tsig_fromWire1.wire rdata_tsig_fromWire2.wire
+BUILT_SOURCES += rdata_tsig_fromWire3.wire rdata_tsig_fromWire4.wire
+BUILT_SOURCES += rdata_tsig_fromWire5.wire rdata_tsig_fromWire6.wire
+BUILT_SOURCES += rdata_tsig_fromWire7.wire rdata_tsig_fromWire8.wire
+BUILT_SOURCES += rdata_tsig_fromWire9.wire
+BUILT_SOURCES += rdata_tsig_toWire1.wire rdata_tsig_toWire2.wire
+BUILT_SOURCES += rdata_tsig_toWire3.wire rdata_tsig_toWire4.wire
+BUILT_SOURCES += rdata_tsig_toWire5.wire
 
 # NOTE: keep this in sync with real file listing
 # so is included in tarball
 EXTRA_DIST = gen-wiredata.py.in
 EXTRA_DIST += edns_toWire1.spec edns_toWire2.spec
 EXTRA_DIST += edns_toWire3.spec edns_toWire4.spec
+EXTRA_DIST += masterload.txt
 EXTRA_DIST += message_fromWire1 message_fromWire2
 EXTRA_DIST += message_fromWire3 message_fromWire4
 EXTRA_DIST += message_fromWire5 message_fromWire6
@@ -51,6 +60,14 @@
 EXTRA_DIST += rrcode16_fromWire1 rrcode16_fromWire2
 EXTRA_DIST += rrcode32_fromWire1 rrcode32_fromWire2
 EXTRA_DIST += rrset_toWire1 rrset_toWire2
+EXTRA_DIST += rdata_tsig_fromWire1.spec rdata_tsig_fromWire2.spec
+EXTRA_DIST += rdata_tsig_fromWire3.spec rdata_tsig_fromWire4.spec
+EXTRA_DIST += rdata_tsig_fromWire5.spec rdata_tsig_fromWire6.spec
+EXTRA_DIST += rdata_tsig_fromWire7.spec rdata_tsig_fromWire8.spec
+EXTRA_DIST += rdata_tsig_fromWire9.spec
+EXTRA_DIST += rdata_tsig_toWire1.spec rdata_tsig_toWire2.spec
+EXTRA_DIST += rdata_tsig_toWire3.spec rdata_tsig_toWire4.spec
+EXTRA_DIST += rdata_tsig_toWire5.spec
 
 .spec.wire:
 	./gen-wiredata.py -o $@ $<

Modified: branches/trac397focused/src/lib/dns/tests/testdata/edns_toWire4.spec
==============================================================================
--- branches/trac397focused/src/lib/dns/tests/testdata/edns_toWire4.spec (original)
+++ branches/trac397focused/src/lib/dns/tests/testdata/edns_toWire4.spec Mon Dec 20 08:19:35 2010
@@ -1,5 +1,6 @@
 #
-# Same as edns_toWire1 but setting the DO bit
+# Same as edns_toWire1 but setting the DO bit, and using an unusual
+# UDP payload size
 #
 [edns]
 do: 1

Modified: branches/trac397focused/src/lib/dns/tests/testdata/gen-wiredata.py.in
==============================================================================
--- branches/trac397focused/src/lib/dns/tests/testdata/gen-wiredata.py.in (original)
+++ branches/trac397focused/src/lib/dns/tests/testdata/gen-wiredata.py.in Mon Dec 20 08:19:35 2010
@@ -19,8 +19,8 @@
 from datetime import datetime
 from optparse import OptionParser
 
-re_hex = re.compile(r'0x[0-9a-fA-F]+')
-re_decimal = re.compile(r'\d+$')
+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'
@@ -48,9 +48,12 @@
                 'maila' : 254, 'any' : 255 }
 rdict_rrtype = dict([(dict_rrtype[k], k.upper()) for k in dict_rrtype.keys()])
 dict_rrclass = { 'in' : 1, 'ch' : 3, 'hs' : 4, 'any' : 255 }
-rdict_rrclass = dict([(dict_rrclass[k], k.upper()) for k in dict_rrclass.keys()])
-dict_algorithm = { 'rsamd5' : 1, 'dh' : 2, 'dsa' : 3, 'ecc' : 4, 'rsasha1' : 5 }
-rdict_algorithm = dict([(dict_algorithm[k], k.upper()) for k in dict_algorithm.keys()])
+rdict_rrclass = dict([(dict_rrclass[k], k.upper()) for k in \
+                          dict_rrclass.keys()])
+dict_algorithm = { 'rsamd5' : 1, 'dh' : 2, 'dsa' : 3, 'ecc' : 4,
+                   'rsasha1' : 5 }
+rdict_algorithm = dict([(dict_algorithm[k], k.upper()) for k in \
+                            dict_algorithm.keys()])
 
 header_xtables = { 'qr' : dict_qr, 'opcode' : dict_opcode,
                    'rcode' : dict_rcode }
@@ -75,13 +78,17 @@
         return dict[code] + '(' + str(code) + ')'
     return str(code)
 
-def encode_name(name, absolute = True):
+def encode_name(name, absolute=True):
     # make sure the name is dot-terminated.  duplicate dots will be ignored
     # below.
     name += '.'
     labels = name.split('.')
     wire = ''
     for l in labels:
+        if len(l) > 4 and l[0:4] == 'ptr=':
+            # special meta-syntax for compression pointer
+            wire += ' %04x' % (0xc000 | int(l[4:]))
+            break
         if absolute or len(l) > 0:
             wire += '%02x' % len(l)
             wire += ''.join(['%02x' % ord(ch) for ch in l])
@@ -89,7 +96,9 @@
             break
     return wire
 
-def encode_string(name):
+def encode_string(name, len=None):
+    if type(name) is int and len is not None:
+        return '%0.*x' % (len * 2, name)
     return ''.join(['%02x' % ord(ch) for ch in name])
 
 def count_namelabels(name):
@@ -121,17 +130,19 @@
 
 class Name:
     name = 'example.com'
-    pointer = -1                # no compression by default
-    def dump(self, f):
-        name_wire = encode_name(self.name,
-                                True if self.pointer == -1 else False)
+    pointer = None                # no compression by default
+    def dump(self, f):
+        name = self.name
+        if self.pointer is not None:
+            if len(name) > 0 and name[-1] != '.':
+                name += '.'
+            name += 'ptr=%d' % self.pointer
+        name_wire = encode_name(name)
         f.write('\n# DNS Name: %s' % self.name)
-        if self.pointer >= 0:
+        if self.pointer is not None:
             f.write(' + compression pointer: %d' % self.pointer)
         f.write('\n')
         f.write('%s' % name_wire)
-        if self.pointer >= 0:
-            f.write(' %04x' % (0xc000 | self.pointer))
         f.write('\n')
 
 class DNSHeader:
@@ -338,20 +349,73 @@
                 (code_totext(self.covered, rdict_rrtype),
                  code_totext(self.algorithm, rdict_algorithm), labels,
                  self.originalttl))
-        f.write('%04x %02x %02x %08x\n' % (self.covered, self.algorithm, labels,
-                                           self.originalttl))
+        f.write('%04x %02x %02x %08x\n' % (self.covered, self.algorithm,
+                                           labels, self.originalttl))
         f.write('# Expiration=%s, Inception=%s\n' %
                 (str(self.expiration), str(self.inception)))
         f.write('%08x %08x\n' % (self.expiration, self.inception))
         f.write('# Tag=%d Signer=%s and Signature\n' % (self.tag, self.signer))
         f.write('%04x %s %s\n' % (self.tag, name_wire, sig_wire))
 
+class TSIG:
+    rdlen = None                # auto-calculate
+    algorithm = 'hmac-sha256'
+    time_signed = 1286978795    # arbitrarily chosen default
+    fudge = 300
+    mac_size = None             # use a common value for the algorithm
+    mac = None                  # use 'x' * mac_size
+    original_id = 2845          # arbitrarily chosen default
+    error = 0
+    other_len = None         # 6 if error is BADTIME; otherwise 0
+    other_data = None        # use time_signed + fudge + 1 for BADTIME
+    dict_macsize = { 'hmac-md5' : 16, 'hmac-sha1' : 20, 'hmac-sha256' : 32 }
+    def dump(self, f):
+        if str(self.algorithm) == 'hmac-md5':
+            name_wire = encode_name('hmac-md5.sig-alg.reg.int')
+        else:
+            name_wire = encode_name(self.algorithm)
+        rdlen = self.rdlen
+        mac_size = self.mac_size
+        if mac_size is None:
+            if self.algorithm in self.dict_macsize.keys():
+                mac_size = self.dict_macsize[self.algorithm]
+            else:
+                raise RuntimeError('TSIG Mac Size cannot be determined')
+        mac = encode_string('x' * mac_size) if self.mac is None else \
+            encode_string(self.mac, mac_size)
+        other_len = self.other_len
+        if other_len is None:
+            # 18 = BADTIME
+            other_len = 6 if self.error == 18 else 0
+        other_data = self.other_data
+        if other_data is None:
+            other_data = '%012x' % (self.time_signed + self.fudge + 1) \
+                if self.error == 18 else ''
+        else:
+            other_data = encode_string(self.other_data, other_len)
+        if rdlen is None:
+            rdlen = int(len(name_wire) / 2 + 16 + len(mac) / 2 + \
+                            len(other_data) / 2)
+        f.write('\n# TSIG RDATA (RDLEN=%d)\n' % rdlen)
+        f.write('%04x\n' % rdlen);
+        f.write('# Algorithm=%s Time-Signed=%d Fudge=%d\n' %
+                (self.algorithm, self.time_signed, self.fudge))
+        f.write('%s %012x %04x\n' % (name_wire, self.time_signed, self.fudge))
+        f.write('# MAC Size=%d MAC=(see hex)\n' % mac_size)
+        f.write('%04x%s\n' % (mac_size, ' ' + mac if len(mac) > 0 else ''))
+        f.write('# Original-ID=%d Error=%d\n' % (self.original_id, self.error))
+        f.write('%04x %04x\n' %  (self.original_id, self.error))
+        f.write('# Other-Len=%d Other-Data=(see hex)\n' % other_len)
+        f.write('%04x%s\n' % (other_len,
+                              ' ' + other_data if len(other_data) > 0 else ''))
+
 def get_config_param(section):
     config_param = {'name' : (Name, {}),
                     'header' : (DNSHeader, header_xtables),
                     'question' : (DNSQuestion, question_xtables),
                     'edns' : (EDNS, {}), 'soa' : (SOA, {}), 'txt' : (TXT, {}),
-                    'rrsig' : (RRSIG, {}), 'nsec' : (NSEC, {})}
+                    'rrsig' : (RRSIG, {}), 'nsec' : (NSEC, {}),
+                    'tsig' : (TSIG, {}) }
     s = section
     m = re.match('^([^:]+)/\d+$', section)
     if m:

Modified: branches/trac397focused/src/lib/dns/tests/unittest_util.cc
==============================================================================
--- branches/trac397focused/src/lib/dns/tests/unittest_util.cc (original)
+++ branches/trac397focused/src/lib/dns/tests/unittest_util.cc Mon Dec 20 08:19:35 2010
@@ -132,10 +132,7 @@
 }
 
 ::testing::AssertionResult
-UnitTestUtil::matchWireData(const char* dataexp1 UNUSED_PARAM,
-                            const char* lenexp1 UNUSED_PARAM,
-                            const char* dataexp2 UNUSED_PARAM,
-                            const char* lenexp2 UNUSED_PARAM,
+UnitTestUtil::matchWireData(const char*, const char*, const char*, const char*,
                             const void* data1, size_t len1,
                             const void* data2, size_t len2)
 {
@@ -162,8 +159,7 @@
 }
 
 ::testing::AssertionResult
-UnitTestUtil::matchName(const char* nameexp1 UNUSED_PARAM,
-                        const char* nameexp2 UNUSED_PARAM,
+UnitTestUtil::matchName(const char*, const char*,
                         const isc::dns::Name& name1,
                         const isc::dns::Name& name2)
 {

Modified: branches/trac397focused/src/lib/exceptions/exceptions.h
==============================================================================
--- branches/trac397focused/src/lib/exceptions/exceptions.h (original)
+++ branches/trac397focused/src/lib/exceptions/exceptions.h Mon Dec 20 08:19:35 2010
@@ -40,7 +40,7 @@
     /// file line number.
     ///
     /// @param file the file name where the exception was thrown.
-    /// @param line the line in @ref file where the exception was thrown.
+    /// @param line the line in \a file where the exception was thrown.
     /// @param what a description (type) of the exception.
     Exception(const char* file, size_t line, const char* what) :
         file_(file), line_(line), what_(what) {}
@@ -49,7 +49,7 @@
     /// file line number.
     ///
     /// @param file the file name where the exception was thrown.
-    /// @param line the line in @ref file where the exception was thrown.
+    /// @param line the line in \a file where the exception was thrown.
     /// @param what a description (type) of the exception.
     Exception(const char* file, size_t line, const std::string& what) :
         file_(file), line_(line), what_(what) {}

Modified: branches/trac397focused/src/lib/python/isc/Makefile.am
==============================================================================
--- branches/trac397focused/src/lib/python/isc/Makefile.am (original)
+++ branches/trac397focused/src/lib/python/isc/Makefile.am Mon Dec 20 08:19:35 2010
@@ -1,4 +1,4 @@
-SUBDIRS = datasrc cc config log net notify utils # Util
+SUBDIRS = datasrc cc config log net notify util 
 
 python_PYTHON = __init__.py
 

Modified: branches/trac397focused/src/lib/python/isc/cc/data.py
==============================================================================
--- branches/trac397focused/src/lib/python/isc/cc/data.py (original)
+++ branches/trac397focused/src/lib/python/isc/cc/data.py Mon Dec 20 08:19:35 2010
@@ -31,10 +31,8 @@
     to_remove = []
     if type(a) != dict or type(b) != dict:
         raise DataTypeError("Not a dict in remove_identical()")
-    for ka in a.keys():
-        if ka in b and a[ka] == b[ka]:
-            to_remove.append(ka)
-    for id in to_remove:
+    duplicate_keys = [key for key in a.keys() if key in b and a[key] == b[key]]
+    for id in duplicate_keys:
         del(a[id])
 
 def merge(orig, new):
@@ -43,32 +41,131 @@
        new it will be removed in orig."""
     if type(orig) != dict or type(new) != dict:
         raise DataTypeError("Not a dict in merge()")
-    for kn in new.keys():
-        if kn in orig:
-            if new[kn]:
-                if type(new[kn]) == dict:
-                    merge(orig[kn], new[kn])
-                else:
-                    orig[kn] = new[kn]
-            else:
-                del orig[kn]
-        else:
-            orig[kn] = new[kn]
+    orig.update(new)
+    remove_null_items(orig)
+
+def remove_null_items(d):
+    """Recursively removes all (key,value) pairs from d where the
+       value is None"""
+    null_keys = []
+    for key in d.keys():
+        if type(d[key]) == dict:
+            remove_null_items(d[key])
+        elif d[key] is None:
+            null_keys.append(key)
+    for k in null_keys:
+        del d[k]
+
+def _concat_identifier(id_parts):
+    """Concatenates the given identifier parts into a string,
+       delimited with the '/' character.
+    """
+    return '/'.join(id_parts)
+
+def split_identifier(identifier):
+    """Splits the given identifier into a list of identifier parts,
+       as delimited by the '/' character.
+       Raises a DataTypeError if identifier is not a string."""
+    if type(identifier) != str:
+        raise DataTypeError("identifier is not a string")
+    id_parts = identifier.split('/')
+    id_parts[:] = (value for value in id_parts if value != "")
+    return id_parts
+
+def split_identifier_list_indices(identifier):
+    """Finds list indexes in the given identifier, which are of the
+       format [integer].
+       Identifier must be a string.
+       This will only give the list index for the last 'part' of the
+       given identifier (as delimited by the '/' sign).
+       Raises a DataTypeError if the identifier is not a string,
+       or if the format is bad.
+       Returns a tuple, where the first element is the string part of
+       the identifier, and the second element is a list of (nested) list
+       indices.
+       Examples:
+       'a/b/c' will return ('a/b/c', None)
+       'a/b/c[1]' will return ('a/b/c', [1])
+       'a/b/c[1][2][3]' will return ('a/b/c', [1, 2, 3])
+       'a[0]/b[1]/c[2]' will return ('a[0]/b[1]/c', [2])
+    """
+    if type(identifier) != str:
+        raise DataTypeError("identifier in "
+                            "split_identifier_list_indices() "
+                            "not a string: " + str(identifier))
+
+    # We only work on the final 'part' of the identifier
+    id_parts = split_identifier(identifier)
+    id_str = id_parts[-1]
+
+    i = id_str.find('[')
+    if i < 0:
+        if identifier.find(']') >= 0:
+            raise DataTypeError("Bad format in identifier: " + str(identifier))
+        return identifier, None
+
+    # keep the non-index part of that to replace later
+    id = id_str[:i]
+    indices = []
+    while i >= 0:
+        e = id_str.find(']')
+        if e < i + 1:
+            raise DataTypeError("Bad format in identifier: " + str(identifier))
+        try:
+            indices.append(int(id_str[i+1:e]))
+        except ValueError:
+            raise DataTypeError("List index in " + identifier + " not an integer")
+        id_str = id_str[e + 1:]
+        i = id_str.find('[')
+        if i > 0:
+            raise DataTypeError("Bad format in identifier: " + str(identifier))
+    if id.find(']') >= 0 or len(id_str) > 0:
+        raise DataTypeError("Bad format in identifier: " + str(identifier))
+
+    # we replace the final part of the original identifier with
+    # the stripped string
+    id_parts[-1] = id
+    id = _concat_identifier(id_parts)
+    return id, indices
+
+def _find_child_el(element, id):
+    """Finds the child of element with the given id. If the id contains
+       [i], where i is a number, and the child element is a list, the
+       i-th element of that list is returned instead of the list itself.
+       Raises a DataTypeError if the element is of wrong type, if id
+       is not a string, or if the id string contains a bad value.
+       Raises a DataNotFoundError if the element at id could not be
+       found.
+    """
+    id, list_indices = split_identifier_list_indices(id)
+    if type(element) == dict and id in element.keys():
+        result = element[id]
+    else:
+        raise DataNotFoundError(id + " in " + str(element))
+    if type(result) == list and list_indices is not None:
+        for list_index in list_indices:
+            if list_index >= len(result):
+                raise DataNotFoundError("Element " + str(list_index) + " in " + str(result))
+            result = result[list_index]
+    return result
 
 def find(element, identifier):
-    """Returns the subelement in the given data element, raises DataNotFoundError if not found"""
-    if type(identifier) != str or (type(element) != dict and identifier != ""):
-        raise DataTypeError("identifier in merge() is not a string")
-    if type(identifier) != str or (type(element) != dict and identifier != ""):
-        raise DataTypeError("element in merge() is not a dict")
-    id_parts = identifier.split("/")
-    id_parts[:] = (value for value in id_parts if value != "")
+    """Returns the subelement in the given data element, raises
+       DataNotFoundError if not found.
+       Returns the given element if the identifier is an empty string.
+       Raises a DataTypeError if identifier is not a string, or if
+       identifier is not empty, and element is not a dict.
+    """
+    if type(identifier) != str:
+        raise DataTypeError("identifier in find() is not a str")
+    if identifier == "":
+        return element
+    if type(element) != dict:
+        raise DataTypeError("element in find() is not a dict")
+    id_parts = split_identifier(identifier)
     cur_el = element
     for id in id_parts:
-        if type(cur_el) == dict and id in cur_el.keys():
-            cur_el = cur_el[id]
-        else:
-            raise DataNotFoundError(identifier + " in " + str(element))
+        cur_el = _find_child_el(cur_el, id)
     return cur_el
 
 def set(element, identifier, value):
@@ -82,25 +179,46 @@
     if type(element) != dict:
         raise DataTypeError("element in set() is not a dict")
     if type(identifier) != str:
-        raise DataTypeError("identifier in set() is not a string")
-    id_parts = identifier.split("/")
-    id_parts[:] = (value for value in id_parts if value != "")
+        raise DataTypeError("identifier in set() is not a str")
+    id_parts = split_identifier(identifier)
     cur_el = element
     for id in id_parts[:-1]:
-        if id in cur_el.keys():
-            cur_el = cur_el[id]
-        else:
-            if value == None:
+        try:
+            cur_el = _find_child_el(cur_el, id)
+        except DataNotFoundError:
+            if value is None:
                 # ok we are unsetting a value that wasn't set in
                 # the first place. Simply stop.
                 return
             cur_el[id] = {}
             cur_el = cur_el[id]
-    # value can be an empty list or dict, so check for None eplicitely
-    if value != None:
-        cur_el[id_parts[-1]] = value
-    elif id_parts[-1] in cur_el:
-        del cur_el[id_parts[-1]]
+
+    id, list_indices = split_identifier_list_indices(id_parts[-1])
+    if list_indices is None:
+        # value can be an empty list or dict, so check for None eplicitely
+        if value is not None:
+            cur_el[id] = value
+        else:
+            del cur_el[id]
+    else:
+        cur_el = cur_el[id]
+        # in case of nested lists, we need to get to the next to last
+        for list_index in list_indices[:-1]:
+            if type(cur_el) != list:
+                raise DataTypeError("Element at " + identifier + " is not a list")
+            if len(cur_el) <= list_index:
+                raise DataNotFoundError("List index at " + identifier + " out of range")
+            cur_el = cur_el[list_index]
+        # value can be an empty list or dict, so check for None eplicitely
+        list_index = list_indices[-1]
+        if type(cur_el) != list:
+            raise DataTypeError("Element at " + identifier + " is not a list")
+        if len(cur_el) <= list_index:
+            raise DataNotFoundError("List index at " + identifier + " out of range")
+        if value is not None:
+            cur_el[list_index] = value
+        else:
+            del cur_el[list_index]
     return element
 
 def unset(element, identifier):
@@ -115,17 +233,12 @@
     """Returns the subelement in the given data element, returns None
        if not found, or if an error occurred (i.e. this function should
        never raise an exception)"""
-    if type(identifier) != str:
+    try:
+        return find(element, identifier)
+    except DataNotFoundError:
         return None
-    id_parts = identifier.split("/")
-    id_parts[:] = (value for value in id_parts if value != "")
-    cur_el = element
-    for id in id_parts:
-        if (type(cur_el) == dict and id in cur_el.keys()) or id=="":
-            cur_el = cur_el[id]
-        else:
-            return None
-    return cur_el
+    except DataTypeError:
+        return None
 
 def parse_value_str(value_str):
     """Parses the given string to a native python object. If the
@@ -138,7 +251,4 @@
     except ValueError as ve:
         # simply return the string itself
         return value_str
-    except SyntaxError as ve:
-        # simply return the string itself
-        return value_str
-
+

Modified: branches/trac397focused/src/lib/python/isc/cc/session.py
==============================================================================
--- branches/trac397focused/src/lib/python/isc/cc/session.py (original)
+++ branches/trac397focused/src/lib/python/isc/cc/session.py Mon Dec 20 08:19:35 2010
@@ -78,6 +78,8 @@
                 raise SessionError("Session has been closed.")
             if type(env) == dict:
                 env = isc.cc.message.to_wire(env)
+            if len(env) > 65535:
+                raise ProtocolError("Envelope too large")
             if type(msg) == dict:
                 msg = isc.cc.message.to_wire(msg)
             self._socket.setblocking(1)
@@ -113,9 +115,6 @@
                     if (seq == None and "reply" not in env) or (seq != None and "reply" in env and seq == env["reply"]):
                         return env, msg
                     else:
-                        tmp = None
-                        if "reply" in env:
-                            tmp = env["reply"]
                         self._queue.append((env,msg))
                         return self.recvmsg(nonblock, seq)
                 else:

Modified: branches/trac397focused/src/lib/python/isc/cc/tests/data_test.py
==============================================================================
--- branches/trac397focused/src/lib/python/isc/cc/tests/data_test.py (original)
+++ branches/trac397focused/src/lib/python/isc/cc/tests/data_test.py Mon Dec 20 08:19:35 2010
@@ -70,6 +70,11 @@
         c = { "a": { "b": "c" } }
         data.remove_identical(a, b)
         self.assertEqual(a, c)
+
+        self.assertRaises(data.DataTypeError, data.remove_identical,
+                          a, 1)
+        self.assertRaises(data.DataTypeError, data.remove_identical,
+                          1, b)
         
     def test_merge(self):
         d1 = { 'a': 'a', 'b': 1, 'c': { 'd': 'd', 'e': 2 } }
@@ -81,6 +86,45 @@
         self.assertRaises(data.DataTypeError, data.merge, d1, "a")
         self.assertRaises(data.DataTypeError, data.merge, 1, d2)
         self.assertRaises(data.DataTypeError, data.merge, None, None)
+
+
+    def test_split_identifier_list_indices(self):
+        id, indices = data.split_identifier_list_indices('a')
+        self.assertEqual(id, 'a')
+        self.assertEqual(indices, None)
+        id, indices = data.split_identifier_list_indices('a[0]')
+        self.assertEqual(id, 'a')
+        self.assertEqual(indices, [0])
+        id, indices = data.split_identifier_list_indices('a[0][1]')
+        self.assertEqual(id, 'a')
+        self.assertEqual(indices, [0, 1])
+
+        # examples from the docstring
+        id, indices = data.split_identifier_list_indices('a/b/c')
+        self.assertEqual(id, 'a/b/c')
+        self.assertEqual(indices, None)
+        
+        id, indices = data.split_identifier_list_indices('a/b/c[1]')
+        self.assertEqual(id, 'a/b/c')
+        self.assertEqual(indices, [1])
+       
+        id, indices = data.split_identifier_list_indices('a/b/c[1][2][3]')
+        self.assertEqual(id, 'a/b/c')
+        self.assertEqual(indices, [1, 2, 3])
+        
+        id, indices = data.split_identifier_list_indices('a[0]/b[1]/c[2]')
+        self.assertEqual(id, 'a[0]/b[1]/c')
+        self.assertEqual(indices, [2])
+
+        # bad formats
+        self.assertRaises(data.DataTypeError, data.split_identifier_list_indices, 'a[')
+        self.assertRaises(data.DataTypeError, data.split_identifier_list_indices, 'a]')
+        self.assertRaises(data.DataTypeError, data.split_identifier_list_indices, 'a[[0]]')
+        self.assertRaises(data.DataTypeError, data.split_identifier_list_indices, 'a[0]a')
+        self.assertRaises(data.DataTypeError, data.split_identifier_list_indices, 'a[0]a[1]')
+
+        self.assertRaises(data.DataTypeError, data.split_identifier_list_indices, 1)
+        
 
     def test_find(self):
         d1 = { 'a': 'a', 'b': 1, 'c': { 'd': 'd', 'e': 2, 'more': { 'data': 'here' } } }
@@ -93,19 +137,47 @@
         self.assertRaises(data.DataNotFoundError, data.find, d1, 'f')
         self.assertRaises(data.DataTypeError, data.find, d1, 1)
         self.assertRaises(data.DataTypeError, data.find, None, 1)
+        self.assertRaises(data.DataTypeError, data.find, None, "foo")
         self.assertRaises(data.DataTypeError, data.find, "123", "123")
         self.assertEqual(data.find("123", ""), "123")
+
+        d2 = { 'a': [ 1, 2, 3 ] }
+        self.assertEqual(data.find(d2, 'a[0]'), 1)
+        self.assertEqual(data.find(d2, 'a[1]'), 2)
+        self.assertEqual(data.find(d2, 'a[2]'), 3)
+        self.assertRaises(data.DataNotFoundError, data.find, d2, 'a[3]')
+        self.assertRaises(data.DataTypeError, data.find, d2, 'a[a]')
+
+        d3 = { 'a': [ { 'b': [ {}, { 'c': 'd' } ] } ] }
+        self.assertEqual(data.find(d3, 'a[0]/b[1]/c'), 'd')
+        self.assertRaises(data.DataNotFoundError, data.find, d3, 'a[1]/b[1]/c')
         
     def test_set(self):
         d1 = { 'a': 'a', 'b': 1, 'c': { 'd': 'd', 'e': 2 } }
         d12 = { 'b': 1, 'c': { 'e': 3, 'f': [ 1 ] } }
+        d13 = { 'b': 1, 'c': { 'e': 3, 'f': [ 2 ] } }
+        d14 = { 'b': 1, 'c': { 'e': 3, 'f': [ { 'g': [ 1, 2 ] } ] } }
+        d15 = { 'b': 1, 'c': { 'e': 3, 'f': [ { 'g': [ 1, 3 ] } ] } }
         data.set(d1, 'a', None)
         data.set(d1, 'c/d', None)
         data.set(d1, 'c/e/', 3)
         data.set(d1, 'c/f', [ 1 ] )
         self.assertEqual(d1, d12)
+        data.set(d1, 'c/f[0]', 2 )
+        self.assertEqual(d1, d13)
+
+        data.set(d1, 'c/f[0]', { 'g': [ 1, 2] } )
+        self.assertEqual(d1, d14)
+        data.set(d1, 'c/f[0]/g[1]', 3)
+        self.assertEqual(d1, d15)
+        
         self.assertRaises(data.DataTypeError, data.set, d1, 1, 2)
         self.assertRaises(data.DataTypeError, data.set, 1, "", 2)
+        self.assertRaises(data.DataTypeError, data.set, d1, 'c[1]', 2)
+        self.assertRaises(data.DataTypeError, data.set, d1, 'c[1][2]', 2)
+        self.assertRaises(data.DataNotFoundError, data.set, d1, 'c/f[5]', 2)
+        self.assertRaises(data.DataNotFoundError, data.set, d1, 'c/f[5][2]', 2)
+
         d3 = {}
         e3 = data.set(d3, "does/not/exist", 123)
         self.assertEqual(d3,
@@ -114,11 +186,25 @@
                          { 'does': { 'not': { 'exist': 123 } } })
 
     def test_unset(self):
-        d1 = { 'a': 'a', 'b': 1, 'c': { 'd': 'd', 'e': 2 } }
+        d1 = { 'a': 'a', 'b': 1, 'c': { 'd': 'd', 'e': [ 1, 2, 3 ] } }
         data.unset(d1, 'a')
         data.unset(d1, 'c/d')
         data.unset(d1, 'does/not/exist')
-        self.assertEqual(d1, { 'b': 1, 'c': { 'e': 2 } })
+        self.assertEqual(d1, { 'b': 1, 'c': { 'e': [ 1, 2, 3 ] } })
+        data.unset(d1, 'c/e[0]')
+        self.assertEqual(d1, { 'b': 1, 'c': { 'e': [ 2, 3 ] } })
+        data.unset(d1, 'c/e[1]')
+        self.assertEqual(d1, { 'b': 1, 'c': { 'e': [ 2 ] } })
+        # index 1 should now be out of range
+        self.assertRaises(data.DataNotFoundError, data.unset, d1, 'c/e[1]')
+        d2 = { 'a': [ { 'b': [ 1, 2 ] } ] }
+        data.unset(d2, 'a[0]/b[1]')
+        self.assertEqual(d2, { 'a': [ { 'b': [ 1 ] } ] })
+        d3 = { 'a': [ [ 1, 2 ] ] }
+        data.set(d3, "a[0][1]", 3)
+        self.assertEqual(d3, { 'a': [ [ 1, 3 ] ] })
+        data.unset(d3, 'a[0][1]')
+        self.assertEqual(d3, { 'a': [ [ 1 ] ] })
         
     def test_find_no_exc(self):
         d1 = { 'a': 'a', 'b': 1, 'c': { 'd': 'd', 'e': 2, 'more': { 'data': 'here' } } }
@@ -146,6 +232,9 @@
         self.assertEqual(data.parse_value_str("{ \"a\": \"b\", \"c\": 1 }"), { 'a': 'b', 'c': 1 })
         self.assertEqual(data.parse_value_str("[ a c"), "[ a c")
 
+        self.assertEqual(data.parse_value_str(1), None)
+
+
 if __name__ == '__main__':
     #if not 'CONFIG_TESTDATA_PATH' in os.environ:
     #    print("You need to set the environment variable CONFIG_TESTDATA_PATH to point to the directory containing the test data files")

Modified: branches/trac397focused/src/lib/python/isc/cc/tests/session_test.py
==============================================================================
--- branches/trac397focused/src/lib/python/isc/cc/tests/session_test.py (original)
+++ branches/trac397focused/src/lib/python/isc/cc/tests/session_test.py Mon Dec 20 08:19:35 2010
@@ -137,6 +137,11 @@
         sess.close()
         self.assertRaises(SessionError, sess.sendmsg, {}, {"hello": "a"})
 
+    def test_env_too_large(self):
+        sess = MySession()
+        largeenv = { "a": "b"*65535 }
+        self.assertRaises(ProtocolError, sess.sendmsg, largeenv, {"hello": "a"})
+
     def test_session_sendmsg(self):
         sess = MySession()
         sess.sendmsg({}, {"hello": "a"})

Modified: branches/trac397focused/src/lib/python/isc/config/ccsession.py
==============================================================================
--- branches/trac397focused/src/lib/python/isc/config/ccsession.py (original)
+++ branches/trac397focused/src/lib/python/isc/config/ccsession.py Mon Dec 20 08:19:35 2010
@@ -398,16 +398,25 @@
         module_spec = self.find_spec_part(identifier)
         if (type(module_spec) != dict or "list_item_spec" not in module_spec):
             raise isc.cc.data.DataNotFoundError(str(identifier) + " is not a list")
-        value = isc.cc.data.parse_value_str(value_str)
-        isc.config.config_data.check_type(module_spec, [value])
-        cur_list, status = self.get_value(identifier)
-        #if not cur_list:
-        #    cur_list = isc.cc.data.find_no_exc(self.config.data, identifier)
-        if not cur_list:
-            cur_list = []
-        if value in cur_list:
-            cur_list.remove(value)
-        self.set_value(identifier, cur_list)
+
+        if value_str is None:
+            # we are directly removing an list index
+            id, list_indices = isc.cc.data.split_identifier_list_indices(identifier)
+            if list_indices is None:
+                raise DataTypeError("identifier in remove_value() does not contain a list index, and no value to remove")
+            else:
+                self.set_value(identifier, None)
+        else:
+            value = isc.cc.data.parse_value_str(value_str)
+            isc.config.config_data.check_type(module_spec, [value])
+            cur_list, status = self.get_value(identifier)
+            #if not cur_list:
+            #    cur_list = isc.cc.data.find_no_exc(self.config.data, identifier)
+            if not cur_list:
+                cur_list = []
+            if value in cur_list:
+                cur_list.remove(value)
+            self.set_value(identifier, cur_list)
 
     def commit(self):
         """Commit all local changes, send them through b10-cmdctl to

Modified: branches/trac397focused/src/lib/python/isc/config/config_data.py
==============================================================================
--- branches/trac397focused/src/lib/python/isc/config/config_data.py (original)
+++ branches/trac397focused/src/lib/python/isc/config/config_data.py Mon Dec 20 08:19:35 2010
@@ -22,6 +22,7 @@
 
 import isc.cc.data
 import isc.config.module_spec
+import ast
 
 class ConfigDataError(Exception): pass
 
@@ -56,14 +57,14 @@
         raise isc.cc.data.DataTypeError(str(value) + " is not a map")
 
 def convert_type(spec_part, value):
-    """Convert the give value(type is string) according specification 
+    """Convert the given value(type is string) according specification 
     part relevant for the value. Raises an isc.cc.data.DataTypeError 
     exception if conversion failed.
     """
     if type(spec_part) == dict and 'item_type' in spec_part:
         data_type = spec_part['item_type']
     else:
-        raise isc.cc.data.DataTypeError(str("Incorrect specification part for type convering"))
+        raise isc.cc.data.DataTypeError(str("Incorrect specification part for type conversion"))
    
     try:
         if data_type == "integer":
@@ -81,18 +82,25 @@
                     ret.append(convert_type(spec_part['list_item_spec'], item))
             elif type(value) == str:    
                 value = value.split(',')
-                for item in value:    
+                for item in value:
                     sub_value = item.split()
                     for sub_item in sub_value:
-                        ret.append(convert_type(spec_part['list_item_spec'], sub_item))
+                        ret.append(convert_type(spec_part['list_item_spec'],
+                                                sub_item))
 
             if ret == []:
                 raise isc.cc.data.DataTypeError(str(value) + " is not a list")
 
             return ret
         elif data_type == "map":
-            return dict(value)
-            # todo: check types of map contents too
+            map = ast.literal_eval(value)
+            if type(map) == dict:
+                # todo: check types of map contents too
+                return map
+            else:
+                raise isc.cc.data.DataTypeError(
+                           "Value in convert_type not a string "
+                           "specifying a dict")
         else:
             return value
     except ValueError as err:
@@ -108,7 +116,11 @@
     id_parts = identifier.split("/")
     id_parts[:] = (value for value in id_parts if value != "")
     cur_el = element
-    for id in id_parts:
+
+    for id_part in id_parts:
+        # strip list selector part
+        # don't need it for the spec part, so just drop it
+        id, list_indices = isc.cc.data.split_identifier_list_indices(id_part)
         if type(cur_el) == dict and 'map_item_spec' in cur_el.keys():
             found = False
             for cur_el_item in cur_el['map_item_spec']:
@@ -158,11 +170,9 @@
                     result.extend(spec_name_list(list_el['map_item_spec'], prefix + list_el['item_name'], recurse))
                 else:
                     name = list_el['item_name']
-                    if list_el['item_type'] in ["list", "map"]:
-                        name += "/"
                     result.append(prefix + name)
             else:
-                raise ConfigDataError("Bad specication")
+                raise ConfigDataError("Bad specification")
     else:
         raise ConfigDataError("Bad specication")
     return result
@@ -228,6 +238,20 @@
             result[item] = value
         return result
 
+# should we just make a class for these?
+def _create_value_map_entry(name, type, value, status = None):
+    entry = {}
+    entry['name'] = name
+    entry['type'] = type
+    entry['value'] = value
+    entry['modified'] = False
+    entry['default'] = False
+    if status == MultiConfigData.LOCAL:
+        entry['modified'] = True
+    if status == MultiConfigData.DEFAULT:
+        entry['default'] = True
+    return entry
+
 class MultiConfigData:
     """This class stores the module specs, current non-default
        configuration values and 'local' (uncommitted) changes for
@@ -272,7 +296,7 @@
            identifier (up to the first /) is interpreted as the module
            name. Returns None if not found, or if identifier is not a
            string."""
-        if type(identifier) != str:
+        if type(identifier) != str or identifier == "":
             return None
         if identifier[0] == '/':
             identifier = identifier[1:]
@@ -336,28 +360,42 @@
         try:
             spec = find_spec_part(self._specifications[module].get_config_spec(), id)
             if 'item_default' in spec:
-                return spec['item_default']
+                id, list_indices = isc.cc.data.split_identifier_list_indices(id)
+                if list_indices is not None and \
+                   type(spec['item_default']) == list:
+                    if len(list_indices) == 1:
+                        default_list = spec['item_default']
+                        index = list_indices[0]
+                        if index < len(default_list):
+                            return default_list[index]
+                        else:
+                            return None
+                else:
+                    return spec['item_default']
             else:
                 return None
         except isc.cc.data.DataNotFoundError as dnfe:
             return None
 
-    def get_value(self, identifier):
+    def get_value(self, identifier, default = True):
         """Returns a tuple containing value,status.
            The value contains the configuration value for the given
            identifier. The status reports where this value came from;
            it is one of: LOCAL, CURRENT, DEFAULT or NONE, corresponding
            (local change, current setting, default as specified by the
-           specification, or not found at all)."""
+           specification, or not found at all). Does not check and
+           set DEFAULT if the argument 'default' is False (default
+           defaults to True)"""
         value = self.get_local_value(identifier)
         if value != None:
             return value, self.LOCAL
         value = self.get_current_value(identifier)
         if value != None:
             return value, self.CURRENT
-        value = self.get_default_value(identifier)
-        if value != None:
-            return value, self.DEFAULT
+        if default:
+            value = self.get_default_value(identifier)
+            if value != None:
+                return value, self.DEFAULT
         return None, self.NONE
 
     def get_value_maps(self, identifier = None):
@@ -374,12 +412,7 @@
         if not identifier:
             # No identifier, so we need the list of current modules
             for module in self._specifications.keys():
-                entry = {}
-                entry['name'] = module
-                entry['type'] = 'module'
-                entry['value'] = None
-                entry['modified'] = False
-                entry['default'] = False
+                entry = _create_value_map_entry(module, 'module', None)
                 result.append(entry)
         else:
             if identifier[0] == '/':
@@ -389,51 +422,41 @@
             if spec:
                 spec_part = find_spec_part(spec.get_config_spec(), id)
                 if type(spec_part) == list:
+                    # list of items to show
                     for item in spec_part:
-                        entry = {}
-                        entry['name'] = item['item_name']
-                        entry['type'] = item['item_type']
-                        value, status = self.get_value("/" + identifier + "/" + item['item_name'])
-                        entry['value'] = value
-                        if status == self.LOCAL:
-                            entry['modified'] = True
-                        else:
-                            entry['modified'] = False
-                        if status == self.DEFAULT:
-                            entry['default'] = False
-                        else:
-                            entry['default'] = False
+                        value, status = self.get_value("/" + identifier\
+                                              + "/" + item['item_name'])
+                        entry = _create_value_map_entry(item['item_name'],
+                                                        item['item_type'],
+                                                        value, status)
                         result.append(entry)
                 elif type(spec_part) == dict:
+                    # Sub-specification
                     item = spec_part
                     if item['item_type'] == 'list':
                         li_spec = item['list_item_spec']
-                        item_list, status =  self.get_value("/" + identifier)
-                        if item_list != None:
-                            for value in item_list:
-                                result_part2 = {}
-                                result_part2['name'] = li_spec['item_name']
-                                result_part2['value'] = value
-                                result_part2['type'] = li_spec['item_type']
-                                result_part2['default'] = False
-                                result_part2['modified'] = False
+                        value, status =  self.get_value("/" + identifier)
+                        if type(value) == list:
+                            for list_value in value:
+                                result_part2 = _create_value_map_entry(
+                                                   li_spec['item_name'],
+                                                   li_spec['item_type'],
+                                                   list_value)
                                 result.append(result_part2)
+                        elif value is not None:
+                            entry = _create_value_map_entry(
+                                        li_spec['item_name'],
+                                        li_spec['item_type'],
+                                        value, status)
+                            result.append(entry)
                     else:
-                        entry = {}
-                        entry['name'] = item['item_name']
-                        entry['type'] = item['item_type']
-                        #value, status = self.get_value("/" + identifier + "/" + item['item_name'])
                         value, status = self.get_value("/" + identifier)
-                        entry['value'] = value
-                        if status == self.LOCAL:
-                            entry['modified'] = True
-                        else:
-                            entry['modified'] = False
-                        if status == self.DEFAULT:
-                            entry['default'] = False
-                        else:
-                            entry['default'] = False
-                        result.append(entry)
+                        if value is not None:
+                            entry = _create_value_map_entry(
+                                        item['item_name'],
+                                        item['item_type'],
+                                        value, status)
+                            result.append(entry)
         return result
 
     def set_value(self, identifier, value):
@@ -441,8 +464,28 @@
            there is a specification for the given identifier, the type
            is checked."""
         spec_part = self.find_spec_part(identifier)
-        if spec_part != None:
+        if spec_part is not None and value is not None:
+            id, list_indices = isc.cc.data.split_identifier_list_indices(identifier)
+            if list_indices is not None \
+               and spec_part['item_type'] == 'list':
+                spec_part = spec_part['list_item_spec']
             check_type(spec_part, value)
+
+        # Since we do not support list diffs (yet?), we need to
+        # copy the currently set list of items to _local_changes
+        # if we want to modify an element in there
+        # (for any list indices specified in the full identifier)
+        id_parts = isc.cc.data.split_identifier(identifier)
+        cur_id_part = '/'
+        for id_part in id_parts:
+            id, list_indices = isc.cc.data.split_identifier_list_indices(id_part)
+            if list_indices is not None:
+                cur_list, status = self.get_value(cur_id_part + id)
+                if status != MultiConfigData.LOCAL:
+                    isc.cc.data.set(self._local_changes,
+                                    cur_id_part + id,
+                                    cur_list)
+            cur_id_part = cur_id_part + id_part + "/"
         isc.cc.data.set(self._local_changes, identifier, value)
  
     def get_config_item_list(self, identifier = None, recurse = False):

Modified: branches/trac397focused/src/lib/python/isc/config/tests/ccsession_test.py
==============================================================================
--- branches/trac397focused/src/lib/python/isc/config/tests/ccsession_test.py (original)
+++ branches/trac397focused/src/lib/python/isc/config/tests/ccsession_test.py Mon Dec 20 08:19:35 2010
@@ -637,6 +637,8 @@
         self.assertEqual({'Spec2': {'item5': ['foo']}}, uccs._local_changes)
         uccs.add_value("Spec2/item5", "foo")
         self.assertEqual({'Spec2': {'item5': ['foo']}}, uccs._local_changes)
+        uccs.remove_value("Spec2/item5[0]", None)
+        self.assertEqual({'Spec2': {'item5': []}}, uccs._local_changes)
 
     def test_commit(self):
         fake_conn = fakeUIConn()

Modified: branches/trac397focused/src/lib/python/isc/config/tests/config_data_test.py
==============================================================================
--- branches/trac397focused/src/lib/python/isc/config/tests/config_data_test.py (original)
+++ branches/trac397focused/src/lib/python/isc/config/tests/config_data_test.py Mon Dec 20 08:19:35 2010
@@ -107,6 +107,8 @@
         self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, "a")
         self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, [ 1, 2 ])
         self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, { "a": 1 })
+        self.assertRaises(isc.cc.data.DataTypeError, convert_type, 1, "a")
+        self.assertRaises(isc.cc.data.DataTypeError, convert_type, { 'somedict': 'somevalue' }, "a")
         
         spec_part = find_spec_part(config_spec, "value2")
         self.assertEqual(1.1, convert_type(spec_part, '1.1'))
@@ -142,6 +144,18 @@
         self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, 1.1)
         self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, True)
         self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, "a")
+        self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, [ "a", "b" ])
+        self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, [ "1", "b" ])
+        self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, { "a": 1 })
+
+        spec_part = find_spec_part(config_spec, "value6")
+        self.assertEqual({}, convert_type(spec_part, '{}'))
+        self.assertEqual({ 'v61': 'a' }, convert_type(spec_part, '{ \'v61\': \'a\' }'))
+
+        self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, 1.1)
+        self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, True)
+        self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, "a")
+        self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, "1")
         self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, [ "a", "b" ])
         self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, [ "1", "b" ])
         self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, { "a": 1 })
@@ -175,9 +189,9 @@
 
     def test_spec_name_list(self):
         name_list = spec_name_list(self.cd.get_module_spec().get_config_spec())
-        self.assertEqual(['item1', 'item2', 'item3', 'item4', 'item5/', 'item6/'], name_list)
+        self.assertEqual(['item1', 'item2', 'item3', 'item4', 'item5', 'item6'], name_list)
         name_list = spec_name_list(self.cd.get_module_spec().get_config_spec(), "", True)
-        self.assertEqual(['item1', 'item2', 'item3', 'item4', 'item5/', 'item6/value1', 'item6/value2'], name_list)
+        self.assertEqual(['item1', 'item2', 'item3', 'item4', 'item5', 'item6/value1', 'item6/value2'], name_list)
         spec_part = find_spec_part(self.cd.get_module_spec().get_config_spec(), "item6")
         name_list = spec_name_list(spec_part, "item6", True)
         self.assertEqual(['item6/value1', 'item6/value2'], name_list)
@@ -193,7 +207,7 @@
         name_list = spec_name_list({ "myModule": config_spec }, "", False)
         self.assertEqual(['myModule/'], name_list)
         name_list = spec_name_list({ "myModule": config_spec }, "", True)
-        self.assertEqual(['myModule/', 'myModule/value1', 'myModule/value2', 'myModule/value3', 'myModule/value4', 'myModule/value5/', 'myModule/value6/v61', 'myModule/value6/v62', 'myModule/value7/', 'myModule/value8/', 'myModule/value9/v91', 'myModule/value9/v92/v92a', 'myModule/value9/v92/v92b'], name_list)
+        self.assertEqual(['myModule/', 'myModule/value1', 'myModule/value2', 'myModule/value3', 'myModule/value4', 'myModule/value5', 'myModule/value6/v61', 'myModule/value6/v62', 'myModule/value7', 'myModule/value8', 'myModule/value9/v91', 'myModule/value9/v92/v92a', 'myModule/value9/v92/v92b'], name_list)
 
         self.assertRaises(ConfigDataError, spec_name_list, 1)
         self.assertRaises(ConfigDataError, spec_name_list, [ 'a' ])
@@ -240,19 +254,19 @@
 
     def test_get_item_list(self):
         name_list = self.cd.get_item_list()
-        self.assertEqual(['item1', 'item2', 'item3', 'item4', 'item5/', 'item6/'], name_list)
+        self.assertEqual(['item1', 'item2', 'item3', 'item4', 'item5', 'item6'], name_list)
         name_list = self.cd.get_item_list("", True)
-        self.assertEqual(['item1', 'item2', 'item3', 'item4', 'item5/', 'item6/value1', 'item6/value2'], name_list)
+        self.assertEqual(['item1', 'item2', 'item3', 'item4', 'item5', 'item6/value1', 'item6/value2'], name_list)
         name_list = self.cd.get_item_list("item6", False)
         self.assertEqual(['item6/value1', 'item6/value2'], name_list)
 
     def test_get_full_config(self):
         full_config = self.cd.get_full_config()
-        self.assertEqual({ "item1": 1, "item2": 1.1, "item3": True, "item4": "test", "item5/": ['a', 'b'], "item6/value1": 'default', 'item6/value2': None}, full_config)
+        self.assertEqual({ "item1": 1, "item2": 1.1, "item3": True, "item4": "test", "item5": ['a', 'b'], "item6/value1": 'default', 'item6/value2': None}, full_config)
         my_config = { "item1": 2, "item2": 2.2, "item3": False, "item4": "asdf", "item5": [ "c", "d" ] }
         self.cd.set_local_config(my_config)
         full_config = self.cd.get_full_config()
-        self.assertEqual({ "item1": 2, "item2": 2.2, "item3": False, "item4": "asdf", "item5/": [ "c", "d" ], "item6/value1": 'default', 'item6/value2': None}, full_config)
+        self.assertEqual({ "item1": 2, "item2": 2.2, "item3": False, "item4": "asdf", "item5": [ "c", "d" ], "item6/value1": 'default', 'item6/value2': None}, full_config)
 
 class TestMultiConfigData(unittest.TestCase):
     def setUp(self):
@@ -342,6 +356,12 @@
         self.assertEqual(1, value)
         value = self.mcd.get_default_value("/Spec2/item1")
         self.assertEqual(1, value)
+        value = self.mcd.get_default_value("Spec2/item5[0]")
+        self.assertEqual('a', value)
+        value = self.mcd.get_default_value("Spec2/item5[5]")
+        self.assertEqual(None, value)
+        value = self.mcd.get_default_value("Spec2/item5[0][1]")
+        self.assertEqual(None, value)
         value = self.mcd.get_default_value("Spec2/item6/value1")
         self.assertEqual('default', value)
         value = self.mcd.get_default_value("Spec2/item6/value2")
@@ -353,19 +373,33 @@
         module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec2.spec")
         self.mcd.set_specification(module_spec)
         self.mcd.set_value("Spec2/item1", 2)
-        value,status = self.mcd.get_value("Spec2/item1")
+
+        value, status = self.mcd.get_value("Spec2/item1")
         self.assertEqual(2, value)
         self.assertEqual(MultiConfigData.LOCAL, status)
-        value,status = self.mcd.get_value("Spec2/item2")
+
+        value, status = self.mcd.get_value("Spec2/item2")
         self.assertEqual(1.1, value)
         self.assertEqual(MultiConfigData.DEFAULT, status)
+
         self.mcd._current_config = { "Spec2": { "item3": False } }
-        value,status = self.mcd.get_value("Spec2/item3")
+
+        value, status = self.mcd.get_value("Spec2/item3")
         self.assertEqual(False, value)
         self.assertEqual(MultiConfigData.CURRENT, status)
-        value,status = self.mcd.get_value("Spec2/no_such_item")
+
+        value, status = self.mcd.get_value("Spec2/no_such_item")
         self.assertEqual(None, value)
         self.assertEqual(MultiConfigData.NONE, status)
+
+        value, status = self.mcd.get_value("Spec2/item5[0]")
+        self.assertEqual("a", value)
+        self.assertEqual(MultiConfigData.DEFAULT, status)
+
+        value, status = self.mcd.get_value("Spec2/item5[0]", False)
+        self.assertEqual(None, value)
+        self.assertEqual(MultiConfigData.NONE, status)
+
 
     def test_get_value_maps(self):
         maps = self.mcd.get_value_maps()
@@ -390,29 +424,31 @@
         self.mcd.set_value("Spec2/item3", False)
         maps = self.mcd.get_value_maps("/Spec2")
         self.assertEqual([{'default': False, 'type': 'integer', 'name': 'item1', 'value': 2, 'modified': False},
-                          {'default': False, 'type': 'real', 'name': 'item2', 'value': 1.1, 'modified': False},
+                          {'default': True, 'type': 'real', 'name': 'item2', 'value': 1.1, 'modified': False},
                           {'default': False, 'type': 'boolean', 'name': 'item3', 'value': False, 'modified': True},
-                          {'default': False, 'type': 'string', 'name': 'item4', 'value': 'test', 'modified': False},
-                          {'default': False, 'type': 'list', 'name': 'item5', 'value': ['a', 'b'], 'modified': False},
-                          {'default': False, 'type': 'map', 'name': 'item6', 'value': {}, 'modified': False}], maps)
+                          {'default': True, 'type': 'string', 'name': 'item4', 'value': 'test', 'modified': False},
+                          {'default': True, 'type': 'list', 'name': 'item5', 'value': ['a', 'b'], 'modified': False},
+                          {'default': True, 'type': 'map', 'name': 'item6', 'value': {}, 'modified': False}], maps)
         maps = self.mcd.get_value_maps("Spec2")
         self.assertEqual([{'default': False, 'type': 'integer', 'name': 'item1', 'value': 2, 'modified': False},
-                          {'default': False, 'type': 'real', 'name': 'item2', 'value': 1.1, 'modified': False},
+                          {'default': True, 'type': 'real', 'name': 'item2', 'value': 1.1, 'modified': False},
                           {'default': False, 'type': 'boolean', 'name': 'item3', 'value': False, 'modified': True},
-                          {'default': False, 'type': 'string', 'name': 'item4', 'value': 'test', 'modified': False},
-                          {'default': False, 'type': 'list', 'name': 'item5', 'value': ['a', 'b'], 'modified': False},
-                          {'default': False, 'type': 'map', 'name': 'item6', 'value': {}, 'modified': False}], maps)
+                          {'default': True, 'type': 'string', 'name': 'item4', 'value': 'test', 'modified': False},
+                          {'default': True, 'type': 'list', 'name': 'item5', 'value': ['a', 'b'], 'modified': False},
+                          {'default': True, 'type': 'map', 'name': 'item6', 'value': {}, 'modified': False}], maps)
         maps = self.mcd.get_value_maps("/Spec2/item5")
         self.assertEqual([{'default': False, 'type': 'string', 'name': 'list_element', 'value': 'a', 'modified': False},
                           {'default': False, 'type': 'string', 'name': 'list_element', 'value': 'b', 'modified': False}], maps)
+        maps = self.mcd.get_value_maps("/Spec2/item5[0]")
+        self.assertEqual([{'default': True, 'modified': False, 'name': 'list_element', 'type': 'string', 'value': 'a'}], maps)
         maps = self.mcd.get_value_maps("/Spec2/item1")
         self.assertEqual([{'default': False, 'type': 'integer', 'name': 'item1', 'value': 2, 'modified': False}], maps)
         maps = self.mcd.get_value_maps("/Spec2/item2")
-        self.assertEqual([{'default': False, 'type': 'real', 'name': 'item2', 'value': 1.1, 'modified': False}], maps)
+        self.assertEqual([{'default': True, 'type': 'real', 'name': 'item2', 'value': 1.1, 'modified': False}], maps)
         maps = self.mcd.get_value_maps("/Spec2/item3")
         self.assertEqual([{'default': False, 'type': 'boolean', 'name': 'item3', 'value': False, 'modified': True}], maps)
         maps = self.mcd.get_value_maps("/Spec2/item4")
-        self.assertEqual([{'default': False, 'type': 'string', 'name': 'item4', 'value': 'test', 'modified': False}], maps)
+        self.assertEqual([{'default': True, 'type': 'string', 'name': 'item4', 'value': 'test', 'modified': False}], maps)
 
         module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec24.spec")
         self.mcd.set_specification(module_spec)
@@ -429,7 +465,19 @@
         self.mcd.set_specification(module_spec)
         self.mcd.set_value("Spec2/item1", 2)
         self.assertRaises(isc.cc.data.DataTypeError, self.mcd.set_value, "Spec2/item1", "asdf")
+
         self.mcd.set_value("Spec2/no_such_item", 4)
+        value, status = self.mcd.get_value("Spec2/no_such_item")
+        self.assertEqual(value, 4)
+        self.assertEqual(MultiConfigData.LOCAL, status)
+
+        self.mcd.set_value("Spec2/item5[0]", "c")
+        value, status = self.mcd.get_value("Spec2/item5[0]")
+        self.assertEqual(value, "c")
+        self.assertEqual(MultiConfigData.LOCAL, status)
+
+        self.assertRaises(isc.cc.data.DataTypeError, self.mcd.set_value, "Spec2/item5[a]", "asdf")
+        
 
     def test_get_config_item_list(self):
         config_items = self.mcd.get_config_item_list()
@@ -441,13 +489,15 @@
         config_items = self.mcd.get_config_item_list(None, False)
         self.assertEqual(['Spec2'], config_items)
         config_items = self.mcd.get_config_item_list(None, True)
-        self.assertEqual(['Spec2/item1', 'Spec2/item2', 'Spec2/item3', 'Spec2/item4', 'Spec2/item5/', 'Spec2/item6/value1', 'Spec2/item6/value2'], config_items)
+        self.assertEqual(['Spec2/item1', 'Spec2/item2', 'Spec2/item3', 'Spec2/item4', 'Spec2/item5', 'Spec2/item6/value1', 'Spec2/item6/value2'], config_items)
         config_items = self.mcd.get_config_item_list("Spec2", True)
-        self.assertEqual(['Spec2/item1', 'Spec2/item2', 'Spec2/item3', 'Spec2/item4', 'Spec2/item5/', 'Spec2/item6/value1', 'Spec2/item6/value2'], config_items)
+        self.assertEqual(['Spec2/item1', 'Spec2/item2', 'Spec2/item3', 'Spec2/item4', 'Spec2/item5', 'Spec2/item6/value1', 'Spec2/item6/value2'], config_items)
         config_items = self.mcd.get_config_item_list("Spec2")
-        self.assertEqual(['Spec2/item1', 'Spec2/item2', 'Spec2/item3', 'Spec2/item4', 'Spec2/item5/', 'Spec2/item6/'], config_items)
+        self.assertEqual(['Spec2/item1', 'Spec2/item2', 'Spec2/item3', 'Spec2/item4', 'Spec2/item5', 'Spec2/item6'], config_items)
+        config_items = self.mcd.get_config_item_list("/Spec2")
+        self.assertEqual(['Spec2/item1', 'Spec2/item2', 'Spec2/item3', 'Spec2/item4', 'Spec2/item5', 'Spec2/item6'], config_items)
         config_items = self.mcd.get_config_item_list("Spec2", True)
-        self.assertEqual(['Spec2/item1', 'Spec2/item2', 'Spec2/item3', 'Spec2/item4', 'Spec2/item5/', 'Spec2/item6/value1', 'Spec2/item6/value2'], config_items)
+        self.assertEqual(['Spec2/item1', 'Spec2/item2', 'Spec2/item3', 'Spec2/item4', 'Spec2/item5', 'Spec2/item6/value1', 'Spec2/item6/value2'], config_items)
 
 if __name__ == '__main__':
     unittest.main()

Modified: branches/trac397focused/src/lib/python/isc/datasrc/Makefile.am
==============================================================================
--- branches/trac397focused/src/lib/python/isc/datasrc/Makefile.am (original)
+++ branches/trac397focused/src/lib/python/isc/datasrc/Makefile.am Mon Dec 20 08:19:35 2010
@@ -1,3 +1,5 @@
+SUBDIRS = . tests
+
 python_PYTHON = __init__.py master.py sqlite3_ds.py
 
 pythondir = $(pyexecdir)/isc/datasrc

Modified: branches/trac397focused/src/lib/python/isc/datasrc/master.py
==============================================================================
--- branches/trac397focused/src/lib/python/isc/datasrc/master.py (original)
+++ branches/trac397focused/src/lib/python/isc/datasrc/master.py Mon Dec 20 08:19:35 2010
@@ -103,7 +103,7 @@
 # isttl: check whether a string is a valid TTL specifier.
 # returns: boolean
 #########################################################################
-ttl_regex = re.compile('([0-9]+[wdhms]?)+', re.I)
+ttl_regex = re.compile('([0-9]+[wdhms]?)+$', re.I)
 def isttl(s):
     global ttl_regex
     if ttl_regex.match(s):

Modified: branches/trac397focused/src/lib/python/isc/notify/notify_out.py
==============================================================================
--- branches/trac397focused/src/lib/python/isc/notify/notify_out.py (original)
+++ branches/trac397focused/src/lib/python/isc/notify/notify_out.py Mon Dec 20 08:19:35 2010
@@ -367,6 +367,7 @@
                     zone_id = self._waiting_zones.pop(0) 
                     self._notify_infos[zone_id].prepare_notify_out()
                     self.notify_num += 1 
+                    self._notifying_zones.append(zone_id)
 
     def _send_notify_message_udp(self, zone_notify_info, addrinfo):
         msg, qid = self._create_notify_message(zone_notify_info.zone_name, 
@@ -402,13 +403,13 @@
         msg.set_qid(qid)
         msg.set_opcode(Opcode.NOTIFY())
         msg.set_rcode(Rcode.NOERROR())
-        msg.set_header_flag(MessageFlag.AA())
+        msg.set_header_flag(Message.HEADERFLAG_AA)
         question = Question(Name(zone_name), RRClass(zone_class), RRType('SOA'))
         msg.add_question(question)
         # Add soa record to answer section
         soa_record = sqlite3_ds.get_zone_rrset(zone_name, zone_name, 'SOA', self._db_file) 
         rrset_soa = self._create_rrset_from_db_record(soa_record[0], zone_class)
-        msg.add_rrset(Section.ANSWER(), rrset_soa)
+        msg.add_rrset(Message.SECTION_ANSWER, rrset_soa)
         return msg, qid
 
     def _handle_notify_reply(self, zone_notify_info, msg_data):
@@ -420,7 +421,7 @@
         try:
             errstr = 'notify reply error: '
             msg.from_wire(msg_data)
-            if not msg.get_header_flag(MessageFlag.QR()):
+            if not msg.get_header_flag(Message.HEADERFLAG_QR):
                 self._log_msg('error', errstr + 'bad flags')
                 return _BAD_QR
 

Modified: branches/trac397focused/src/lib/python/isc/notify/tests/notify_out_test.py
==============================================================================
--- branches/trac397focused/src/lib/python/isc/notify/tests/notify_out_test.py (original)
+++ branches/trac397focused/src/lib/python/isc/notify/tests/notify_out_test.py Mon Dec 20 08:19:35 2010
@@ -156,7 +156,7 @@
         com_info = self._notify._notify_infos[('com.', 'IN')]
         self._notify._notify_next_target(com_info)
         self.assertEqual(2, self._notify.notify_num)
-        self.assertEqual(0, len(self._notify._notifying_zones))
+        self.assertEqual(2, len(self._notify._notifying_zones))
     
     def test_handle_notify_reply(self):
         self.assertEqual(notify_out._BAD_REPLY_PACKET, self._notify._handle_notify_reply(None, b'badmsg'))

Modified: branches/trac397focused/src/lib/python/isc/utils/Makefile.am
==============================================================================
--- branches/trac397focused/src/lib/python/isc/utils/Makefile.am (original)
+++ branches/trac397focused/src/lib/python/isc/utils/Makefile.am Mon Dec 20 08:19:35 2010
@@ -1,5 +1,5 @@
 SUBDIRS = tests
 
-python_PYTHON = __init__.py process.py socketserver_mixin.py
+python_PYTHON = __init__.py process.py
 
 pythondir = $(pyexecdir)/isc/utils

Modified: branches/trac397focused/src/lib/python/isc/utils/__init__.py
==============================================================================
--- branches/trac397focused/src/lib/python/isc/utils/__init__.py (original)
+++ branches/trac397focused/src/lib/python/isc/utils/__init__.py Mon Dec 20 08:19:35 2010
@@ -1,1 +1,0 @@
-from isc.utils.socketserver_mixin import *

Modified: branches/trac397focused/src/lib/python/isc/utils/tests/Makefile.am
==============================================================================
--- branches/trac397focused/src/lib/python/isc/utils/tests/Makefile.am (original)
+++ branches/trac397focused/src/lib/python/isc/utils/tests/Makefile.am Mon Dec 20 08:19:35 2010
@@ -1,4 +1,4 @@
-PYTESTS = process_test.py socketserver_mixin_test.py
+PYTESTS = process_test.py
 EXTRA_DIST = $(PYTESTS)
 
 # later will have configure option to choose this, like: coverage run --branch

Modified: branches/trac397focused/src/lib/xfr/Makefile.am
==============================================================================
--- branches/trac397focused/src/lib/xfr/Makefile.am (original)
+++ branches/trac397focused/src/lib/xfr/Makefile.am Mon Dec 20 08:19:35 2010
@@ -1,8 +1,12 @@
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
+AM_CPPFLAGS += $(BOOST_INCLUDES)
 
 AM_CXXFLAGS = $(B10_CXXFLAGS) -Wno-strict-aliasing
 AM_CXXFLAGS += -Wno-unused-parameter # see src/lib/cc/Makefile.am
+if USE_CLANGPP
+AM_CXXFLAGS += -Wno-error
+endif
 
 CLEANFILES = *.gcno *.gcda
 

Modified: branches/trac397focused/src/lib/xfr/fd_share.cc
==============================================================================
--- branches/trac397focused/src/lib/xfr/fd_share.cc (original)
+++ branches/trac397focused/src/lib/xfr/fd_share.cc Mon Dec 20 08:19:35 2010
@@ -93,7 +93,7 @@
 
     if (recvmsg(sock, &msghdr, 0) < 0) {
         free(msghdr.msg_control);
-        return (-1);
+        return (XFR_FD_RECEIVE_FAIL);
     }
     const struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msghdr);
     int fd = -1;

Modified: branches/trac397focused/src/lib/xfr/fd_share.h
==============================================================================
--- branches/trac397focused/src/lib/xfr/fd_share.h (original)
+++ branches/trac397focused/src/lib/xfr/fd_share.h Mon Dec 20 08:19:35 2010
@@ -20,12 +20,16 @@
 namespace isc {
 namespace xfr {
 
+/// Failed to receive xfr socket descriptor "fd" on unix domain socket 'sock'
+const int XFR_FD_RECEIVE_FAIL = -2;
+
 // Receive socket descriptor on unix domain socket 'sock'.
 // Returned value is the socket descriptor received.
+// Returned XFR_FD_RECEIVE_FAIL if failed to receive xfr socket descriptor
 // Errors are indicated by a return value of -1.
 int recv_fd(const int sock);
 
-// Send socket descriptor "fd" to server over unix domain socket 'sock', 
+// Send socket descriptor "fd" to server over unix domain socket 'sock',
 // the connection from socket 'sock' to unix domain server should be established first.
 // Errors are indicated by a return value of -1.
 int send_fd(const int sock, const int fd);
@@ -35,6 +39,6 @@
 
 #endif
 
-// Local Variables: 
+// Local Variables:
 // mode: c++
-// End: 
+// End:

Modified: branches/trac397focused/src/lib/xfr/fdshare_python.cc
==============================================================================
--- branches/trac397focused/src/lib/xfr/fdshare_python.cc (original)
+++ branches/trac397focused/src/lib/xfr/fdshare_python.cc Mon Dec 20 08:19:35 2010
@@ -22,8 +22,9 @@
 
 #include <xfr/fd_share.h>
 
+
 static PyObject*
-fdshare_recv_fd(PyObject *self UNUSED_PARAM, PyObject *args) {
+fdshare_recv_fd(PyObject*, PyObject* args) {
     int sock, fd;
     if (!PyArg_ParseTuple(args, "i", &sock)) {
         return (NULL);
@@ -33,7 +34,7 @@
 }
 
 static PyObject*
-fdshare_send_fd(PyObject *self UNUSED_PARAM, PyObject *args) {
+fdshare_send_fd(PyObject*, PyObject* args) {
     int sock, fd, result;
     if (!PyArg_ParseTuple(args, "ii", &sock, &fd)) {
         return (NULL);
@@ -63,8 +64,20 @@
 
 PyMODINIT_FUNC
 PyInit_libxfr_python(void) {
-    PyObject *mod = PyModule_Create(&bind10_fdshare_python);
+    PyObject* mod = PyModule_Create(&bind10_fdshare_python);
     if (mod == NULL) {
+        return (NULL);
+    }
+
+    PyObject* XFR_FD_RECEIVE_FAIL = Py_BuildValue("i", isc::xfr::XFR_FD_RECEIVE_FAIL);
+    if (XFR_FD_RECEIVE_FAIL == NULL) {
+        Py_XDECREF(mod);
+        return (NULL);
+    }
+    int ret = PyModule_AddObject(mod, "XFR_FD_RECEIVE_FAIL", XFR_FD_RECEIVE_FAIL);
+    if (-1 == ret) {
+        Py_XDECREF(XFR_FD_RECEIVE_FAIL);
+        Py_XDECREF(mod);
         return (NULL);
     }
 

Modified: branches/trac397focused/src/lib/xfr/xfrout_client.cc
==============================================================================
--- branches/trac397focused/src/lib/xfr/xfrout_client.cc (original)
+++ branches/trac397focused/src/lib/xfr/xfrout_client.cc Mon Dec 20 08:19:35 2010
@@ -69,7 +69,7 @@
     }
 }
 
-int 
+int
 XfroutClient::sendXfroutRequestInfo(const int tcp_sock,
                                     const void* const msg_data,
                                     const uint16_t msg_len)
@@ -93,12 +93,6 @@
         isc_throw(XfroutError,
                   "failed to send XFR request data to xfrout module");
     }
-    
-    int databuf = 0;
-    if (recv(impl_->socket_.native(), &databuf, sizeof(int), 0) != 0) {
-        isc_throw(XfroutError,
-                  "xfr query hasn't been processed properly by xfrout module");
-    }
 
     return (0);
 }




More information about the bind10-changes mailing list