[svn] commit: r3496 - in /experiments/327-sync: ./ doc/guide/ src/bin/ src/bin/auth/ src/bin/auth/benchmarks/ src/bin/auth/tests/ src/bin/auth/tests/testdata/ src/bin/bind10/ src/bin/bind10/tests/ src/bin/bindctl/ src/bin/cfgmgr/ src/bin/cmdctl/ src/bin/host/ src/bin/loadzone/ src/bin/loadzone/tests/error/ src/bin/msgq/ src/bin/msgq/tests/ src/bin/stats/ src/bin/stats/test/ src/bin/stats/tests/ src/bin/tests/ src/bin/usermgr/ src/bin/xfrin/ src/bin/xfrin/tests/ src/bin/xfrout/ src/bin/xfrout/tests/ src/bin/zonemgr/ src/bin/zonemgr/tests/ src/lib/bench/ src/lib/bench/example/ src/lib/bench/tests/ src/lib/cc/ src/lib/cc/tests/ src/lib/config/ src/lib/config/testdata/ src/lib/config/tests/ src/lib/config/tests/testdata/ src/lib/datasrc/ src/lib/datasrc/tests/ src/lib/dns/ src/lib/dns/python/ src/lib/dns/python/tests/ src/lib/dns/rdata/ src/lib/dns/rdata/ch_3/ src/lib/dns/rdata/generic/ src/lib/dns/rdata/hs_4/ src/lib/dns/tests/ src/lib/dns/tests/testdata/ src/lib/dns/util/ src/lib/exceptions/ src/lib/exceptions/tests/ src/lib/python/isc/ src/lib/python/isc/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/dns/ src/lib/python/isc/log/ src/lib/python/isc/log/tests/ src/lib/python/isc/net/ src/lib/python/isc/notify/ src/lib/python/isc/notify/tests/ src/lib/python/isc/util/ src/lib/xfr/

BIND 10 source code commits bind10-changes at lists.isc.org
Tue Nov 9 10:38:18 UTC 2010


Author: vorner
Date: Tue Nov  9 10:38:17 2010
New Revision: 3496

Log:
Merge without any conflict resolutions, left for future commits (for easier replay)

Added:
    experiments/327-sync/src/bin/auth/benchmarks/
      - copied from r3495, trunk/src/bin/auth/benchmarks/
    experiments/327-sync/src/bin/auth/tests/testdata/Makefile.am
      - copied unchanged from r3495, trunk/src/bin/auth/tests/testdata/Makefile.am
    experiments/327-sync/src/bin/stats/Makefile.am
      - copied unchanged from r3495, trunk/src/bin/stats/Makefile.am
    experiments/327-sync/src/bin/stats/b10-stats.8
      - copied unchanged from r3495, trunk/src/bin/stats/b10-stats.8
    experiments/327-sync/src/bin/stats/b10-stats.xml
      - copied unchanged from r3495, trunk/src/bin/stats/b10-stats.xml
    experiments/327-sync/src/bin/stats/run_b10-stats.sh.in
      - copied unchanged from r3495, trunk/src/bin/stats/run_b10-stats.sh.in
    experiments/327-sync/src/bin/stats/run_b10-stats_stub.sh.in
      - copied unchanged from r3495, trunk/src/bin/stats/run_b10-stats_stub.sh.in
    experiments/327-sync/src/bin/stats/stats.py.in
      - copied unchanged from r3495, trunk/src/bin/stats/stats.py.in
    experiments/327-sync/src/bin/stats/stats.spec.pre.in
      - copied unchanged from r3495, trunk/src/bin/stats/stats.spec.pre.in
    experiments/327-sync/src/bin/stats/stats_stub.py.in
      - copied unchanged from r3495, trunk/src/bin/stats/stats_stub.py.in
    experiments/327-sync/src/bin/stats/tests/
      - copied from r3495, trunk/src/bin/stats/tests/
    experiments/327-sync/src/bin/tests/
      - copied from r3495, trunk/src/bin/tests/
    experiments/327-sync/src/bin/xfrin/xfrin.spec
      - copied unchanged from r3495, trunk/src/bin/xfrin/xfrin.spec
    experiments/327-sync/src/bin/zonemgr/b10-zonemgr.8
      - copied unchanged from r3495, trunk/src/bin/zonemgr/b10-zonemgr.8
    experiments/327-sync/src/bin/zonemgr/b10-zonemgr.xml
      - copied unchanged from r3495, trunk/src/bin/zonemgr/b10-zonemgr.xml
    experiments/327-sync/src/lib/config/tests/testdata/
      - copied from r3495, trunk/src/lib/config/tests/testdata/
    experiments/327-sync/src/lib/dns/edns.cc
      - copied unchanged from r3495, trunk/src/lib/dns/edns.cc
    experiments/327-sync/src/lib/dns/edns.h
      - copied unchanged from r3495, trunk/src/lib/dns/edns.h
    experiments/327-sync/src/lib/dns/opcode.cc
      - copied unchanged from r3495, trunk/src/lib/dns/opcode.cc
    experiments/327-sync/src/lib/dns/opcode.h
      - copied unchanged from r3495, trunk/src/lib/dns/opcode.h
    experiments/327-sync/src/lib/dns/python/edns_python.cc
      - copied unchanged from r3495, trunk/src/lib/dns/python/edns_python.cc
    experiments/327-sync/src/lib/dns/python/opcode_python.cc
      - copied unchanged from r3495, trunk/src/lib/dns/python/opcode_python.cc
    experiments/327-sync/src/lib/dns/python/pydnspp.cc
      - copied unchanged from r3495, trunk/src/lib/dns/python/pydnspp.cc
    experiments/327-sync/src/lib/dns/python/pydnspp_common.cc
      - copied unchanged from r3495, trunk/src/lib/dns/python/pydnspp_common.cc
    experiments/327-sync/src/lib/dns/python/pydnspp_common.h
      - copied unchanged from r3495, trunk/src/lib/dns/python/pydnspp_common.h
    experiments/327-sync/src/lib/dns/python/rcode_python.cc
      - copied unchanged from r3495, trunk/src/lib/dns/python/rcode_python.cc
    experiments/327-sync/src/lib/dns/python/tests/edns_python_test.py
      - copied unchanged from r3495, trunk/src/lib/dns/python/tests/edns_python_test.py
    experiments/327-sync/src/lib/dns/python/tests/opcode_python_test.py
      - copied unchanged from r3495, trunk/src/lib/dns/python/tests/opcode_python_test.py
    experiments/327-sync/src/lib/dns/python/tests/rcode_python_test.py
      - copied unchanged from r3495, trunk/src/lib/dns/python/tests/rcode_python_test.py
    experiments/327-sync/src/lib/dns/python/tests/testutil.py
      - copied unchanged from r3495, trunk/src/lib/dns/python/tests/testutil.py
    experiments/327-sync/src/lib/dns/rcode.cc
      - copied unchanged from r3495, trunk/src/lib/dns/rcode.cc
    experiments/327-sync/src/lib/dns/rcode.h
      - copied unchanged from r3495, trunk/src/lib/dns/rcode.h
    experiments/327-sync/src/lib/dns/tests/edns_unittest.cc
      - copied unchanged from r3495, trunk/src/lib/dns/tests/edns_unittest.cc
    experiments/327-sync/src/lib/dns/tests/opcode_unittest.cc
      - copied unchanged from r3495, trunk/src/lib/dns/tests/opcode_unittest.cc
    experiments/327-sync/src/lib/dns/tests/rcode_unittest.cc
      - copied unchanged from r3495, trunk/src/lib/dns/tests/rcode_unittest.cc
    experiments/327-sync/src/lib/dns/tests/testdata/Makefile.am
      - copied unchanged from r3495, trunk/src/lib/dns/tests/testdata/Makefile.am
    experiments/327-sync/src/lib/dns/tests/testdata/edns_toWire1.spec
      - copied unchanged from r3495, trunk/src/lib/dns/tests/testdata/edns_toWire1.spec
    experiments/327-sync/src/lib/dns/tests/testdata/edns_toWire2.spec
      - copied unchanged from r3495, trunk/src/lib/dns/tests/testdata/edns_toWire2.spec
    experiments/327-sync/src/lib/dns/tests/testdata/edns_toWire3.spec
      - copied unchanged from r3495, trunk/src/lib/dns/tests/testdata/edns_toWire3.spec
    experiments/327-sync/src/lib/dns/tests/testdata/edns_toWire4.spec
      - copied unchanged from r3495, trunk/src/lib/dns/tests/testdata/edns_toWire4.spec
    experiments/327-sync/src/lib/python/isc/net/
      - copied from r3495, trunk/src/lib/python/isc/net/
    experiments/327-sync/src/lib/python/isc/util/
      - copied from r3495, trunk/src/lib/python/isc/util/
Removed:
    experiments/327-sync/src/bin/auth/tests/testdata/badExampleQuery_fromWire
    experiments/327-sync/src/bin/auth/tests/testdata/examplequery_fromWire
    experiments/327-sync/src/bin/auth/tests/testdata/iqueryresponse_fromWire
    experiments/327-sync/src/bin/auth/tests/testdata/multiquestion_fromWire
    experiments/327-sync/src/bin/auth/tests/testdata/queryBadEDNS_fromWire
    experiments/327-sync/src/bin/auth/tests/testdata/shortanswer_fromWire
    experiments/327-sync/src/bin/auth/tests/testdata/simplequery_fromWire
    experiments/327-sync/src/bin/auth/tests/testdata/simpleresponse_fromWire
    experiments/327-sync/src/bin/stats/statsd.py
    experiments/327-sync/src/bin/stats/statsd.txt
    experiments/327-sync/src/bin/stats/test/
    experiments/327-sync/src/bin/stats/test_total.py
    experiments/327-sync/src/bin/xfrin/xfrin.spec.pre.in
    experiments/327-sync/src/lib/config/testdata/
    experiments/327-sync/src/lib/dns/message_test.py
    experiments/327-sync/src/lib/dns/python/libdns_python.cc
    experiments/327-sync/src/lib/dns/python/libdns_python_common.cc
    experiments/327-sync/src/lib/dns/python/libdns_python_common.h
    experiments/327-sync/src/lib/dns/python/tests/test.py
    experiments/327-sync/src/lib/dns/tests/testdata/message_fromWire10
    experiments/327-sync/src/lib/dns/tests/testdata/message_fromWire11
    experiments/327-sync/src/lib/dns/tests/testdata/name_toWire5
    experiments/327-sync/src/lib/dns/tests/testdata/name_toWire6
    experiments/327-sync/src/lib/dns/tests/testdata/rdata_nsec_fromWire10
    experiments/327-sync/src/lib/dns/tests/testdata/rdata_nsec_fromWire4
    experiments/327-sync/src/lib/dns/tests/testdata/rdata_nsec_fromWire5
    experiments/327-sync/src/lib/dns/tests/testdata/rdata_nsec_fromWire6
    experiments/327-sync/src/lib/dns/tests/testdata/rdata_nsec_fromWire7
    experiments/327-sync/src/lib/dns/tests/testdata/rdata_nsec_fromWire8
    experiments/327-sync/src/lib/dns/tests/testdata/rdata_nsec_fromWire9
    experiments/327-sync/src/lib/dns/tests/testdata/rdata_rrsig_fromWire2
    experiments/327-sync/src/lib/dns/tests/testdata/rdata_soa_toWireUncompressed
    experiments/327-sync/src/lib/dns/tests/testdata/rdata_txt_fromWire2
    experiments/327-sync/src/lib/dns/tests/testdata/rdata_txt_fromWire3
    experiments/327-sync/src/lib/dns/tests/testdata/rdata_txt_fromWire4
    experiments/327-sync/src/lib/dns/tests/testdata/rdata_txt_fromWire5
    experiments/327-sync/src/lib/python/isc/Util/
Modified:
    experiments/327-sync/   (props changed)
    experiments/327-sync/ChangeLog
    experiments/327-sync/README
    experiments/327-sync/configure.ac
    experiments/327-sync/doc/guide/bind10-guide.html
    experiments/327-sync/doc/guide/bind10-guide.xml
    experiments/327-sync/src/bin/Makefile.am
    experiments/327-sync/src/bin/auth/Makefile.am
    experiments/327-sync/src/bin/auth/auth_srv.cc
    experiments/327-sync/src/bin/auth/auth_srv.h
    experiments/327-sync/src/bin/auth/b10-auth.8
    experiments/327-sync/src/bin/auth/b10-auth.xml
    experiments/327-sync/src/bin/auth/tests/Makefile.am
    experiments/327-sync/src/bin/auth/tests/auth_srv_unittest.cc
    experiments/327-sync/src/bin/auth/tests/run_unittests.cc
    experiments/327-sync/src/bin/bind10/Makefile.am
    experiments/327-sync/src/bin/bind10/bind10.8
    experiments/327-sync/src/bin/bind10/bind10.py.in   (contents, props changed)
    experiments/327-sync/src/bin/bind10/bind10.xml
    experiments/327-sync/src/bin/bind10/run_bind10.sh.in
    experiments/327-sync/src/bin/bind10/tests/args_test.py
    experiments/327-sync/src/bin/bind10/tests/bind10_test.py
    experiments/327-sync/src/bin/bindctl/Makefile.am
    experiments/327-sync/src/bin/bindctl/bindctl-source.py.in
    experiments/327-sync/src/bin/cfgmgr/Makefile.am
    experiments/327-sync/src/bin/cfgmgr/b10-cfgmgr.py.in
    experiments/327-sync/src/bin/cmdctl/Makefile.am
    experiments/327-sync/src/bin/cmdctl/cmdctl.py.in   (contents, props changed)
    experiments/327-sync/src/bin/host/Makefile.am
    experiments/327-sync/src/bin/host/host.cc
    experiments/327-sync/src/bin/loadzone/Makefile.am
    experiments/327-sync/src/bin/loadzone/b10-loadzone.py.in
    experiments/327-sync/src/bin/loadzone/tests/error/error.known
    experiments/327-sync/src/bin/msgq/Makefile.am
    experiments/327-sync/src/bin/msgq/msgq.py.in
    experiments/327-sync/src/bin/msgq/tests/Makefile.am
    experiments/327-sync/src/bin/msgq/tests/msgq_test.py
    experiments/327-sync/src/bin/usermgr/b10-cmdctl-usermgr.py.in
    experiments/327-sync/src/bin/xfrin/Makefile.am
    experiments/327-sync/src/bin/xfrin/TODO
    experiments/327-sync/src/bin/xfrin/b10-xfrin.8
    experiments/327-sync/src/bin/xfrin/b10-xfrin.xml
    experiments/327-sync/src/bin/xfrin/tests/xfrin_test.py
    experiments/327-sync/src/bin/xfrin/xfrin.py.in
    experiments/327-sync/src/bin/xfrout/Makefile.am
    experiments/327-sync/src/bin/xfrout/TODO
    experiments/327-sync/src/bin/xfrout/b10-xfrout.8
    experiments/327-sync/src/bin/xfrout/b10-xfrout.xml
    experiments/327-sync/src/bin/xfrout/tests/xfrout_test.py
    experiments/327-sync/src/bin/xfrout/xfrout.py.in
    experiments/327-sync/src/bin/zonemgr/Makefile.am
    experiments/327-sync/src/bin/zonemgr/TODO
    experiments/327-sync/src/bin/zonemgr/tests/Makefile.am
    experiments/327-sync/src/bin/zonemgr/tests/zonemgr_test.py
    experiments/327-sync/src/bin/zonemgr/zonemgr.py.in
    experiments/327-sync/src/bin/zonemgr/zonemgr.spec.pre.in
    experiments/327-sync/src/lib/bench/Makefile.am
    experiments/327-sync/src/lib/bench/benchmark_util.cc
    experiments/327-sync/src/lib/bench/example/search_bench.cc
    experiments/327-sync/src/lib/bench/tests/Makefile.am
    experiments/327-sync/src/lib/bench/tests/loadquery_unittest.cc
    experiments/327-sync/src/lib/cc/Makefile.am
    experiments/327-sync/src/lib/cc/data.cc
    experiments/327-sync/src/lib/cc/tests/Makefile.am
    experiments/327-sync/src/lib/cc/tests/data_unittests.cc
    experiments/327-sync/src/lib/cc/tests/run_unittests.cc
    experiments/327-sync/src/lib/config/Makefile.am
    experiments/327-sync/src/lib/config/ccsession.cc
    experiments/327-sync/src/lib/config/ccsession.h
    experiments/327-sync/src/lib/config/config_data.h
    experiments/327-sync/src/lib/config/module_spec.cc
    experiments/327-sync/src/lib/config/module_spec.h
    experiments/327-sync/src/lib/config/tests/Makefile.am
    experiments/327-sync/src/lib/config/tests/ccsession_unittests.cc
    experiments/327-sync/src/lib/config/tests/data_def_unittests_config.h.in
    experiments/327-sync/src/lib/config/tests/module_spec_unittests.cc
    experiments/327-sync/src/lib/config/tests/run_unittests.cc
    experiments/327-sync/src/lib/datasrc/Makefile.am
    experiments/327-sync/src/lib/datasrc/data_source.cc
    experiments/327-sync/src/lib/datasrc/query.cc
    experiments/327-sync/src/lib/datasrc/query.h
    experiments/327-sync/src/lib/datasrc/static_datasrc.cc
    experiments/327-sync/src/lib/datasrc/tests/Makefile.am
    experiments/327-sync/src/lib/datasrc/tests/datasrc_unittest.cc
    experiments/327-sync/src/lib/datasrc/tests/query_unittest.cc
    experiments/327-sync/src/lib/datasrc/tests/run_unittests.cc
    experiments/327-sync/src/lib/dns/Makefile.am
    experiments/327-sync/src/lib/dns/exceptions.cc
    experiments/327-sync/src/lib/dns/gen-rdatacode.py.in
    experiments/327-sync/src/lib/dns/message.cc
    experiments/327-sync/src/lib/dns/message.h
    experiments/327-sync/src/lib/dns/name.h
    experiments/327-sync/src/lib/dns/python/Makefile.am
    experiments/327-sync/src/lib/dns/python/README
    experiments/327-sync/src/lib/dns/python/message_python.cc
    experiments/327-sync/src/lib/dns/python/messagerenderer_python.cc
    experiments/327-sync/src/lib/dns/python/name_python.cc
    experiments/327-sync/src/lib/dns/python/question_python.cc
    experiments/327-sync/src/lib/dns/python/rdata_python.cc
    experiments/327-sync/src/lib/dns/python/rrclass_python.cc
    experiments/327-sync/src/lib/dns/python/rrset_python.cc
    experiments/327-sync/src/lib/dns/python/rrttl_python.cc
    experiments/327-sync/src/lib/dns/python/rrtype_python.cc
    experiments/327-sync/src/lib/dns/python/tests/Makefile.am
    experiments/327-sync/src/lib/dns/python/tests/message_python_test.py
    experiments/327-sync/src/lib/dns/python/tests/messagerenderer_python_test.py
    experiments/327-sync/src/lib/dns/python/tests/name_python_test.py
    experiments/327-sync/src/lib/dns/python/tests/question_python_test.py
    experiments/327-sync/src/lib/dns/python/tests/rdata_python_test.py
    experiments/327-sync/src/lib/dns/python/tests/rrclass_python_test.py
    experiments/327-sync/src/lib/dns/python/tests/rrset_python_test.py
    experiments/327-sync/src/lib/dns/python/tests/rrttl_python_test.py
    experiments/327-sync/src/lib/dns/python/tests/rrtype_python_test.py
    experiments/327-sync/src/lib/dns/question.cc
    experiments/327-sync/src/lib/dns/rdata.cc
    experiments/327-sync/src/lib/dns/rdata/ch_3/a_1.cc
    experiments/327-sync/src/lib/dns/rdata/generic/cname_5.cc
    experiments/327-sync/src/lib/dns/rdata/generic/dname_39.cc
    experiments/327-sync/src/lib/dns/rdata/generic/dnskey_48.cc
    experiments/327-sync/src/lib/dns/rdata/generic/ds_43.cc
    experiments/327-sync/src/lib/dns/rdata/generic/mx_15.cc
    experiments/327-sync/src/lib/dns/rdata/generic/mx_15.h
    experiments/327-sync/src/lib/dns/rdata/generic/ns_2.cc
    experiments/327-sync/src/lib/dns/rdata/generic/nsec3_50.cc
    experiments/327-sync/src/lib/dns/rdata/generic/nsec3param_51.cc
    experiments/327-sync/src/lib/dns/rdata/generic/opt_41.cc
    experiments/327-sync/src/lib/dns/rdata/generic/ptr_12.cc
    experiments/327-sync/src/lib/dns/rdata/generic/rrsig_46.cc
    experiments/327-sync/src/lib/dns/rdata/generic/soa_6.cc
    experiments/327-sync/src/lib/dns/rdata/generic/soa_6.h
    experiments/327-sync/src/lib/dns/rdata/hs_4/a_1.cc
    experiments/327-sync/src/lib/dns/rdata/template.cc
    experiments/327-sync/src/lib/dns/rrclass-placeholder.h
    experiments/327-sync/src/lib/dns/rrclass.cc
    experiments/327-sync/src/lib/dns/rrparamregistry-placeholder.cc
    experiments/327-sync/src/lib/dns/rrset.cc
    experiments/327-sync/src/lib/dns/rrset.h
    experiments/327-sync/src/lib/dns/rrsetlist.cc
    experiments/327-sync/src/lib/dns/rrttl.cc
    experiments/327-sync/src/lib/dns/rrtype-placeholder.h
    experiments/327-sync/src/lib/dns/rrtype.cc
    experiments/327-sync/src/lib/dns/tests/Makefile.am
    experiments/327-sync/src/lib/dns/tests/buffer_unittest.cc
    experiments/327-sync/src/lib/dns/tests/message_unittest.cc
    experiments/327-sync/src/lib/dns/tests/messagerenderer_unittest.cc
    experiments/327-sync/src/lib/dns/tests/name_unittest.cc
    experiments/327-sync/src/lib/dns/tests/question_unittest.cc
    experiments/327-sync/src/lib/dns/tests/rdata_cname_unittest.cc
    experiments/327-sync/src/lib/dns/tests/rdata_dname_unittest.cc
    experiments/327-sync/src/lib/dns/tests/rdata_ns_unittest.cc
    experiments/327-sync/src/lib/dns/tests/rdata_nsec_unittest.cc
    experiments/327-sync/src/lib/dns/tests/rdata_opt_unittest.cc
    experiments/327-sync/src/lib/dns/tests/rdata_ptr_unittest.cc
    experiments/327-sync/src/lib/dns/tests/rdata_rrsig_unittest.cc
    experiments/327-sync/src/lib/dns/tests/rdata_soa_unittest.cc
    experiments/327-sync/src/lib/dns/tests/rdata_txt_unittest.cc
    experiments/327-sync/src/lib/dns/tests/rdata_unittest.cc
    experiments/327-sync/src/lib/dns/tests/rrclass_unittest.cc
    experiments/327-sync/src/lib/dns/tests/rrparamregistry_unittest.cc
    experiments/327-sync/src/lib/dns/tests/rrset_unittest.cc
    experiments/327-sync/src/lib/dns/tests/rrttl_unittest.cc
    experiments/327-sync/src/lib/dns/tests/rrtype_unittest.cc
    experiments/327-sync/src/lib/dns/tests/run_unittests.cc
    experiments/327-sync/src/lib/dns/tests/testdata/gen-wiredata.py.in
    experiments/327-sync/src/lib/dns/util/sha1.cc
    experiments/327-sync/src/lib/exceptions/exceptions.cc
    experiments/327-sync/src/lib/exceptions/exceptions.h
    experiments/327-sync/src/lib/exceptions/tests/run_unittests.cc
    experiments/327-sync/src/lib/python/isc/Makefile.am
    experiments/327-sync/src/lib/python/isc/cc/Makefile.am
    experiments/327-sync/src/lib/python/isc/cc/data.py
    experiments/327-sync/src/lib/python/isc/cc/session.py
    experiments/327-sync/src/lib/python/isc/cc/tests/session_test.py
    experiments/327-sync/src/lib/python/isc/config/Makefile.am
    experiments/327-sync/src/lib/python/isc/config/ccsession.py
    experiments/327-sync/src/lib/python/isc/config/cfgmgr.py
    experiments/327-sync/src/lib/python/isc/config/module_spec.py
    experiments/327-sync/src/lib/python/isc/config/tests/Makefile.am
    experiments/327-sync/src/lib/python/isc/config/tests/ccsession_test.py
    experiments/327-sync/src/lib/python/isc/config/tests/cfgmgr_test.py
    experiments/327-sync/src/lib/python/isc/config/tests/unittest_fakesession.py
    experiments/327-sync/src/lib/python/isc/datasrc/master.py
    experiments/327-sync/src/lib/python/isc/dns/__init__.py
    experiments/327-sync/src/lib/python/isc/log/Makefile.am
    experiments/327-sync/src/lib/python/isc/log/log.py
    experiments/327-sync/src/lib/python/isc/log/tests/log_test.py
    experiments/327-sync/src/lib/python/isc/notify/Makefile.am
    experiments/327-sync/src/lib/python/isc/notify/notify_out.py
    experiments/327-sync/src/lib/python/isc/notify/tests/notify_out_test.py
    experiments/327-sync/src/lib/xfr/Makefile.am
    experiments/327-sync/src/lib/xfr/fd_share.cc
    experiments/327-sync/src/lib/xfr/fd_share.h
    experiments/327-sync/src/lib/xfr/fdshare_python.cc
    experiments/327-sync/src/lib/xfr/python_xfr.cc
    experiments/327-sync/src/lib/xfr/xfrout_client.cc

Modified: experiments/327-sync/ChangeLog
==============================================================================
--- experiments/327-sync/ChangeLog (original)
+++ experiments/327-sync/ChangeLog Tue Nov  9 10:38:17 2010
@@ -1,11 +1,154 @@
+<<<<<<< .working
   TBD.  [func]      vorner
 	The b10-recursive is configured through config manager.
 	It has "listen_on" and "forward_addresses" options.
 	(Trac #389, r3448)
 
+=======
+  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)
+
+  111.	[bug]*   zhanglikun, Michal Vaner
+	Make sure process xfrin/xfrout/zonemgr/cmdctl can be stoped
+	properly when user enter "ctrl+c" or 'Boss shutdown' command
+	through	bindctl.
+
+	The ZonemgrRefresh.run_timer and NotifyOut.dispatcher spawn
+	a thread themselves.
+	(Trac #335, svn r3273)
+
+  110.  [func]      Michal Vaner
+	Added isc.net.check module to check ip addresses and ports for
+	correctness and isc.net.addr to hold IP address. The bind10, xfrin
+	and cmdctl programs are modified to use it.
+	(Trac #353, svn r3240)
+
+  109.  [func]		naokikambe
+	Added the initial version of the stats module for the statistics
+	feature of BIND 10, which supports the restricted features and
+	items and reports via bindctl command (Trac #191, r3218)
+	Added the document of the stats module, which is about how stats
+	module collects the data (Trac #170, [wiki:StatsModule])
+
+  108.	[func]		jerry
+	src/bin/zonemgr: Provide customizable configurations for
+	lowerbound_refresh, lowerbound_retry, max_transfer_timeout and
+	jitter_scope. (Trac #340, r3205)
+
+  107.  [func]       zhang likun
+	Remove the parameter 'db_file' for command 'retransfer' of
+	xfrin module. xfrin.spec will not be generated by script.
+	(Trac #329, r3171)
+
+  106.  [bug]       zhang likun
+	When xfrin can't connect with one zone's master, it should tell
+	the bad news to zonemgr, so that zonemgr can reset the timer for
+	that zone. (Trac #329, r3170)
+
+  105.  [bug]       Michal Vaner
+	Python processes: they no longer take 100% CPU while idle
+	due to a busy loop in reading command session in a nonblocking way.
+	(Trac #349, svn r3153), (Trac #382, svn r3294)
+
+  104.	[bug]		jerry
+	bin/zonemgr: zonemgr should be attempting to refresh expired zones.
+	(Trac #336, r3139)
+				   
+  103.	[bug]		jerry
+	lib/python/isc/log: Fixed an issue with python logging,
+	python log shouldn't die with OSError.(Trac #267, r3137)
+				   
+  102.	[build]		jinmei
+	Disable threads in ASIO to minimize build time dependency.
+	(Trac #345, r3100)
+
+  101.	[func]		jinmei
+	src/lib/dns: Completed Opcode and Rcode implementation with more
+	tests and documentation.  API is mostly the same but the
+	validation was a bit tightened. (Trac #351, svn r3056)
+
+  100.  [func]      Michal Vaner
+	Python processes: support naming of python processes so
+	they're not all called python3.
+	(Trac #322, svn r3052)
+
+  99.	[func]*		jinmei
+	Introduced a separate EDNS class to encapsulate EDNS related
+	information more cleanly.  The related APIs are changed a bit,
+	although it won't affect most of higher level applications.
+	(Trac #311, svn r3020)
+
+  98.	[build]		jinmei
+	The ./configure script now tries to search some common include
+	paths for boost header files to minimize the need for explicit
+	configuration with --with-boost-include. (Trac #323, svn r3006)
+
+  97.	[func]		jinmei
+	Added a micro benchmark test for query processing of b10-auth.
+	(Trac #308, svn r2982)
+
+  96.	[bug]		jinmei
+	Fixed two small issues with configure: Do not set CXXFLAGS so that
+	it can be customized; Make sure --disable-static works.
+	(Trac #325, r2976)
+
+bind10-devel-20100917 released on September 17, 2010 
+
+  95.	[doc]		jreed
+	Add b10-zonemgr manual page. Update other docs to introduce
+	this secondary manager. (Trac #341, svn r2951)
+
+  95.	[bug]		jreed
+	bin/xfrout and bin/zonemgr: Fixed some stderr output.
+	(Trac #342, svn r2949)
+
+  94.	[bug]		jelte
+  	bin/xfrout:  Fixed a problem in xfrout where only 2 or 3 RRs
+	were used per DNS message in the xfrout stream.
+	(Trac #334, r2931)
+
+  93.	[bug]		jinmei
+	lib/datasrc: A DS query could crash the library (and therefore,
+	e.g. the authoritative server) if some RR of the same apex name
+	is stored in the hot spot cache.  (Trac #307, svn r2923)
+
+  92.	[func]*		jelte
+	libdns_python (the python wrappers for libdns++) has been renamed
+	to pydnspp (Python DNS++). Programs and libraries that used
+	'import libdns_python' now need to use 'import pydnspp'.
+	(Trac #314, r2902)
+
+>>>>>>> .merge-right.r3495
   91.	[func]*		jinmei
 	lib/cc: Use const pointers and const member functions for the API
-	as much as possible for safer operations.  Basically this does
+	as much as possible for safer operations.  Basically this does not
 	change the observable behavior, but some of the API were changed
 	in a backward incompatible manner.  This change also involves more
 	copies, but at this moment the overhead is deemed acceptable.
@@ -34,8 +177,8 @@
 	zone axfr/ixfr finishing, the server will notify its slaves.
 	(Trac #289, svn r2737)
 
-  86.   [func]		jerry
-    	bin/zonemgr: Added zone manager module. The zone manager is one 
+  86.	[func]		jerry
+	bin/zonemgr: Added zone manager module. The zone manager is one 
 	of the co-operating processes of BIND10, which keeps track of 
 	timers and other information necessary for BIND10 to act as a 
 	slave. (Trac #215, svn r2737)

Modified: experiments/327-sync/README
==============================================================================
--- experiments/327-sync/README (original)
+++ experiments/327-sync/README Tue Nov  9 10:38:17 2010
@@ -17,7 +17,8 @@
 bus, b10-auth authoritative DNS server (with SQLite3 backend),
 b10-cmdctl remote control daemon, b10-cfgmgr configuration manager,
 b10-xfrin AXFR inbound service, b10-xfrout outgoing AXFR service,
-and a new libdns++ library for C++ with a python wrapper.
+b10-zonemgr secondary manager, and a new libdns++ library for C++
+with a python wrapper.
 
 Documentation is included and also available via the BIND 10
 website at http://bind10.isc.org/

Modified: experiments/327-sync/configure.ac
==============================================================================
--- experiments/327-sync/configure.ac (original)
+++ experiments/327-sync/configure.ac Tue Nov  9 10:38:17 2010
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ([2.59])
-AC_INIT(bind10-devel, 20100701, bind10-dev at isc.org)
+AC_INIT(bind10-devel, 20101013, bind10-dev at isc.org)
 AC_CONFIG_SRCDIR(README)
 AM_INIT_AUTOMAKE
 AC_CONFIG_HEADERS([config.h])
@@ -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
 
@@ -39,6 +41,20 @@
   [build programs with static link [[default=no]]]),
   [enable_static_link=yes], [enable_static_link=no])
 AM_CONDITIONAL(USE_STATIC_LINK, test $enable_static_link = yes)
+
+# Check validity about some libtool options
+if test $enable_static_link = yes -a $enable_static = no; then
+	AC_MSG_ERROR([--enable-static-link requires --enable-static])
+fi
+if test $enable_shared = no; then
+	AC_MSG_ERROR([BIND 10 requires shared libraries to be built])
+fi
+
+# allow configuring without setproctitle.
+AC_ARG_ENABLE(setproctitle-check,
+AC_HELP_STRING([--disable-setproctitle-check],
+  [do not check for python setproctitle module (used to give nice names to python processes)]),
+  setproctitle_check=$enableval, setproctitle_check=yes)
 
 # OS dependent configuration
 SET_ENV_LIBRARY_PATH=no
@@ -154,6 +170,18 @@
 AC_SUBST(PYTHON_LIB)
 LDFLAGS=$LDFLAGS_SAVED
 
+# Check for the setproctitle module
+if test "$setproctitle_check" = "yes" ; then
+    AC_MSG_CHECKING(for setproctitle module)
+    if "$PYTHON" -c 'import setproctitle' 2>/dev/null ; then
+        AC_MSG_RESULT(ok)
+    else
+        AC_MSG_RESULT(missing)
+        AC_MSG_ERROR([Missing setproctitle module. Either install it or provide --disable-setproctitle-check.
+In that case we will continue, but naming of python processes will not work.])
+    fi
+fi
+
 # TODO: check for _sqlite3.py module
 
 # Compiler dependent settings: define some mandatory CXXFLAGS here.
@@ -167,7 +195,6 @@
 # specify the default warning flags in CXXFLAGS and let specific modules
 # "override" the default.
 
-CXXFLAGS=-g
 werror_ok=0
 
 # SunStudio compiler requires special compiler options for boost
@@ -236,7 +263,6 @@
 [  --with-gtest=PATH       specify a path to gtest header files (PATH/include) and library (PATH/lib)],
     gtest_path="$withval", gtest_path="no")
 
-
 USE_LCOV="no"
 if test "$lcov" != "no"; then
 	# force gtest if not set
@@ -270,14 +296,33 @@
 fi
 AC_SUBST(USE_LCOV)
 
+#
+# Configure Boost header path
+#
+# If explicitly specified, use it.
 AC_ARG_WITH([boost-include],
   AC_HELP_STRING([--with-boost-include=PATH],
     [specify exact directory for Boost headers]),
     [boost_include_path="$withval"])
+# If not specified, try some common paths.
+if test -z "$with_boost_include"; then
+	boostdirs="/usr/local /usr/pkg /opt /opt/local"
+	for d in $boostdirs
+	do
+		if test -f $d/include/boost/shared_ptr.hpp; then
+			boost_include_path=$d/include
+			break
+		fi
+	done
+fi
+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_MSG_ERROR([Missing required header files.]))
+CPPFLAGS="$CPPFLAGS_SAVES"
 AC_SUBST(BOOST_INCLUDES)
 
 #
@@ -351,6 +396,9 @@
 # Use local ASIO headers from ext
 #
 CPPFLAGS="$CPPFLAGS -I\$(top_srcdir)/ext/asio"
+#
+# Disable threads: Currently we don't use them.
+CPPFLAGS="$CPPFLAGS -DASIO_DISABLE_THREADS=1"
 #
 # kqueue portability: ASIO uses kqueue by default if it's available (it's
 # generally available in BSD variants).  Unfortunately, some public
@@ -389,12 +437,8 @@
 	CPPFLAGS="$CPPFLAGS -DASIO_DISABLE_DEV_POLL=1"
 fi
 
-# Check for headers from required devel kits.
-AC_CHECK_HEADERS([boost/shared_ptr.hpp boost/foreach.hpp],,
-  AC_MSG_ERROR([Missing required header files.]))
-
 AC_ARG_ENABLE(man, [AC_HELP_STRING([--enable-man],
-  [regenerate man pages [default=no]])] ,enable_man=yes, enable_man=no)
+  [regenerate man pages [default=no]])], enable_man=yes, enable_man=no)
 
 AM_CONDITIONAL(ENABLE_MAN, test x$enable_man != xno)
 
@@ -423,15 +467,28 @@
                  src/bin/msgq/tests/Makefile
                  src/bin/auth/Makefile
                  src/bin/auth/tests/Makefile
+<<<<<<< .working
                  src/bin/recurse/Makefile
                  src/bin/recurse/tests/Makefile
+=======
+                 src/bin/auth/tests/testdata/Makefile
+                 src/bin/auth/benchmarks/Makefile
+>>>>>>> .merge-right.r3495
                  src/bin/xfrin/Makefile
                  src/bin/xfrin/tests/Makefile
                  src/bin/xfrout/Makefile
                  src/bin/xfrout/tests/Makefile
                  src/bin/zonemgr/Makefile
                  src/bin/zonemgr/tests/Makefile
+                 src/bin/stats/Makefile
+                 src/bin/stats/tests/Makefile
+                 src/bin/stats/tests/isc/Makefile
+                 src/bin/stats/tests/isc/cc/Makefile
+                 src/bin/stats/tests/isc/config/Makefile
+                 src/bin/stats/tests/isc/util/Makefile
+                 src/bin/stats/tests/testdata/Makefile
                  src/bin/usermgr/Makefile
+                 src/bin/tests/Makefile
                  src/lib/Makefile
                  src/lib/asiolink/Makefile
                  src/lib/asiolink/tests/Makefile
@@ -442,6 +499,8 @@
                  src/lib/cc/tests/Makefile
                  src/lib/python/Makefile
                  src/lib/python/isc/Makefile
+                 src/lib/python/isc/util/Makefile
+                 src/lib/python/isc/util/tests/Makefile
                  src/lib/python/isc/datasrc/Makefile
                  src/lib/python/isc/cc/Makefile
                  src/lib/python/isc/cc/tests/Makefile
@@ -449,13 +508,16 @@
                  src/lib/python/isc/config/tests/Makefile
                  src/lib/python/isc/log/Makefile
                  src/lib/python/isc/log/tests/Makefile
+                 src/lib/python/isc/net/Makefile
+                 src/lib/python/isc/net/tests/Makefile
                  src/lib/python/isc/notify/Makefile
                  src/lib/python/isc/notify/tests/Makefile
                  src/lib/config/Makefile
                  src/lib/config/tests/Makefile
-                 src/lib/config/testdata/Makefile
+                 src/lib/config/tests/testdata/Makefile
                  src/lib/dns/Makefile
                  src/lib/dns/tests/Makefile
+                 src/lib/dns/tests/testdata/Makefile
                  src/lib/dns/python/Makefile
                  src/lib/dns/python/tests/Makefile
                  src/lib/exceptions/Makefile
@@ -472,7 +534,6 @@
            src/bin/cmdctl/cmdctl.spec.pre
            src/bin/xfrin/tests/xfrin_test
            src/bin/xfrin/xfrin.py
-           src/bin/xfrin/xfrin.spec.pre
            src/bin/xfrin/run_b10-xfrin.sh
            src/bin/xfrout/xfrout.py
            src/bin/xfrout/xfrout.spec.pre
@@ -482,6 +543,12 @@
            src/bin/zonemgr/zonemgr.spec.pre
            src/bin/zonemgr/tests/zonemgr_test
            src/bin/zonemgr/run_b10-zonemgr.sh
+           src/bin/stats/stats.py
+           src/bin/stats/stats_stub.py
+           src/bin/stats/stats.spec.pre
+           src/bin/stats/run_b10-stats.sh
+           src/bin/stats/run_b10-stats_stub.sh
+           src/bin/stats/tests/stats_test
            src/bin/bind10/bind10.py
            src/bin/bind10/tests/bind10_test
            src/bin/bind10/run_bind10.sh
@@ -499,8 +566,12 @@
            src/bin/msgq/run_msgq.sh
            src/bin/auth/auth.spec.pre
            src/bin/auth/spec_config.h.pre
+<<<<<<< .working
            src/bin/recurse/recurse.spec.pre
            src/bin/recurse/spec_config.h.pre
+=======
+           src/bin/tests/process_rename_test.py
+>>>>>>> .merge-right.r3495
            src/lib/config/tests/data_def_unittests_config.h
            src/lib/python/isc/config/tests/config_test
            src/lib/python/isc/cc/tests/cc_test
@@ -516,6 +587,9 @@
            chmod +x src/bin/xfrin/run_b10-xfrin.sh
            chmod +x src/bin/xfrout/run_b10-xfrout.sh
            chmod +x src/bin/zonemgr/run_b10-zonemgr.sh
+           chmod +x src/bin/stats/tests/stats_test
+           chmod +x src/bin/stats/run_b10-stats.sh
+           chmod +x src/bin/stats/run_b10-stats_stub.sh
            chmod +x src/bin/bind10/run_bind10.sh
            chmod +x src/bin/cmdctl/tests/cmdctl_test
            chmod +x src/bin/xfrin/tests/xfrin_test
@@ -546,16 +620,18 @@
   Name:          $PACKAGE_NAME
   Version:       $PACKAGE_VERSION
 
+C++ Compiler:    $CXX
+
 Flags:
   DEFS:          $DEFS
   CPPFLAGS:      $CPPFLAGS
-  CFLAGS:        $CFLAGS
   CXXFLAGS:      $CXXFLAGS
   B10_CXXFLAGS:  $B10_CXXFLAGS
 dnl includes too
   Python:        ${PYTHON_INCLUDES}
                  ${PYTHON_LDFLAGS}
                  ${PYTHON_LIB}
+  Boost:         ${BOOST_INCLUDES}
   SQLite:        $SQLITE_CFLAGS
                  $SQLITE_LIBS
 
@@ -575,4 +651,3 @@
   Now you can type "make" to build BIND 10
 
 EOF
-

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

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

Modified: experiments/327-sync/src/bin/Makefile.am
==============================================================================
--- experiments/327-sync/src/bin/Makefile.am (original)
+++ experiments/327-sync/src/bin/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,1 +1,8 @@
+<<<<<<< .working
 SUBDIRS = bind10 bindctl cfgmgr loadzone msgq host cmdctl auth recurse xfrin xfrout usermgr zonemgr
+=======
+SUBDIRS = bind10 bindctl cfgmgr loadzone msgq host cmdctl auth xfrin xfrout \
+	usermgr zonemgr stats tests
+
+check-recursive: all-recursive
+>>>>>>> .merge-right.r3495

Modified: experiments/327-sync/src/bin/auth/Makefile.am
==============================================================================
--- experiments/327-sync/src/bin/auth/Makefile.am (original)
+++ experiments/327-sync/src/bin/auth/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,4 +1,4 @@
-SUBDIRS = . tests
+SUBDIRS = . tests benchmarks
 
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin
@@ -6,6 +6,7 @@
 AM_CPPFLAGS += -I$(top_srcdir)/src/lib/cc -I$(top_builddir)/src/lib/cc
 AM_CPPFLAGS += -I$(top_srcdir)/src/lib/asiolink
 AM_CPPFLAGS += -I$(top_builddir)/src/lib/asiolink
+AM_CPPFLAGS += $(BOOST_INCLUDES)
 
 AM_CXXFLAGS = $(B10_CXXFLAGS)
 
@@ -31,6 +32,29 @@
 spec_config.h: spec_config.h.pre
 	$(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" spec_config.h.pre >$@
 
+<<<<<<< .working
+=======
+# This is a wrapper library solely used for b10-auth.  The ASIO header files
+# have some code fragments that would hit gcc's unused-parameter warning,
+# which would make the build fail with -Werror (our default setting).
+# We don't want to lower the warning level for our own code just for ASIO,
+# so as a workaround we extract the ASIO related code into a separate library,
+# only for which we accept the unused-parameter warning.
+lib_LIBRARIES = libasio_link.a
+libasio_link_a_SOURCES = asio_link.cc asio_link.h
+# Note: the ordering matters: -Wno-... must follow -Wextra (defined in
+# B10_CXXFLAGS)
+libasio_link_a_CXXFLAGS = $(AM_CXXFLAGS)
+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)
+
+>>>>>>> .merge-right.r3495
 BUILT_SOURCES = spec_config.h 
 pkglibexec_PROGRAMS = b10-auth
 b10_auth_SOURCES = auth_srv.cc auth_srv.h

Modified: experiments/327-sync/src/bin/auth/auth_srv.cc
==============================================================================
--- experiments/327-sync/src/bin/auth/auth_srv.cc (original)
+++ experiments/327-sync/src/bin/auth/auth_srv.cc Tue Nov  9 10:38:17 2010
@@ -32,10 +32,13 @@
 #include <exceptions/exceptions.h>
 
 #include <dns/buffer.h>
+#include <dns/edns.h>
 #include <dns/exceptions.h>
 #include <dns/messagerenderer.h>
 #include <dns/name.h>
 #include <dns/question.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
 #include <dns/rrset.h>
 #include <dns/rrttl.h>
 #include <dns/message.h>
@@ -72,6 +75,7 @@
     ~AuthSrvImpl();
     isc::data::ConstElementPtr setDbFile(isc::data::ConstElementPtr config);
 
+<<<<<<< .working
     bool processNormalQuery(const IOMessage& io_message, MessagePtr message,
                             OutputBufferPtr buffer);
     bool processAxfrQuery(const IOMessage& io_message, MessagePtr message,
@@ -88,6 +92,14 @@
     AbstractSession* xfrin_session_;
 
 private:
+=======
+    bool processNormalQuery(const IOMessage& io_message, Message& message,
+                            MessageRenderer& response_renderer);
+    bool processAxfrQuery(const IOMessage& io_message, Message& message,
+                            MessageRenderer& response_renderer);
+    bool processNotify(const IOMessage& io_message, Message& message,
+                            MessageRenderer& response_renderer);
+>>>>>>> .merge-right.r3495
     std::string db_file_;
 
     MetaDataSrc data_sources_;
@@ -216,10 +228,17 @@
     // extract the parameters that should be kept.
     // 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.
+<<<<<<< .working
     const qid_t qid = message->getQid();
     const bool rd = message->getHeaderFlag(MessageFlag::RD());
     const bool cd = message->getHeaderFlag(MessageFlag::CD());
     const Opcode& opcode = message->getOpcode();
+=======
+    const qid_t qid = message.getQid();
+    const bool rd = message.getHeaderFlag(Message::HEADERFLAG_RD);
+    const bool cd = message.getHeaderFlag(Message::HEADERFLAG_CD);
+    const Opcode& opcode = message.getOpcode();
+>>>>>>> .merge-right.r3495
     vector<QuestionPtr> questions;
 
     // If this is an error to a query or notify, we should also copy the
@@ -228,16 +247,31 @@
         questions.assign(message->beginQuestion(), message->endQuestion());
     }
 
+<<<<<<< .working
     message->clear(Message::RENDER);
     message->setQid(qid);
     message->setOpcode(opcode);
     message->setHeaderFlag(MessageFlag::QR());
     message->setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
+=======
+    message.clear(Message::RENDER);
+    message.setQid(qid);
+    message.setOpcode(opcode);
+    message.setHeaderFlag(Message::HEADERFLAG_QR);
+>>>>>>> .merge-right.r3495
     if (rd) {
+<<<<<<< .working
         message->setHeaderFlag(MessageFlag::RD());
+=======
+        message.setHeaderFlag(Message::HEADERFLAG_RD);
+>>>>>>> .merge-right.r3495
     }
     if (cd) {
+<<<<<<< .working
         message->setHeaderFlag(MessageFlag::CD());
+=======
+        message.setHeaderFlag(Message::HEADERFLAG_CD);
+>>>>>>> .merge-right.r3495
     }
     for_each(questions.begin(), questions.end(), QuestionInserter(message));
     message->setRcode(rcode);
@@ -260,6 +294,16 @@
 bool
 AuthSrv::getVerbose() const {
     return (impl_->verbose_mode_);
+}
+
+void
+AuthSrv::setCacheSlots(const size_t slots) {
+    impl_->cache_.setSlots(slots);
+}
+
+size_t
+AuthSrv::getCacheSlots() const {
+    return (impl_->cache_.getSlots());
 }
 
 void
@@ -289,7 +333,11 @@
         message->parseHeader(request_buffer);
 
         // Ignore all responses.
+<<<<<<< .working
         if (message->getHeaderFlag(MessageFlag::QR())) {
+=======
+        if (message.getHeaderFlag(Message::HEADERFLAG_QR)) {
+>>>>>>> .merge-right.r3495
             if (impl_->verbose_mode_) {
                 cerr << "[b10-auth] received unexpected response, ignoring"
                      << endl;
@@ -342,8 +390,16 @@
         }
         makeErrorMessage(message, buffer, Rcode::NOTIMP(),
                          impl_->verbose_mode_);
+<<<<<<< .working
     } else if (message->getRRCount(Section::QUESTION()) != 1) {
         makeErrorMessage(message, buffer, Rcode::FORMERR(),
+=======
+        return (true);
+    }
+
+    if (message.getRRCount(Message::SECTION_QUESTION) != 1) {
+        makeErrorMessage(message, response_renderer, Rcode::FORMERR(),
+>>>>>>> .merge-right.r3495
                          impl_->verbose_mode_);
     } else {
         ConstQuestionPtr question = *message->beginQuestion();
@@ -365,14 +421,34 @@
 AuthSrvImpl::processNormalQuery(const IOMessage& io_message, MessagePtr message,
                                 OutputBufferPtr buffer)
 {
+<<<<<<< .working
     const bool dnssec_ok = message->isDNSSECSupported();
     const uint16_t remote_bufsize = message->getUDPSize();
-
+=======
+    ConstEDNSPtr remote_edns = message.getEDNS();
+    const bool dnssec_ok = remote_edns && remote_edns->getDNSSECAwareness();
+    const uint16_t remote_bufsize = remote_edns ? remote_edns->getUDPSize() :
+        Message::DEFAULT_MAX_UDPSIZE;
+>>>>>>> .merge-right.r3495
+
+<<<<<<< .working
     message->makeResponse();
     message->setHeaderFlag(MessageFlag::AA());
     message->setRcode(Rcode::NOERROR());
     message->setDNSSECSupported(dnssec_ok);
     message->setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
+=======
+    message.makeResponse();
+    message.setHeaderFlag(Message::HEADERFLAG_AA);
+    message.setRcode(Rcode::NOERROR());
+>>>>>>> .merge-right.r3495
+
+    if (remote_edns) {
+        EDNSPtr local_edns = EDNSPtr(new EDNS());
+        local_edns->setDNSSECAwareness(dnssec_ok);
+        local_edns->setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
+        message.setEDNS(local_edns);
+    }
 
     try {
         Query query(*message, cache_, dnssec_ok);
@@ -415,8 +491,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(),
@@ -430,7 +508,7 @@
             xfrout_client_.disconnect();
             xfrout_connected_ = false;
         }
-        
+
         if (verbose_mode_) {
             cerr << "[b10-auth] Error in handling XFR request: " << err.what()
                  << endl;
@@ -439,22 +517,32 @@
         return (true);
     }
 
-    xfrout_client_.disconnect();
-    xfrout_connected_ = false;
-
     return (false);
 }
 
 bool
+<<<<<<< .working
 AuthSrvImpl::processNotify(const IOMessage& io_message, MessagePtr message, 
                            OutputBufferPtr buffer)
+=======
+AuthSrvImpl::processNotify(const IOMessage& io_message, Message& message,
+                           MessageRenderer& response_renderer)
+>>>>>>> .merge-right.r3495
 {
     // The incoming notify must contain exactly one question for SOA of the
     // zone name.
+<<<<<<< .working
     if (message->getRRCount(Section::QUESTION()) != 1) {
+=======
+    if (message.getRRCount(Message::SECTION_QUESTION) != 1) {
+>>>>>>> .merge-right.r3495
         if (verbose_mode_) {
                 cerr << "[b10-auth] invalid number of questions in notify: "
+<<<<<<< .working
                      << message->getRRCount(Section::QUESTION()) << endl;
+=======
+                     << message.getRRCount(Message::SECTION_QUESTION) << endl;
+>>>>>>> .merge-right.r3495
         }
         makeErrorMessage(message, buffer, Rcode::FORMERR(), verbose_mode_);
         return (true);
@@ -487,7 +575,7 @@
         }
         return (false);
     }
-    
+
     const string remote_ip_address =
         io_message.getRemoteEndpoint().getAddress().toText();
     static const string command_template_start =
@@ -498,7 +586,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);
@@ -512,7 +600,7 @@
         if (rcode != 0) {
             if (verbose_mode_) {
                 cerr << "[b10-auth] failed to notify Zonemgr: "
-                     << parsed_answer->str() << endl; 
+                     << parsed_answer->str() << endl;
             }
             return (false);
         }
@@ -523,12 +611,19 @@
         return (false);
     }
 
+<<<<<<< .working
     message->makeResponse();
     message->setHeaderFlag(MessageFlag::AA());
     message->setRcode(Rcode::NOERROR());
 
     MessageRenderer renderer(*buffer);
     message->toWire(renderer);
+=======
+    message.makeResponse();
+    message.setHeaderFlag(Message::HEADERFLAG_AA);
+    message.setRcode(Rcode::NOERROR());
+    message.toWire(response_renderer);
+>>>>>>> .merge-right.r3495
     return (true);
 }
 

Modified: experiments/327-sync/src/bin/auth/auth_srv.h
==============================================================================
--- experiments/327-sync/src/bin/auth/auth_srv.h (original)
+++ experiments/327-sync/src/bin/auth/auth_srv.h Tue Nov  9 10:38:17 2010
@@ -30,8 +30,30 @@
 }
 }
 
+/// \brief The implementation class for the \c AuthSrv class using the pimpl
+/// idiom.
 class AuthSrvImpl;
 
+/// \brief The authoritative nameserver class.
+///
+/// \c AuthSrv is a concrete class that implements authoritative DNS server
+/// protocol processing.
+/// An \c AuthSrv object is primarily responsible for handling incoming DNS
+/// requests: It parses the request and dispatches subsequent processing to
+/// the corresponding module (which may be an internal library or a separate
+/// process) depending on the request type.  For normal queries, the
+/// \c AuthSrv object searches configured data sources for the answer to the
+/// query, and builds a response containing the answer.
+///
+/// This class uses the "pimpl" idiom, and hides detailed implementation
+/// through the \c impl_ pointer (which points to an instance of the
+/// \c AuthSrvImpl class).  An \c AuthSrv object is supposed to exist for quite
+/// a long period, and only a few \c AuthSrv objects will be created (in fact,
+/// in this current implementation there will only be one object), so the
+/// construction overhead of this approach should be acceptable.
+///
+/// The design of this class is still in flux.  It's quite likely to change
+/// in future versions.
 class AuthSrv {
     ///
     /// \name Constructors, Assignment Operator and Destructor.
@@ -74,15 +96,88 @@
     /// \brief Set verbose flag
     ///
     /// \param on The new value of the verbose flag
-    void setVerbose(bool on);
+
+    /// \brief Enable or disable verbose logging.
+    ///
+    /// This method never throws an exception.
+    ///
+    /// \param on \c true to enable verbose logging; \c false to disable
+    /// verbose logging.
+    void setVerbose(const bool on);
+
+    /// \brief Returns the logging verbosity of the \c AuthSrv object.
+    ///
+    /// This method never throws an exception.
+    ///
+    /// \return \c true if verbose logging is enabled; otherwise \c false.
 
     /// \brief Get the current value of the verbose flag
     bool getVerbose() const;
+<<<<<<< .working
 
     /// \brief Set and get the config session
+=======
+
+    /// \brief Updates the data source for the \c AuthSrv object.
+    ///
+    /// This method installs or replaces the data source that the \c AuthSrv
+    /// object refers to for query processing.
+    /// Although the method name is generic, the only thing it does is to
+    /// update the data source information.
+    /// If there is a data source installed, it will be replaced with the
+    /// new one.
+    ///
+    /// In the current implementation, the SQLite data source is assumed.
+    /// The \c config parameter will simply be passed to the initialization
+    /// routine of the \c Sqlite3DataSrc class.
+    ///
+    /// On success this method returns a data \c Element (in the form of a
+    /// pointer like object) indicating the successful result,
+    /// i.e., {"result": [0]}.
+    /// Otherwise, it returns a data \c Element explaining the error:
+    /// {"result": [1, <error-description>]}.
+    ///
+    /// This method is mostly exception free (error conditions are represented
+    /// via the return value).  But it may still throw a standard exception
+    /// if memory allocation fails inside the method.
+    /// When a standard exception is thrown or an implementation specific
+    /// exception is triggered and caught internally, this function provides
+    /// the strong exception guarantee: Unless everything succeeds, currently
+    /// installed data source (if any) won't be replaced.
+    ///
+    /// \param config An immutable pointer-like object to a data \c Element,
+    /// possibly containing the data source information to be used.
+    /// \return An immutable pointer-like object to a data \c Element
+    /// containing the result of the update operation.
+    isc::data::ConstElementPtr updateConfig(isc::data::ConstElementPtr config);
+
+    /// \param Returns the command and configuration session for the
+    /// \c AuthSrv.
+    ///
+    /// This method never throws an exception.
+    ///
+    /// \return A pointer to \c ModuleCCSession object stored in the
+    /// \c AuthSrv object.  In this implementation it could be NULL.
+    isc::config::ModuleCCSession* getConfigSession() const;
+
+    /// \brief Set the command and configuration session for the \c AuthSrv.
+    ///
+    /// Note: this interface is tentative.  We'll revisit the ASIO and session
+    /// frameworks, at which point the session will probably be passed on
+    /// construction of the server.
+    /// In the current implementation, this method is expected to be called
+    /// exactly once as part of initialization.  If this method is called
+    /// multiple times, previously specified session is silently overridden.
+    ///
+    /// This method never throws an exception.
+    ///
+    /// \param config_session A pointer to \c ModuleCCSession object to receive
+    /// control commands and configuration updates.
+>>>>>>> .merge-right.r3495
     void setConfigSession(isc::config::ModuleCCSession* config_session);
     isc::config::ModuleCCSession* getConfigSession() const;
 
+<<<<<<< .working
     /// \brief Handle commands from the config session
     isc::data::ConstElementPtr updateConfig(isc::data::ConstElementPtr config);
 
@@ -101,6 +196,30 @@
     /// \brief Return pointer to the Checkin callback function
     asiolink::SimpleCallback* getCheckinProvider() const { return (checkin_); }
 
+=======
+    /// \brief Set or update the size (number of slots) of hot spot cache.
+>>>>>>> .merge-right.r3495
+    ///
+    /// If the specified size is 0, it means the size will be unlimited.
+    /// The specified size is recorded even if the cache is disabled; the
+    /// new size will be effective when the cache is enabled.
+    ///
+    /// This method never throws an exception.
+    ///
+    /// \param slots The number of cache slots.
+    void setCacheSlots(const size_t slots);
+
+    /// \brief Get the current size (number of slots) of hot spot cache.
+    ///
+    /// It always returns the recorded size regardless of the cache is enabled.
+    ///
+    /// This method never throws an exception.
+    ///
+    /// \return The current number of cache slots.
+    size_t getCacheSlots() const;
+
+    /// \brief Set the communication session with a separate process for
+    /// outgoing zone transfers.
     ///
     /// Note: this interface is tentative.  We'll revisit the ASIO and session
     /// frameworks, at which point the session will probably be passed on
@@ -113,6 +232,7 @@
     /// Ownership isn't transferred: the caller is responsible for keeping
     /// this object to be valid while the server object is working and for
     /// disconnecting the session and destroying the object when the server
+    /// is shutdown.
     ///
     void setXfrinSession(isc::cc::AbstractSession* xfrin_session);
 private:

Modified: experiments/327-sync/src/bin/auth/b10-auth.8
==============================================================================
--- experiments/327-sync/src/bin/auth/b10-auth.8 (original)
+++ experiments/327-sync/src/bin/auth/b10-auth.8 Tue Nov  9 10:38:17 2010
@@ -137,6 +137,7 @@
 \fBb10-cmdctl\fR(8),
 \fBb10-loadzone\fR(8),
 \fBb10-msgq\fR(8),
+\fBb10-zonemgr\fR(8),
 \fBbind10\fR(8),
 BIND 10 Guide\&.
 .SH "HISTORY"

Modified: experiments/327-sync/src/bin/auth/b10-auth.xml
==============================================================================
--- experiments/327-sync/src/bin/auth/b10-auth.xml (original)
+++ experiments/327-sync/src/bin/auth/b10-auth.xml Tue Nov  9 10:38:17 2010
@@ -201,6 +201,9 @@
         <refentrytitle>b10-msgq</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
       <citerefentry>
+        <refentrytitle>b10-zonemgr</refentrytitle><manvolnum>8</manvolnum>
+      </citerefentry>,
+      <citerefentry>
         <refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
       <citetitle>BIND 10 Guide</citetitle>.

Modified: experiments/327-sync/src/bin/auth/tests/Makefile.am
==============================================================================
--- experiments/327-sync/src/bin/auth/tests/Makefile.am (original)
+++ experiments/327-sync/src/bin/auth/tests/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,7 +1,11 @@
+SUBDIRS = testdata .
+
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += -I$(top_builddir)/src/lib/dns -I$(top_srcdir)/src/bin
 AM_CPPFLAGS += -I$(top_builddir)/src/lib/cc
+AM_CPPFLAGS += $(BOOST_INCLUDES)
 AM_CPPFLAGS += -DTEST_DATA_DIR=\"$(srcdir)/testdata\"
+AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/bin/auth/tests/testdata\"
 
 AM_CXXFLAGS = $(B10_CXXFLAGS)
 
@@ -35,25 +39,3 @@
 endif
 
 noinst_PROGRAMS = $(TESTS)
-
-EXTRA_DIST =  testdata/badExampleQuery_fromWire
-EXTRA_DIST += testdata/badExampleQuery_fromWire.spec
-EXTRA_DIST += testdata/example.com
-EXTRA_DIST += testdata/examplequery_fromWire
-EXTRA_DIST += testdata/examplequery_fromWire.spec
-EXTRA_DIST += testdata/example.sqlite3
-EXTRA_DIST += testdata/iqueryresponse_fromWire
-EXTRA_DIST += testdata/iqueryresponse_fromWire.spec
-EXTRA_DIST += testdata/multiquestion_fromWire
-EXTRA_DIST += testdata/multiquestion_fromWire.spec
-EXTRA_DIST += testdata/queryBadEDNS_fromWire
-EXTRA_DIST += testdata/queryBadEDNS_fromWire.spec
-EXTRA_DIST += testdata/shortanswer_fromWire
-EXTRA_DIST += testdata/shortanswer_fromWire.spec
-EXTRA_DIST += testdata/shortmessage_fromWire
-EXTRA_DIST += testdata/shortquestion_fromWire
-EXTRA_DIST += testdata/shortresponse_fromWire
-EXTRA_DIST += testdata/simplequery_fromWire
-EXTRA_DIST += testdata/simplequery_fromWire.spec
-EXTRA_DIST += testdata/simpleresponse_fromWire
-EXTRA_DIST += testdata/simpleresponse_fromWire.spec

Modified: experiments/327-sync/src/bin/auth/tests/auth_srv_unittest.cc
==============================================================================
--- experiments/327-sync/src/bin/auth/tests/auth_srv_unittest.cc (original)
+++ experiments/327-sync/src/bin/auth/tests/auth_srv_unittest.cc Tue Nov  9 10:38:17 2010
@@ -22,6 +22,8 @@
 #include <dns/name.h>
 #include <dns/message.h>
 #include <dns/messagerenderer.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
 #include <dns/rrclass.h>
 #include <dns/rrtype.h>
 
@@ -69,12 +71,21 @@
 protected:
     AuthSrvTest() : server(true, xfrout),
                     request_message(Message::RENDER),
+<<<<<<< .working
                     parse_message(new Message(Message::PARSE)),
                     default_qid(0x1035), opcode(Opcode(Opcode::QUERY())),
                     qname("www.example.com"), qclass(RRClass::IN()),
                     qtype(RRType::A()), io_message(NULL), endpoint(NULL),
                     request_obuffer(0), request_renderer(request_obuffer),
                     response_obuffer(new OutputBuffer(0))
+=======
+                    parse_message(Message::PARSE), default_qid(0x1035),
+                    opcode(Opcode::QUERY()), qname("www.example.com"),
+                    qclass(RRClass::IN()), qtype(RRType::A()),
+                    io_message(NULL), endpoint(NULL), request_obuffer(0),
+                    request_renderer(request_obuffer),
+                    response_obuffer(0), response_renderer(response_obuffer)
+>>>>>>> .merge-right.r3495
     {
         server.setXfrinSession(&notify_session);
     }
@@ -134,7 +145,26 @@
 }
 
 void
+<<<<<<< .working
 AuthSrvTest::createRequestPacket(Message& message,
+=======
+AuthSrvTest::createRequestMessage(const Opcode& opcode,
+                                  const Name& request_name,
+                                  const RRClass& rrclass,
+                                  const RRType& rrtype)
+{
+    request_message.clear(Message::RENDER);
+    request_message.setOpcode(opcode);
+    request_message.setRcode(Rcode::NOERROR());
+    request_message.setQid(default_qid);
+    request_message.addQuestion(Question(request_name, rrclass, rrtype));
+}
+
+void
+AuthSrvTest::createRequestPacket(const Opcode& opcode,
+                                 const Name& request_name,
+                                 const RRClass& rrclass, const RRType& rrtype,
+>>>>>>> .merge-right.r3495
                                  const int protocol = IPPROTO_UDP)
 {
     message.toWire(request_renderer);
@@ -160,18 +190,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.
@@ -183,14 +220,21 @@
             i == Opcode::NOTIFY().getCode()) {
             continue;
         }
-        createDataFromFile("simplequery_fromWire");
+        createDataFromFile("simplequery_fromWire.wire");
         data[2] = ((i << 3) & 0xff);
 
+<<<<<<< .working
         parse_message->clear(Message::PARSE);
         server.processMessage(*io_message, parse_message, response_obuffer,
                               &dnsserv);
         EXPECT_TRUE(dnsserv.hasAnswer());
         headerCheck(*parse_message, default_qid, Rcode::NOTIMP(), i, QR_FLAG,
+=======
+        parse_message.clear(Message::PARSE);
+        EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                          response_renderer));
+        headerCheck(parse_message, default_qid, Rcode::NOTIMP(), i, QR_FLAG,
+>>>>>>> .merge-right.r3495
                     0, 0, 0, 0);
     }
 }
@@ -206,10 +250,17 @@
 
 // Multiple questions.  Should result in FORMERR.
 TEST_F(AuthSrvTest, multiQuestion) {
+<<<<<<< .working
     createDataFromFile("multiquestion_fromWire");
     server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
     EXPECT_TRUE(dnsserv.hasAnswer());
     headerCheck(*parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
+=======
+    createDataFromFile("multiquestion_fromWire.wire");
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
+    headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
+>>>>>>> .merge-right.r3495
                 QR_FLAG, 2, 0, 0, 0);
 
     QuestionIterator qit = parse_message->beginQuestion();
@@ -228,35 +279,62 @@
 // dropped.
 TEST_F(AuthSrvTest, shortMessage) {
     createDataFromFile("shortmessage_fromWire");
-    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
-    EXPECT_FALSE(dnsserv.hasAnswer());
+<<<<<<< .working
+    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+    EXPECT_FALSE(dnsserv.hasAnswer());
+=======
+    EXPECT_FALSE(server.processMessage(*io_message, parse_message,
+                                       response_renderer));
+>>>>>>> .merge-right.r3495
 }
 
 // Response messages.  Must be silently dropped, whether it's a valid response
 // or malformed or could otherwise cause a protocol error.
 TEST_F(AuthSrvTest, response) {
     // A valid (although unusual) response
+<<<<<<< .working
     createDataFromFile("simpleresponse_fromWire");
     server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
     EXPECT_FALSE(dnsserv.hasAnswer());
+=======
+    createDataFromFile("simpleresponse_fromWire.wire");
+    EXPECT_FALSE(server.processMessage(*io_message, parse_message,
+                                       response_renderer));
+>>>>>>> .merge-right.r3495
 
     // A response with a broken question section.  must be dropped rather than
     // returning FORMERR.
     createDataFromFile("shortresponse_fromWire");
-    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
-    EXPECT_FALSE(dnsserv.hasAnswer());
+<<<<<<< .working
+    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+    EXPECT_FALSE(dnsserv.hasAnswer());
+=======
+    EXPECT_FALSE(server.processMessage(*io_message, parse_message,
+                                       response_renderer));
+>>>>>>> .merge-right.r3495
 
     // A response to iquery.  must be dropped rather than returning NOTIMP.
+<<<<<<< .working
     createDataFromFile("iqueryresponse_fromWire");
     server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
     EXPECT_FALSE(dnsserv.hasAnswer());
+=======
+    createDataFromFile("iqueryresponse_fromWire.wire");
+    EXPECT_FALSE(server.processMessage(*io_message, parse_message,
+                                       response_renderer));
+>>>>>>> .merge-right.r3495
 }
 
 // Query with a broken question
 TEST_F(AuthSrvTest, shortQuestion) {
     createDataFromFile("shortquestion_fromWire");
-    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
-    EXPECT_TRUE(dnsserv.hasAnswer());
+<<<<<<< .working
+    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+    EXPECT_TRUE(dnsserv.hasAnswer());
+=======
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
+>>>>>>> .merge-right.r3495
     // 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(),
@@ -265,9 +343,15 @@
 
 // Query with a broken answer section
 TEST_F(AuthSrvTest, shortAnswer) {
+<<<<<<< .working
     createDataFromFile("shortanswer_fromWire");
     server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
     EXPECT_TRUE(dnsserv.hasAnswer());
+=======
+    createDataFromFile("shortanswer_fromWire.wire");
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
+>>>>>>> .merge-right.r3495
 
     // This is a bogus query, but question section is valid.  So the response
     // should copy the question section.
@@ -284,21 +368,40 @@
 
 // Query with unsupported version of EDNS.
 TEST_F(AuthSrvTest, ednsBadVers) {
+<<<<<<< .working
     createDataFromFile("queryBadEDNS_fromWire");
     server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
     EXPECT_TRUE(dnsserv.hasAnswer());
-
-    // The response must have an EDNS OPT RR in the additional section.
+=======
+    createDataFromFile("queryBadEDNS_fromWire.wire");
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
+>>>>>>> .merge-right.r3495
+
+    // The response must have an EDNS OPT RR in the additional section, but
+    // it will be added automatically at the render time.
     // Note that the DNSSEC DO bit is cleared even if this bit in the query
     // is set.  This is a limitation of the current implementation.
     headerCheck(*parse_message, default_qid, Rcode::BADVERS(), opcode.getCode(),
                 QR_FLAG, 1, 0, 0, 1);
+<<<<<<< .working
     EXPECT_EQ(4096, parse_message->getUDPSize());
     EXPECT_FALSE(parse_message->isDNSSECSupported());
+=======
+    EXPECT_FALSE(parse_message.getEDNS()); // EDNS isn't added at this point
+
+    parse_message.clear(Message::PARSE);
+    InputBuffer ib(response_renderer.getData(), response_renderer.getLength());
+    parse_message.fromWire(ib);
+    EXPECT_EQ(Rcode::BADVERS(), parse_message.getRcode());
+    EXPECT_TRUE(parse_message.getEDNS());
+    EXPECT_FALSE(parse_message.getEDNS()->getDNSSECAwareness());
+>>>>>>> .merge-right.r3495
 }
 
 TEST_F(AuthSrvTest, AXFROverUDP) {
     // AXFR over UDP is invalid and should result in FORMERR.
+<<<<<<< .working
     UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
                          Name("example.com"), RRClass::IN(),
                          RRType::AXFR());
@@ -306,6 +409,13 @@
     server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
     EXPECT_TRUE(dnsserv.hasAnswer());
     headerCheck(*parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
+=======
+    createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
+                        RRType::AXFR(), IPPROTO_UDP);
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
+    headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
+>>>>>>> .merge-right.r3495
                 QR_FLAG, 1, 0, 0, 0);
 }
 
@@ -316,9 +426,15 @@
     createRequestPacket(request_message, IPPROTO_TCP);
     // On success, the AXFR query has been passed to a separate process,
     // so we shouldn't have to respond.
+<<<<<<< .working
     server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
     EXPECT_FALSE(dnsserv.hasAnswer());
     EXPECT_FALSE(xfrout.isConnected());
+=======
+    EXPECT_FALSE(server.processMessage(*io_message, parse_message,
+                                       response_renderer));
+    EXPECT_TRUE(xfrout.isConnected());
+>>>>>>> .merge-right.r3495
 }
 
 TEST_F(AuthSrvTest, AXFRConnectFail) {
@@ -331,8 +447,6 @@
     EXPECT_TRUE(dnsserv.hasAnswer());
     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());
 }
 
@@ -343,7 +457,7 @@
                          Name("example.com"), RRClass::IN(), RRType::AXFR());
     createRequestPacket(request_message, IPPROTO_TCP);
     server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
-    EXPECT_FALSE(xfrout.isConnected()); // see above
+    EXPECT_TRUE(xfrout.isConnected());
 
     xfrout.disableSend();
     parse_message->clear(Message::PARSE);
@@ -380,10 +494,16 @@
 TEST_F(AuthSrvTest, notify) {
     UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
                          Name("example.com"), RRClass::IN(), RRType::SOA());
-    request_message.setHeaderFlag(MessageFlag::AA());
-    createRequestPacket(request_message, IPPROTO_UDP);
-    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
-    EXPECT_TRUE(dnsserv.hasAnswer());
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
+<<<<<<< .working
+    createRequestPacket(request_message, IPPROTO_UDP);
+    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+    EXPECT_TRUE(dnsserv.hasAnswer());
+=======
+    createRequestPacket(IPPROTO_UDP);
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
+>>>>>>> .merge-right.r3495
 
     // An internal command message should have been created and sent to an
     // external module.  Check them.
@@ -412,10 +532,16 @@
     // Same as the previous test, but for the CH RRClass.
     UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
                          Name("example.com"), RRClass::CH(), RRType::SOA());
-    request_message.setHeaderFlag(MessageFlag::AA());
-    createRequestPacket(request_message, IPPROTO_UDP);
-    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
-    EXPECT_TRUE(dnsserv.hasAnswer());
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
+<<<<<<< .working
+    createRequestPacket(request_message, IPPROTO_UDP);
+    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+    EXPECT_TRUE(dnsserv.hasAnswer());
+=======
+    createRequestPacket(IPPROTO_UDP);
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
+>>>>>>> .merge-right.r3495
 
     // Other conditions should be the same, so simply confirm the RR class is
     // set correctly.
@@ -427,13 +553,21 @@
 TEST_F(AuthSrvTest, notifyEmptyQuestion) {
     request_message.clear(Message::RENDER);
     request_message.setOpcode(Opcode::NOTIFY());
-    request_message.setHeaderFlag(MessageFlag::AA());
+    request_message.setRcode(Rcode::NOERROR());
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
     request_message.setQid(default_qid);
     request_message.toWire(request_renderer);
+<<<<<<< .working
     createRequestPacket(request_message, IPPROTO_UDP);
     server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
     EXPECT_TRUE(dnsserv.hasAnswer());
     headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
+=======
+    createRequestPacket(IPPROTO_UDP);
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
+    headerCheck(parse_message, default_qid, Rcode::FORMERR(),
+>>>>>>> .merge-right.r3495
                 Opcode::NOTIFY().getCode(), QR_FLAG, 0, 0, 0, 0);
 }
 
@@ -443,45 +577,74 @@
     // add one more SOA question
     request_message.addQuestion(Question(Name("example.com"), RRClass::IN(),
                                          RRType::SOA()));
-    request_message.setHeaderFlag(MessageFlag::AA());
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
+<<<<<<< .working
     createRequestPacket(request_message, IPPROTO_UDP);
     server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
     EXPECT_TRUE(dnsserv.hasAnswer());
     headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
+=======
+    createRequestPacket(IPPROTO_UDP);
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
+    headerCheck(parse_message, default_qid, Rcode::FORMERR(),
+>>>>>>> .merge-right.r3495
                 Opcode::NOTIFY().getCode(), QR_FLAG, 2, 0, 0, 0);
 }
 
 TEST_F(AuthSrvTest, notifyNonSOAQuestion) {
     UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
                          Name("example.com"), RRClass::IN(), RRType::NS());
-    request_message.setHeaderFlag(MessageFlag::AA());
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
+<<<<<<< .working
     createRequestPacket(request_message, IPPROTO_UDP);
     server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
     EXPECT_TRUE(dnsserv.hasAnswer());
     headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
+=======
+    createRequestPacket(IPPROTO_UDP);
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
+    headerCheck(parse_message, default_qid, Rcode::FORMERR(),
+>>>>>>> .merge-right.r3495
                 Opcode::NOTIFY().getCode(), QR_FLAG, 1, 0, 0, 0);
 }
 
 TEST_F(AuthSrvTest, notifyWithoutAA) {
     // implicitly leave the AA bit off.  our implementation will accept it.
+<<<<<<< .working
     UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
                          Name("example.com"), RRClass::IN(), RRType::SOA());
     createRequestPacket(request_message, IPPROTO_UDP);
     server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
     EXPECT_TRUE(dnsserv.hasAnswer());
     headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
+=======
+    createRequestPacket(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
+                        RRType::SOA());
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
+    headerCheck(parse_message, default_qid, Rcode::NOERROR(),
+>>>>>>> .merge-right.r3495
                 Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
 }
 
 TEST_F(AuthSrvTest, notifyWithErrorRcode) {
     UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
                          Name("example.com"), RRClass::IN(), RRType::SOA());
-    request_message.setHeaderFlag(MessageFlag::AA());
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
     request_message.setRcode(Rcode::SERVFAIL());
+<<<<<<< .working
     createRequestPacket(request_message, IPPROTO_UDP);
     server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
     EXPECT_TRUE(dnsserv.hasAnswer());
     headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
+=======
+    createRequestPacket(IPPROTO_UDP);
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
+    headerCheck(parse_message, default_qid, Rcode::NOERROR(),
+>>>>>>> .merge-right.r3495
                 Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
 }
 
@@ -490,7 +653,7 @@
 
     UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
                          Name("example.com"), RRClass::IN(), RRType::SOA());
-    request_message.setHeaderFlag(MessageFlag::AA());
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
     createRequestPacket(request_message, IPPROTO_UDP);
 
     // we simply ignore the notify and let it be resent if an internal error
@@ -504,7 +667,7 @@
 
     UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
                          Name("example.com"), RRClass::IN(), RRType::SOA());
-    request_message.setHeaderFlag(MessageFlag::AA());
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
     createRequestPacket(request_message, IPPROTO_UDP);
 
     server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
@@ -516,7 +679,7 @@
 
     UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
                          Name("example.com"), RRClass::IN(), RRType::SOA());
-    request_message.setHeaderFlag(MessageFlag::AA());
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
     createRequestPacket(request_message, IPPROTO_UDP);
     server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
     EXPECT_FALSE(dnsserv.hasAnswer());
@@ -527,7 +690,7 @@
 
     UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
                          Name("example.com"), RRClass::IN(), RRType::SOA());
-    request_message.setHeaderFlag(MessageFlag::AA());
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
     createRequestPacket(request_message, IPPROTO_UDP);
     server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
     EXPECT_FALSE(dnsserv.hasAnswer());
@@ -539,7 +702,7 @@
 
     UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
                          Name("example.com"), RRClass::IN(), RRType::SOA());
-    request_message.setHeaderFlag(MessageFlag::AA());
+    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
     createRequestPacket(request_message, IPPROTO_UDP);
     server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
     EXPECT_FALSE(dnsserv.hasAnswer());
@@ -566,10 +729,17 @@
     // query for existent data in the installed data source.  The resulting
     // response should have the AA flag on, and have an RR in each answer
     // and authority section.
+<<<<<<< .working
     createDataFromFile("examplequery_fromWire");
     server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
     EXPECT_TRUE(dnsserv.hasAnswer());
     headerCheck(*parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
+=======
+    createDataFromFile("examplequery_fromWire.wire");
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
+    headerCheck(parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
+>>>>>>> .merge-right.r3495
                 QR_FLAG | AA_FLAG, 1, 1, 1, 0);
 }
 
@@ -580,10 +750,17 @@
     // tool and the data source itself naively accept it).  This will result
     // in a SERVFAIL response, and the answer and authority sections should
     // be empty.
+<<<<<<< .working
     createDataFromFile("badExampleQuery_fromWire");
     server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
     EXPECT_TRUE(dnsserv.hasAnswer());
     headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
+=======
+    createDataFromFile("badExampleQuery_fromWire.wire");
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
+    headerCheck(parse_message, default_qid, Rcode::SERVFAIL(),
+>>>>>>> .merge-right.r3495
                 opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
 }
 
@@ -595,10 +772,27 @@
     updateConfig(&server, BADCONFIG_TESTDB, false);
 
     // The original data source should still exist.
+<<<<<<< .working
     createDataFromFile("examplequery_fromWire");
     server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
     EXPECT_TRUE(dnsserv.hasAnswer());
     headerCheck(*parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
+=======
+    createDataFromFile("examplequery_fromWire.wire");
+    EXPECT_TRUE(server.processMessage(*io_message, parse_message,
+                                      response_renderer));
+    headerCheck(parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
+>>>>>>> .merge-right.r3495
                 QR_FLAG | AA_FLAG, 1, 1, 1, 0);
 }
-}
+
+TEST_F(AuthSrvTest, cacheSlots) {
+    // simple check for the get/set operations
+    server.setCacheSlots(10);    // 10 = arbitrary choice
+    EXPECT_EQ(10, server.getCacheSlots());
+
+    // 0 is a valid size
+    server.setCacheSlots(0);
+    EXPECT_EQ(00, server.getCacheSlots());
+}
+}

Modified: experiments/327-sync/src/bin/auth/tests/run_unittests.cc
==============================================================================
--- experiments/327-sync/src/bin/auth/tests/run_unittests.cc (original)
+++ experiments/327-sync/src/bin/auth/tests/run_unittests.cc Tue Nov  9 10:38:17 2010
@@ -19,10 +19,10 @@
 #include <dns/tests/unittest_util.h>
 
 int
-main(int argc, char* argv[])
-{
+main(int argc, char* argv[]) {
     ::testing::InitGoogleTest(&argc, argv);
     isc::UnitTestUtil::addDataPath(TEST_DATA_DIR);
+    isc::UnitTestUtil::addDataPath(TEST_DATA_BUILDDIR);
 
     return (RUN_ALL_TESTS());
 }

Modified: experiments/327-sync/src/bin/bind10/Makefile.am
==============================================================================
--- experiments/327-sync/src/bin/bind10/Makefile.am (original)
+++ experiments/327-sync/src/bin/bind10/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 sbin_SCRIPTS = bind10
 CLEANFILES = bind10 bind10.pyc

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

Modified: experiments/327-sync/src/bin/bind10/bind10.py.in
==============================================================================
--- experiments/327-sync/src/bin/bind10/bind10.py.in (original)
+++ experiments/327-sync/src/bin/bind10/bind10.py.in Tue Nov  9 10:38:17 2010
@@ -63,9 +63,19 @@
 import posix
 
 import isc.cc
+import isc.util.process
+import isc.net.parse
+
+# Assign this process some longer name
+isc.util.process.rename(sys.argv[0])
 
 # This is the version that gets displayed to the user.
-__version__ = "v20100531"
+# The VERSION string consists of the module name, the module version
+# number, and the overall BIND 10 version number (set in configure.ac).
+VERSION = "bind10 20100916 (BIND 10 @PACKAGE_VERSION@)"
+
+# This is for bind10.boottime of stats module
+_BASETIME = time.gmtime()
 
 class RestartSchedule:
     """
@@ -131,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)
@@ -167,44 +182,24 @@
                                         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 IPAddr:
-    """Stores an IPv4 or IPv6 address."""
-    family = None
-    addr = None
-
-    def __init__(self, addr):
-        try:
-            a = socket.inet_pton(socket.AF_INET, addr)
-            self.family = socket.AF_INET
-            self.addr = a
-            return
-        except:
-            pass
-
-        try:
-            a = socket.inet_pton(socket.AF_INET6, addr)
-            self.family = socket.AF_INET6
-            self.addr = a
-            return
-        except Exception as e:
-            raise e
-    
-    def __str__(self):
-        return socket.inet_ntop(self.family, self.addr)
 
 class BoB:
     """Boss of BIND class."""
     
+<<<<<<< .working
     def __init__(self, msgq_socket_file=None, dns_port=5300, address='',
                  forward=None, nocache=False, verbose=False, setuid=None,
                  username=None):
+=======
+    def __init__(self, msgq_socket_file=None, auth_port=5300, address=None,
+                 nocache=False, verbose=False, setuid=None, username=None):
+>>>>>>> .merge-right.r3495
         """Initialize the Boss of BIND. This is a singleton (only one
         can run).
         
@@ -218,7 +213,7 @@
         self.address = None
         self.nocache = nocache
         if address:
-            self.address = IPAddr(address)
+            self.address = address
         self.forward = None
         self.recursive = False
         if forward:
@@ -443,6 +438,27 @@
                 sys.stdout.write("[bind10] Started b10-zonemgr(PID %d)\n" % 
                                  zonemgr.pid)
 
+        # start b10-stats
+        stats_args = ['b10-stats']
+        if self.verbose:
+            sys.stdout.write("[bind10] Starting b10-stats\n")
+            stats_args += ['-v']
+        try:
+            statsd = ProcessInfo("b10-stats", stats_args,
+                                 c_channel_env)
+        except Exception as e:
+            c_channel.process.kill()
+            bind_cfgd.process.kill()
+            xfrout.process.kill()
+            auth.process.kill()
+            xfrind.process.kill()
+            zonemgr.process.kill()
+            return "Unable to start b10-stats; " + str(e)
+
+        self.processes[statsd.pid] = statsd
+        if self.verbose:
+            sys.stdout.write("[bind10] Started b10-stats (PID %d)\n" % statsd.pid)
+
         # start the b10-cmdctl
         # XXX: we hardcode port 8080
         cmdctl_args = ['b10-cmdctl']
@@ -462,6 +478,7 @@
                 xfrind.process.kill()
             if zonemgr:
                 zonemgr.process.kill()
+            statsd.process.kill()
             return "Unable to start b10-cmdctl; " + str(e)
         self.processes[cmd_ctrld.pid] = cmd_ctrld
         if self.verbose:
@@ -475,6 +492,7 @@
     def stop_all_processes(self):
         """Stop all processes."""
         cmd = { "command": ['shutdown']}
+<<<<<<< .working
         self.cc_session.group_sendmsg(cmd, 'Boss', 'Cmdctl')
         self.cc_session.group_sendmsg(cmd, "Boss", "ConfigManager")
         self.cc_session.group_sendmsg(cmd, "Boss", "Auth")
@@ -482,6 +500,15 @@
         self.cc_session.group_sendmsg(cmd, "Boss", "Xfrout")
         self.cc_session.group_sendmsg(cmd, "Boss", "Xfrin")
         self.cc_session.group_sendmsg(cmd, "Boss", "Zonemgr")
+=======
+        self.cc_session.group_sendmsg(cmd, 'Cmdctl', 'Cmdctl')
+        self.cc_session.group_sendmsg(cmd, "ConfigManager", "ConfigManager")
+        self.cc_session.group_sendmsg(cmd, "Auth", "Auth")
+        self.cc_session.group_sendmsg(cmd, "Xfrout", "Xfrout")
+        self.cc_session.group_sendmsg(cmd, "Xfrin", "Xfrin")
+        self.cc_session.group_sendmsg(cmd, "Zonemgr", "Zonemgr")
+        self.cc_session.group_sendmsg(cmd, "Boss", "Stats")
+>>>>>>> .merge-right.r3495
 
     def stop_process(self, process):
         """Stop the given process, friendly-like."""
@@ -498,7 +525,9 @@
         except:
             pass
         # XXX: some delay probably useful... how much is uncertain
-        time.sleep(0.5)  
+        # I have changed the delay from 0.5 to 1, but sometime it's 
+        # still not enough.
+        time.sleep(1)  
         self.reap_children()
         # next try sending a SIGTERM
         processes_to_stop = list(self.processes.values())
@@ -605,7 +634,7 @@
     # the Python signal handler has been set up to write
     # down a pipe, waking up our select() bit
     pass
-                   
+
 def get_signame(signal_number):
     """Return the symbolic name for a signal."""
     for sig in dir(signal):
@@ -627,6 +656,7 @@
 def check_port(option, opt_str, value, parser):
     """Function to insure that the port we are passed is actually 
     a valid port number. Used by OptionParser() on startup."""
+<<<<<<< .working
     if not re.match('^(6553[0-5]|655[0-2]\d|65[0-4]\d\d|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3}|0)$', value):
         raise OptionValueError("%s requires a port number (0-65535)" % opt_str)
     if (opt_str == '-m' or opt_str == '--msgq-port'):
@@ -636,13 +666,27 @@
     else:
         raise OptionValueError("Unknown option " + opt_str)
   
+=======
+    try:
+        if opt_str in ['-p', '--port']:
+            parser.values.auth_port = isc.net.parse.port_parse(value)
+        else:
+            raise OptionValueError("Unknown option " + opt_str)
+    except ValueError as e:
+        raise OptionValueError(str(e))
+
+>>>>>>> .merge-right.r3495
 def check_addr(option, opt_str, value, parser):
     """Function to insure that the address we are passed is actually 
     a valid address. Used by OptionParser() on startup."""
     try:
-        IPAddr(value)
-    except:
+        if opt_str in ['-a', '--address']:
+            parser.values.address = isc.net.parse.addr_parse(value)
+        else:
+            raise OptionValueError("Unknown option " + opt_str)
+    except ValueError:
         raise OptionValueError("%s requires a valid IPv4 or IPv6 address" % opt_str)
+<<<<<<< .working
     if (opt_str == '-a' or opt_str == '--address'):
         parser.values.address = value
     elif (opt_str == '-f' or opt_str == '--forward'):
@@ -650,6 +694,13 @@
     else:
         raise OptionValueError("Unknown option " + opt_str)
   
+=======
+
+def process_rename(option, opt_str, value, parser):
+    """Function that renames the process if it is requested by a option."""
+    isc.util.process.rename(value)
+
+>>>>>>> .merge-right.r3495
 def main():
     global options
     global boss_of_bind
@@ -657,7 +708,7 @@
     sys.stdout = io.TextIOWrapper(sys.stdout.detach(), line_buffering=True)
 
     # Parse any command-line options.
-    parser = OptionParser(version=__version__)
+    parser = OptionParser(version=VERSION)
     parser.add_option("-a", "--address", dest="address", type="string",
                       action="callback", callback=check_addr, default='',
                       help="address the DNS server will use (default: listen on all addresses)")
@@ -668,14 +719,23 @@
                       type="string", default=None,
                       help="UNIX domain socket file the b10-msgq daemon will use")
     parser.add_option("-n", "--no-cache", action="store_true", dest="nocache",
+<<<<<<< .working
                       default=False, help="disable hot-spot cache in authoritative DNS server")
     parser.add_option("-p", "--port", dest="dns_port", type="string",
                       action="callback", callback=check_port, default="5300",
+=======
+                      default=False, help="disable hot-spot cache in b10-auth")
+    parser.add_option("-p", "--port", dest="auth_port", type="int",
+                      action="callback", callback=check_port, default=5300,
+>>>>>>> .merge-right.r3495
                       help="port the DNS server will use (default 5300)")
     parser.add_option("-u", "--user", dest="user", type="string", default=None,
                       help="Change user after startup (must run as root)")
     parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
                       help="display more about what is going on")
+    parser.add_option("--pretty-name", type="string", action="callback",
+                      callback=process_rename,
+                      help="Set the process name (displayed in ps, top, ...)")
     (options, args) = parser.parse_args()
     if args:
         parser.print_help()
@@ -712,7 +772,7 @@
 
     # Announce startup.
     if options.verbose:
-        sys.stdout.write("BIND 10 %s\n" % __version__)
+        sys.stdout.write("%s\n" % VERSION)
 
     # TODO: set process name, perhaps by:
     #       http://code.google.com/p/procname/
@@ -729,15 +789,35 @@
     signal.signal(signal.SIGINT, fatal_signal)
     signal.signal(signal.SIGTERM, fatal_signal)
 
+    # Block SIGPIPE, as we don't want it to end this process
+    signal.signal(signal.SIGPIPE, signal.SIG_IGN)
+
     # Go bob!
+<<<<<<< .working
     boss_of_bind = BoB(options.msgq_socket_file, int(options.dns_port),
                        options.address, options.forward, options.nocache,
                        options.verbose, setuid, username)
+=======
+    boss_of_bind = BoB(options.msgq_socket_file, options.auth_port,
+                       options.address, options.nocache, options.verbose,
+                       setuid, username)
+>>>>>>> .merge-right.r3495
     startup_result = boss_of_bind.startup()
     if startup_result:
         sys.stderr.write("[bind10] Error on startup: %s\n" % startup_result)
         sys.exit(1)
     sys.stdout.write("[bind10] BIND 10 started\n")
+
+    # send "bind10.boot_time" to b10-stats
+    time.sleep(1) # wait a second
+    if options.verbose:
+        sys.stdout.write("[bind10] send \"bind10.boot_time\" to b10-stats\n")
+    cmd = isc.config.ccsession.create_command('set', 
+            { "stats_data": {
+              'bind10.boot_time': time.strftime('%Y-%m-%dT%H:%M:%SZ', _BASETIME)
+              }
+            })
+    boss_of_bind.cc_session.group_sendmsg(cmd, 'Stats')
 
     # In our main loop, we check for dead processes or messages 
     # on the c-channel.
@@ -767,7 +847,12 @@
 
         for fd in rlist + xlist:
             if fd == ccs_fd:
-                boss_of_bind.ccs.check_command()
+                try:
+                    boss_of_bind.ccs.check_command()
+                except isc.cc.session.ProtocolError:
+                    if options.verbose:
+                        sys.stderr.write("[bind10] msgq channel disappeared.\n")
+                    break
             elif fd == wakeup_fd:
                 os.read(wakeup_fd, 32)
 

Modified: experiments/327-sync/src/bin/bind10/bind10.xml
==============================================================================
--- experiments/327-sync/src/bin/bind10/bind10.xml (original)
+++ experiments/327-sync/src/bin/bind10/bind10.xml Tue Nov  9 10:38:17 2010
@@ -56,6 +56,7 @@
       <arg><option>--no-cache</option></arg>
       <arg><option>--port <replaceable>number</replaceable></option></arg>
       <arg><option>--user <replaceable>user</replaceable></option></arg>
+      <arg><option>--pretty-name <replaceable>name</replaceable></option></arg>
       <arg><option>--verbose</option></arg>
     </cmdsynopsis>
   </refsynopsisdiv>
@@ -149,6 +150,17 @@
       </varlistentry>
 
       <varlistentry>
+        <term><option>--pretty-name <replaceable>name</replaceable></option></term>
+
+        <listitem>
+          <para>The name this process should have in tools like
+          <command>ps</command> or <command>top</command>. This
+          is handy if you have multiple versions/installations
+          of <command>bind10</command>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><option>-v</option>, <option>--verbose</option></term>
         <listitem>
 	  <para>Display more about what is going on for
@@ -188,6 +200,12 @@
       </citerefentry>,
       <citerefentry>
         <refentrytitle>b10-xfrin</refentrytitle><manvolnum>8</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>b10-xfrout</refentrytitle><manvolnum>8</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>b10-zonemgr</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
       <citetitle>BIND 10 Guide</citetitle>.
     </para>

Modified: experiments/327-sync/src/bin/bind10/run_bind10.sh.in
==============================================================================
--- experiments/327-sync/src/bin/bind10/run_bind10.sh.in (original)
+++ experiments/327-sync/src/bin/bind10/run_bind10.sh.in Tue Nov  9 10:38:17 2010
@@ -20,7 +20,11 @@
 
 BIND10_PATH=@abs_top_builddir@/src/bin/bind10
 
+<<<<<<< .working
 PATH=@abs_top_builddir@/src/bin/msgq:@abs_top_builddir@/src/bin/auth:@abs_top_builddir@/src/bin/recurse:@abs_top_builddir@/src/bin/cfgmgr:@abs_top_builddir@/src/bin/cmdctl:@abs_top_builddir@/src/bin/xfrin:@abs_top_builddir@/src/bin/xfrout:@abs_top_builddir@/src/bin/zonemgr:$PATH
+=======
+PATH=@abs_top_builddir@/src/bin/msgq:@abs_top_builddir@/src/bin/auth:@abs_top_builddir@/src/bin/cfgmgr:@abs_top_builddir@/src/bin/cmdctl:@abs_top_builddir@/src/bin/stats:@abs_top_builddir@/src/bin/xfrin:@abs_top_builddir@/src/bin/xfrout:@abs_top_builddir@/src/bin/zonemgr:$PATH
+>>>>>>> .merge-right.r3495
 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: experiments/327-sync/src/bin/bind10/tests/args_test.py
==============================================================================
--- experiments/327-sync/src/bin/bind10/tests/args_test.py (original)
+++ experiments/327-sync/src/bin/bind10/tests/args_test.py Tue Nov  9 10:38:17 2010
@@ -130,5 +130,28 @@
         x = bob.wait()
         self.assertTrue(bob.wait() == 0)
 
+    def testPrettyName(self):
+        """Try the --pretty-name option."""
+        CMD_PRETTY_NAME = b'bob-name-test'
+        bob = subprocess.Popen(args=(BIND10_EXE, '--pretty-name',
+            CMD_PRETTY_NAME), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+        started_ok = self._waitForString(bob, '[bind10] BIND 10 started')
+        self.assertTrue(started_ok)
+        ps = subprocess.Popen(args=("ps", "axo", "pid,comm"),
+                              stdout=subprocess.PIPE)
+        s = ps.stdout.readline()
+        command = None
+        while True:
+            s = ps.stdout.readline()
+            if s == '': break
+            (pid,comm) = s.split(None, 1)
+            if int(pid) == bob.pid:
+                command = comm
+                break
+        self.assertEqual(command, CMD_PRETTY_NAME + b'\n')
+        time.sleep(0.1)
+        bob.terminate()
+        bob.wait()
+
 if __name__ == '__main__':
     unittest.main()

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

Modified: experiments/327-sync/src/bin/bindctl/Makefile.am
==============================================================================
--- experiments/327-sync/src/bin/bindctl/Makefile.am (original)
+++ experiments/327-sync/src/bin/bindctl/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 bin_SCRIPTS = bindctl
 man_MANS = bindctl.1

Modified: experiments/327-sync/src/bin/bindctl/bindctl-source.py.in
==============================================================================
--- experiments/327-sync/src/bin/bindctl/bindctl-source.py.in (original)
+++ experiments/327-sync/src/bin/bindctl/bindctl-source.py.in Tue Nov  9 10:38:17 2010
@@ -24,6 +24,9 @@
 from bindctl.bindcmd import *
 import pprint
 from optparse import OptionParser, OptionValueError
+import isc.util.process
+
+isc.util.process.rename()
 
 __version__ = 'Bindctl'
 

Modified: experiments/327-sync/src/bin/cfgmgr/Makefile.am
==============================================================================
--- experiments/327-sync/src/bin/cfgmgr/Makefile.am (original)
+++ experiments/327-sync/src/bin/cfgmgr/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 pkglibexecdir = $(libexecdir)/@PACKAGE@
 

Modified: experiments/327-sync/src/bin/cfgmgr/b10-cfgmgr.py.in
==============================================================================
--- experiments/327-sync/src/bin/cfgmgr/b10-cfgmgr.py.in (original)
+++ experiments/327-sync/src/bin/cfgmgr/b10-cfgmgr.py.in Tue Nov  9 10:38:17 2010
@@ -21,8 +21,11 @@
 
 from isc.config.cfgmgr import ConfigManager, ConfigManagerDataReadError
 from isc.cc import SessionError
+import isc.util.process
 import signal
 import os
+
+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: experiments/327-sync/src/bin/cmdctl/Makefile.am
==============================================================================
--- experiments/327-sync/src/bin/cmdctl/Makefile.am (original)
+++ experiments/327-sync/src/bin/cmdctl/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 pkglibexecdir = $(libexecdir)/@PACKAGE@
 
@@ -15,7 +15,7 @@
 
 b10_cmdctl_DATA = $(CMDCTL_CONFIGURATIONS)
 b10_cmdctl_DATA += cmdctl.spec
- 
+
 EXTRA_DIST = $(CMDCTL_CONFIGURATIONS)
 
 CLEANFILES=	b10-cmdctl cmdctl.pyc cmdctl.spec

Modified: experiments/327-sync/src/bin/cmdctl/cmdctl.py.in
==============================================================================
--- experiments/327-sync/src/bin/cmdctl/cmdctl.py.in (original)
+++ experiments/327-sync/src/bin/cmdctl/cmdctl.py.in Tue Nov  9 10:38:17 2010
@@ -1,6 +1,7 @@
 #!@PYTHON@
 
 # Copyright (C) 2010  Internet Systems Consortium.
+# Copyright (C) 2010  CZ NIC
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -42,12 +43,18 @@
 import time
 import signal
 from isc.config import ccsession
+import isc.util.process
+import isc.net.parse
 from optparse import OptionParser, OptionValueError
 from hashlib import sha1
+from isc.util import socketserver_mixin
+
 try:
     import threading
 except ImportError:
     import dummy_threading as threading
+
+isc.util.process.rename()
 
 __version__ = 'BIND10'
 URL_PATTERN = re.compile('/([\w]+)(?:/([\w]+))?/?')
@@ -320,8 +327,8 @@
     def _handle_msg_from_msgq(self):
         '''Process all the received commands with module session. '''
         while self._serving:
-            self._module_cc.check_command() 
- 
+            self._module_cc.check_command(False)
+
     def _parse_command_result(self, rcode, reply):
         '''Ignore the error reason when command rcode isn't 0, '''
         if rcode != 0:
@@ -380,6 +387,7 @@
     def send_command(self, module_name, command_name, params = None):
         '''Send the command from bindctl to proper module. '''
         errstr = 'unknown error'
+        answer = None
         if self._verbose:
             self.log_info("Begin send command '%s' to module '%s'" %(command_name, module_name))
 
@@ -390,7 +398,10 @@
             msg = ccsession.create_command(command_name, params)
             seq = self._cc.group_sendmsg(msg, module_name)
             #TODO, it may be blocked, msqg need to add a new interface waiting in timeout.
-            answer, env = self._cc.group_recvmsg(False, seq)
+            try:
+                answer, env = self._cc.group_recvmsg(False, seq)
+            except isc.cc.session.SessionTimeout:
+                errstr = "Module '%s' not responding" % module_name
 
         if self._verbose:
             self.log_info("Finish send command '%s' to module '%s'" % (command_name, module_name))
@@ -410,7 +421,6 @@
             except ccsession.ModuleCCSessionError as mcse:
                 errstr = str("Error in ccsession answer:") + str(mcse)
                 self.log_info(errstr)
-        
         return 1, {'error': errstr}
     
     def log_info(self, msg):
@@ -433,7 +443,9 @@
 
         return (keyfile, certfile, accountsfile)
 
-class SecureHTTPServer(socketserver.ThreadingMixIn, http.server.HTTPServer):
+class SecureHTTPServer(socketserver_mixin.NoPollMixIn,
+                       socketserver.ThreadingMixIn,
+                       http.server.HTTPServer):
     '''Make the server address can be reused.'''
     allow_reuse_address = True
 
@@ -441,6 +453,7 @@
                  CommandControlClass,
                  idle_timeout = 1200, verbose = False):
         '''idle_timeout: the max idle time for login'''
+        socketserver_mixin.NoPollMixIn.__init__(self)
         try:
             http.server.HTTPServer.__init__(self, server_address, RequestHandlerClass)
         except socket.error as err:
@@ -558,22 +571,17 @@
     httpd.serve_forever()
 
 def check_port(option, opt_str, value, parser):
-    if (value < 0) or (value > 65535):
-        raise OptionValueError('%s requires a port number (0-65535)' % opt_str)
-    parser.values.port = value
+    try:
+        parser.values.port = isc.net.parse.port_parse(value)
+    except ValueError as e:
+        raise OptionValueError(str(e))
 
 def check_addr(option, opt_str, value, parser):
-    ipstr = value
-    ip_family = socket.AF_INET
-    if (ipstr.find(':') != -1):
-        ip_family = socket.AF_INET6
-
     try:
-        socket.inet_pton(ip_family, ipstr)
-    except:
-        raise OptionValueError("%s invalid ip address" % ipstr)
-
-    parser.values.addr = value
+        isc.net.parse.addr_parse(value)
+        parser.values.addr = value
+    except ValueError as e:
+        raise OptionValueError(str(e))
 
 def set_cmd_options(parser):
     parser.add_option('-p', '--port', dest = 'port', type = 'int',
@@ -602,6 +610,9 @@
     except isc.cc.SessionError as err:
         sys.stderr.write("[b10-cmdctl] Error creating b10-cmdctl, "
                          "is the command channel daemon running?\n")        
+    except isc.cc.SessionTimeout:
+        sys.stderr.write("[b10-cmdctl] Error creating b10-cmdctl, "
+                         "is the configuration manager running?\n")        
     except KeyboardInterrupt:
         sys.stderr.write("[b10-cmdctl] exit from Cmdctl\n")
     except CmdctlException as err:

Modified: experiments/327-sync/src/bin/host/Makefile.am
==============================================================================
--- experiments/327-sync/src/bin/host/Makefile.am (original)
+++ experiments/327-sync/src/bin/host/Makefile.am Tue Nov  9 10:38:17 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: experiments/327-sync/src/bin/host/host.cc
==============================================================================
--- experiments/327-sync/src/bin/host/host.cc (original)
+++ experiments/327-sync/src/bin/host/host.cc Tue Nov  9 10:38:17 2010
@@ -28,6 +28,8 @@
 #include <dns/name.h>
 #include <dns/message.h>
 #include <dns/messagerenderer.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
 #include <dns/rrclass.h>
 #include <dns/rrtype.h>
 #include <dns/rrset.h>
@@ -56,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),
@@ -120,9 +122,10 @@
 
             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;
                       }

Modified: experiments/327-sync/src/bin/loadzone/Makefile.am
==============================================================================
--- experiments/327-sync/src/bin/loadzone/Makefile.am (original)
+++ experiments/327-sync/src/bin/loadzone/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,5 +1,4 @@
-SUBDIRS = tests/correct
-SUBDIRS += tests/error
+SUBDIRS = . tests/correct tests/error
 bin_SCRIPTS = b10-loadzone
 
 CLEANFILES = b10-loadzone

Modified: experiments/327-sync/src/bin/loadzone/b10-loadzone.py.in
==============================================================================
--- experiments/327-sync/src/bin/loadzone/b10-loadzone.py.in (original)
+++ experiments/327-sync/src/bin/loadzone/b10-loadzone.py.in Tue Nov  9 10:38:17 2010
@@ -18,9 +18,13 @@
 import sys; sys.path.append ('@@PYTHONPATH@@')
 import re, getopt
 import isc.datasrc
+import isc.util.process
 from isc.datasrc.master import MasterFile
 import time
 import os
+
+isc.util.process.rename()
+
 #########################################################################
 # usage: print usage note and exit
 #########################################################################

Modified: experiments/327-sync/src/bin/loadzone/tests/error/error.known
==============================================================================
--- experiments/327-sync/src/bin/loadzone/tests/error/error.known (original)
+++ experiments/327-sync/src/bin/loadzone/tests/error/error.known Tue Nov  9 10:38:17 2010
@@ -1,5 +1,5 @@
 Error reading zone file: Cannot parse RR, No $ORIGIN: @ IN SOA ns hostmaster 1 3600 1800 1814400 3600
-Error reading zone file: $ORIGIN is not absolute in record:$ORIGIN com
+Error reading zone file: $ORIGIN is not absolute in record: $ORIGIN com
 Error reading zone file: Cannot parse RR: $TL 300
 Error reading zone file: Cannot parse RR: $OIGIN com.
 Error loading database: Error while loading com.: Cannot parse RR: $INLUDE file.txt

Modified: experiments/327-sync/src/bin/msgq/Makefile.am
==============================================================================
--- experiments/327-sync/src/bin/msgq/Makefile.am (original)
+++ experiments/327-sync/src/bin/msgq/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 pkglibexecdir = $(libexecdir)/@PACKAGE@
  

Modified: experiments/327-sync/src/bin/msgq/msgq.py.in
==============================================================================
--- experiments/327-sync/src/bin/msgq/msgq.py.in (original)
+++ experiments/327-sync/src/bin/msgq/msgq.py.in Tue Nov  9 10:38:17 2010
@@ -31,8 +31,11 @@
 import pprint
 import random
 from optparse import OptionParser, OptionValueError
+import isc.util.process
 
 import isc.cc
+
+isc.util.process.rename()
 
 # This is the version that gets displayed to the user.
 __version__ = "v20091030 (Paving the DNS Parking Lot)"
@@ -139,6 +142,10 @@
 
     def setup_listener(self):
         """Set up the listener socket.  Internal function."""
+        if self.verbose:
+            sys.stdout.write("[b10-msgq] Setting up socket at %s\n" %
+                             self.socket_file)
+
         self.listen_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
         
         if os.path.exists(self.socket_file):

Modified: experiments/327-sync/src/bin/msgq/tests/Makefile.am
==============================================================================
--- experiments/327-sync/src/bin/msgq/tests/Makefile.am (original)
+++ experiments/327-sync/src/bin/msgq/tests/Makefile.am Tue Nov  9 10:38:17 2010
@@ -8,6 +8,7 @@
 	for pytest in $(PYTESTS) ; do \
 	echo Running test: $$pytest ; \
 	env PYTHONPATH=$(abs_top_builddir)/src/bin/msgq:$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python \
+	BIND10_TEST_SOCKET_FILE=$(builddir)/test_msgq_socket.sock \
 	$(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
 	done
 

Modified: experiments/327-sync/src/bin/msgq/tests/msgq_test.py
==============================================================================
--- experiments/327-sync/src/bin/msgq/tests/msgq_test.py (original)
+++ experiments/327-sync/src/bin/msgq/tests/msgq_test.py Tue Nov  9 10:38:17 2010
@@ -79,9 +79,14 @@
 
     def test_open_socket_default(self):
         env_var = None
+        orig_socket_file = None
         if "BIND10_MSGQ_SOCKET_FILE" in os.environ:
             env_var = os.environ["BIND10_MSGQ_SOCKET_FILE"]
             del os.environ["BIND10_MSGQ_SOCKET_FILE"]
+        # temporarily replace the class "default" not to be disrupted by
+        # any running BIND 10 instance.
+        if "BIND10_TEST_SOCKET_FILE" in os.environ:
+            MsgQ.SOCKET_FILE = os.environ["BIND10_TEST_SOCKET_FILE"]
         socket_file = MsgQ.SOCKET_FILE
         self.assertFalse(os.path.exists(socket_file))
         msgq = MsgQ();
@@ -96,6 +101,8 @@
             pass
         if env_var is not None:
             os.environ["BIND10_MSGQ_SOCKET_FILE"] = env_var
+        if orig_socket_file is not None:
+            MsgQ.SOCKET_FILE = orig_socket_file
 
     def test_open_socket_bad(self):
         msgq = MsgQ("/does/not/exist")

Modified: experiments/327-sync/src/bin/usermgr/b10-cmdctl-usermgr.py.in
==============================================================================
--- experiments/327-sync/src/bin/usermgr/b10-cmdctl-usermgr.py.in (original)
+++ experiments/327-sync/src/bin/usermgr/b10-cmdctl-usermgr.py.in Tue Nov  9 10:38:17 2010
@@ -25,6 +25,9 @@
 import getpass
 import getopt
 import sys
+import isc.util.process
+
+isc.util.process.rename()
 
 VERSION_NUMBER = 'bind10'
 DEFAULT_FILE = 'cmdctl-accounts.csv'

Modified: experiments/327-sync/src/bin/xfrin/Makefile.am
==============================================================================
--- experiments/327-sync/src/bin/xfrin/Makefile.am (original)
+++ experiments/327-sync/src/bin/xfrin/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 pkglibexecdir = $(libexecdir)/@PACKAGE@
 
@@ -7,10 +7,11 @@
 b10_xfrindir = $(DESTDIR)$(pkgdatadir)
 b10_xfrin_DATA = xfrin.spec
 
-CLEANFILES = b10-xfrin xfrin.pyc xfrin.spec
+CLEANFILES = b10-xfrin xfrin.pyc 
 
 man_MANS = b10-xfrin.8
 EXTRA_DIST = $(man_MANS) b10-xfrin.xml
+EXTRA_DIST += xfrin.spec
 
 if ENABLE_MAN
 
@@ -19,9 +20,6 @@
 
 endif
 
-xfrin.spec: xfrin.spec.pre
-	$(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" xfrin.spec.pre >$@
-
 # TODO: does this need $$(DESTDIR) also?
 # this is done here since configure.ac AC_OUTPUT doesn't expand exec_prefix
 b10-xfrin: xfrin.py

Modified: experiments/327-sync/src/bin/xfrin/TODO
==============================================================================
--- experiments/327-sync/src/bin/xfrin/TODO (original)
+++ experiments/327-sync/src/bin/xfrin/TODO Tue Nov  9 10:38:17 2010
@@ -63,3 +63,8 @@
     which a shutdown notification would be sent to the child.  With
     this approach each thread needs to watch at least two channels,
     and then it would need some asynchronous communication mechanism.
+17. Do zone transfer from notifyfrom address first, if it's one master of the zone.
+18. Check soa serial first when doing zone refreshment.
+19. Add configuration items to seperate zone, including ACL, multiple masters, etc.
+20. Be able to cancel the ongoing zone transfer, and be able to disable zone transfer.
+

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

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

Modified: experiments/327-sync/src/bin/xfrin/tests/xfrin_test.py
==============================================================================
--- experiments/327-sync/src/bin/xfrin/tests/xfrin_test.py (original)
+++ experiments/327-sync/src/bin/xfrin/tests/xfrin_test.py Tue Nov  9 10:38:17 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)
@@ -421,21 +421,21 @@
         name, rrclass = self._do_parse_zone_name_class()
         master_addrinfo = self._do_parse_master_port()
         db_file = self.args.get('db_file')
-        self.assertEqual(master_addrinfo[4][1], int(TEST_MASTER_PORT))
+        self.assertEqual(master_addrinfo[2][1], int(TEST_MASTER_PORT))
         self.assertEqual(name, TEST_ZONE_NAME)
         self.assertEqual(rrclass, TEST_RRCLASS)
-        self.assertEqual(master_addrinfo[4][0], TEST_MASTER_IPV4_ADDRESS)
+        self.assertEqual(master_addrinfo[2][0], TEST_MASTER_IPV4_ADDRESS)
         self.assertEqual(db_file, TEST_DB_FILE)
 
     def test_parse_cmd_params_default_port(self):
         del self.args['port']
         master_addrinfo = self._do_parse_master_port()
-        self.assertEqual(master_addrinfo[4][1], 53)
+        self.assertEqual(master_addrinfo[2][1], 53)
 
     def test_parse_cmd_params_ip6master(self):
         self.args['master'] = TEST_MASTER_IPV6_ADDRESS
         master_addrinfo = self._do_parse_master_port()
-        self.assertEqual(master_addrinfo[4][0], TEST_MASTER_IPV6_ADDRESS)
+        self.assertEqual(master_addrinfo[2][0], TEST_MASTER_IPV6_ADDRESS)
 
     def test_parse_cmd_params_chclass(self):
         self.args['zone_class'] = 'CH'
@@ -454,7 +454,7 @@
         # master address is mandatory.
         del self.args['master']
         master_addrinfo = self._do_parse_master_port()
-        self.assertEqual(master_addrinfo[4][0], DEFAULT_MASTER)
+        self.assertEqual(master_addrinfo[2][0], DEFAULT_MASTER)
 
     def test_parse_cmd_params_bad_ip4(self):
         self.args['master'] = '3.3.3.3.3'
@@ -508,12 +508,12 @@
                                                   self.args)['result'][0], 1)
 
     def test_command_handler_retransfer_nomodule(self):
-        dns_module = sys.modules['libdns_python'] # this must exist
-        del sys.modules['libdns_python']
+        dns_module = sys.modules['pydnspp'] # this must exist
+        del sys.modules['pydnspp']
         self.assertEqual(self.xfr.command_handler("retransfer",
                                                   self.args)['result'][0], 1)
         # sys.modules is global, so we must recover it
-        sys.modules['libdns_python'] = dns_module
+        sys.modules['pydnspp'] = dns_module
 
     def test_command_handler_refresh(self):
         # at this level, refresh is no different than retransfer.

Modified: experiments/327-sync/src/bin/xfrin/xfrin.py.in
==============================================================================
--- experiments/327-sync/src/bin/xfrin/xfrin.py.in (original)
+++ experiments/327-sync/src/bin/xfrin/xfrin.py.in Tue Nov  9 10:38:17 2010
@@ -1,6 +1,7 @@
 #!@PYTHON@
 
 # Copyright (C) 2010  Internet Systems Consortium.
+# Copyright (C) 2010  CZ NIC
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -29,12 +30,16 @@
 from optparse import OptionParser, OptionValueError
 from isc.config.ccsession import *
 from isc.notify import notify_out
+import isc.util.process
+import isc.net.parse
 try:
-    from libdns_python import *
+    from pydnspp import *
 except ImportError as e:
     # C++ loadable module may not be installed; even so the xfrin process
     # must keep running, so we warn about it and move forward.
     sys.stderr.write('[b10-xfrin] failed to import DNS module: %s\n' % str(e))
+
+isc.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,7 +95,7 @@
         self.setblocking(1)
         self._shutdown_event = shutdown_event
         self._verbose = verbose
-        self._master_address = master_addrinfo[4]
+        self._master_address = master_addrinfo[2]
 
     def connect_to_master(self):
         '''Connect to master in TCP.'''
@@ -197,7 +202,6 @@
                                             self._handle_xfrin_response)
 
                 self.log_msg(logstr + 'succeeded')
-                ret = XFRIN_OK
 
         except XfrinException as e:
             self.log_msg(e)
@@ -236,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:
@@ -247,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):
@@ -290,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
 
@@ -327,10 +331,14 @@
     sock_map = {}
     conn = XfrinConnection(sock_map, zone_name, rrclass, db_file,
                            shutdown_event, master_addrinfo, verbose)
+    ret = XFRIN_FAIL
     if conn.connect_to_master():
         ret = conn.do_xfrin(check_soa)
-        server.publish_xfrin_news(zone_name, rrclass, ret)
-
+    
+    # Publish the zone transfer result news, so zonemgr can reset the
+    # zone timer, and xfrout can notify the zone's slaves if the result
+    # is success.
+    server.publish_xfrin_news(zone_name, rrclass, ret)
     xfrin_recorder.decrement(zone_name)
 
 
@@ -394,20 +402,20 @@
         '''This is a straightforward wrapper for cc.check_command, 
         but provided as a separate method for the convenience 
         of unit tests.'''
-        self._module_cc.check_command()
+        self._module_cc.check_command(False)
 
     def config_handler(self, new_config):
         self._max_transfers_in = new_config.get("transfers_in") or self._max_transfers_in
         if ('master_addr' in new_config) or ('master_port' in new_config):
-            # Check if the new master is valid, there should be library for check it.
-            # and user should change the port and address together.
+            # User should change the port and address together.
             try:
                 addr = new_config.get('master_addr') or self._master_addr
                 port = new_config.get('master_port') or self._master_port
-                check_addr_port(addr, port)
+                isc.net.parse.addr_parse(addr)
+                isc.net.parse.port_parse(port)
                 self._master_addr = addr
                 self._master_port = port
-            except:
+            except ValueError:
                 errmsg = "bad format for zone's master: " + str(new_config)
                 log_error(errmsg)
                 return create_answer(1, errmsg)
@@ -436,7 +444,7 @@
                 # specify the notifyfrom address and port, according the RFC1996, zone
                 # transfer should starts first from the notifyfrom, but now, let 'TODO' it.
                 (zone_name, rrclass) = self._parse_zone_name_and_class(args)
-                (master_addr) = check_addr_port(self._master_addr, self._master_port)
+                (master_addr) = build_addr_info(self._master_addr, self._master_port)
                 ret = self.xfrin_start(zone_name, 
                                        rrclass, 
                                        self._get_db_file(),
@@ -484,7 +492,7 @@
     def _parse_master_and_port(self, args):
         port = args.get('port') or self._master_port
         master = args.get('master') or self._master_addr
-        return check_addr_port(master, port)
+        return build_addr_info(master, port)
  
     def _get_db_file(self):
         #TODO, the db file path should be got in auth server's configuration
@@ -511,11 +519,21 @@
         param = {'zone_name': zone_name, 'zone_class': zone_class.to_text()}
         if xfr_result == XFRIN_OK:
             msg = create_command(notify_out.ZONE_NEW_DATA_READY_CMD, param)
-            self._send_cc_session.group_sendmsg(msg, XFROUT_MODULE_NAME)
-            self._send_cc_session.group_sendmsg(msg, ZONE_MANAGER_MODULE_NAME)
+            # catch the exception, in case msgq has been killed.
+            try:
+                self._send_cc_session.group_sendmsg(msg, XFROUT_MODULE_NAME)
+                self._send_cc_session.group_sendmsg(msg, ZONE_MANAGER_MODULE_NAME)
+            except socket.error as err: 
+                log_error("Fail to send message to %s and %s, msgq may has been killed" 
+                          % (XFROUT_MODULE_NAME, ZONE_MANAGER_MODULE_NAME))
         else:
             msg = create_command(ZONE_XFRIN_FAILED, param)
-            self._send_cc_session.group_sendmsg(msg, ZONE_MANAGER_MODULE_NAME)
+            # catch the exception, in case msgq has been killed.
+            try:
+                self._send_cc_session.group_sendmsg(msg, ZONE_MANAGER_MODULE_NAME)
+            except socket.error as err:
+                log_error("Fail to send message to %s, msgq may has been killed" 
+                          % ZONE_MANAGER_MODULE_NAME)
 
     def startup(self):
         while not self._shutdown_event.is_set():
@@ -523,8 +541,8 @@
 
     def xfrin_start(self, zone_name, rrclass, db_file, master_addrinfo,
                     check_soa = True):
-        if "libdns_python" not in sys.modules:
-            return (1, "xfrin failed, can't load dns message python library: 'libdns_python'")
+        if "pydnspp" not in sys.modules:
+            return (1, "xfrin failed, can't load dns message python library: 'pydnspp'")
 
         # check max_transfer_in, else return quota error
         if self.recorder.count() >= self._max_transfers_in:
@@ -557,30 +575,19 @@
     signal.signal(signal.SIGTERM, signal_handler)
     signal.signal(signal.SIGINT, signal_handler)
 
-def check_addr_port(addrstr, portstr):
-    # XXX: Linux (glibc)'s getaddrinfo incorrectly accepts numeric port
-    # string larger than 65535.  So we need to explicit validate it separately.
+def build_addr_info(addrstr, portstr):
+    """
+    Return tuple (family, socktype, sockaddr) for given address and port.
+    IPv4 and IPv6 are the only supported addresses now, so sockaddr will be
+    (address, port). The socktype is socket.SOCK_STREAM for now.
+    """
     try:
-        portnum = int(portstr)
-        if portnum < 0 or portnum > 65535:
-            raise ValueError("invalid port number (out of range): " + portstr)
+        port = isc.net.parse.port_parse(portstr)
+        addr = isc.net.parse.addr_parse(addrstr)
+        return (addr.family, socket.SOCK_STREAM, (addrstr, port))
     except ValueError as err:
         raise XfrinException("failed to resolve master address/port=%s/%s: %s" %
                              (addrstr, portstr, str(err)))
-
-    try:
-        addrinfo = socket.getaddrinfo(addrstr, portstr, socket.AF_UNSPEC,
-                                      socket.SOCK_STREAM, socket.IPPROTO_TCP,
-                                      socket.AI_NUMERICHOST|
-                                      socket.AI_NUMERICSERV)
-    except socket.gaierror as err:
-        raise XfrinException("failed to resolve master address/port=%s/%s: %s" %
-                             (addrstr, portstr, str(err)))
-    if len(addrinfo) != 1:
-        # with the parameters above the result must be uniquely determined.
-        errmsg = "unexpected result for address/port resolution for %s:%s"
-        raise XfrinException(errmsg % (addrstr, portstr))
-    return addrinfo[0]
 
 def set_cmd_options(parser):
     parser.add_option("-v", "--verbose", dest="verbose", action="store_true",

Modified: experiments/327-sync/src/bin/xfrout/Makefile.am
==============================================================================
--- experiments/327-sync/src/bin/xfrout/Makefile.am (original)
+++ experiments/327-sync/src/bin/xfrout/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 pkglibexecdir = $(libexecdir)/@PACKAGE@
 

Modified: experiments/327-sync/src/bin/xfrout/TODO
==============================================================================
--- experiments/327-sync/src/bin/xfrout/TODO (original)
+++ experiments/327-sync/src/bin/xfrout/TODO Tue Nov  9 10:38:17 2010
@@ -1,1 +1,2 @@
-Add unittest code.
+Add unittest code.
+Be able to cancel the outgoing zone transfer, and also be able to disable outgoing zone transfer.

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

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

Modified: experiments/327-sync/src/bin/xfrout/tests/xfrout_test.py
==============================================================================
--- experiments/327-sync/src/bin/xfrout/tests/xfrout_test.py (original)
+++ experiments/327-sync/src/bin/xfrout/tests/xfrout_test.py Tue Nov  9 10:38:17 2010
@@ -19,7 +19,7 @@
 import unittest
 import os
 from isc.cc.session import *
-from libdns_python import *
+from pydnspp import *
 from xfrout import *
 
 # our fake socket, where we can read and insert messages
@@ -40,25 +40,36 @@
         return len(data)
 
     def readsent(self):
-        result = self.sendqueue[:]
-        del self.sendqueue[:]
+        if len(self.sendqueue) >= 2:
+            size = 2 + struct.unpack("!H", self.sendqueue[:2])[0]
+        else:
+            size = 0
+        result = self.sendqueue[:size]
+        self.sendqueue = self.sendqueue[size:]
         return result
-    
+
     def read_msg(self):
         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()
@@ -76,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")
@@ -89,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()
@@ -99,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()
@@ -111,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()
@@ -133,25 +153,67 @@
 
         msg = self.getmsg()
         msg.make_response()
-        self.xfrsess._send_message_with_last_soa(msg, self.sock, rrset_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)
+        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(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")
         rdata = answer.get_rdata()
         self.assertEqual(rdata[0].to_text(), self.soa_record[7])
 
-    def test_get_message_len(self):
-        msg = self.getmsg()
-        msg.make_response()  
-        self.assertEqual(self.xfrsess._get_message_len(msg), 29)
+    def test_trigger_send_message_with_last_soa(self):
+        rrset_a = RRset(Name("example.com"), RRClass.IN(), RRType.A(), RRTTL(3600))
+        rrset_a.add_rdata(Rdata(RRType.A(), RRClass.IN(), "192.0.2.1"))
+        rrset_soa = self.xfrsess._create_rrset_from_db_record(self.soa_record)
+
+        msg = self.getmsg()
+        msg.make_response()
+
+        msg.add_rrset(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)
+
+        # this should have triggered the sending of two messages
+        # (1 with the rrset we added manually, and 1 that triggered
+        # the sending in _with_last_soa)
+        get_msg = self.sock.read_msg()
+        self.assertEqual(get_msg.get_rr_count(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")
+        rdata = answer.get_rdata()
+        self.assertEqual(rdata[0].to_text(), "192.0.2.1")
+
+        get_msg = self.sock.read_msg()
+        self.assertEqual(get_msg.get_rr_count(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")
+        rdata = answer.get_rdata()
+        self.assertEqual(rdata[0].to_text(), self.soa_record[7])
+
+        # and it should not have sent anything else
+        self.assertEqual(0, len(self.sock.sendqueue))
+
+    def test_get_rrset_len(self):
+        rrset_soa = self.xfrsess._create_rrset_from_db_record(self.soa_record)
+        self.assertEqual(82, get_rrset_len(rrset_soa))
 
     def test_zone_is_empty(self):
         global sqlite3_ds
@@ -171,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
@@ -197,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"
 
@@ -209,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):
@@ -235,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):
@@ -246,7 +308,7 @@
             return "initdb.file", False
         else:
             return "unknown", False
-    
+
 
 class MyUnixSockServer(UnixSockServer):
     def __init__(self):
@@ -260,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)
@@ -278,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()
@@ -289,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: experiments/327-sync/src/bin/xfrout/xfrout.py.in
==============================================================================
--- experiments/327-sync/src/bin/xfrout/xfrout.py.in (original)
+++ experiments/327-sync/src/bin/xfrout/xfrout.py.in Tue Nov  9 10:38:17 2010
@@ -1,6 +1,7 @@
 #!@PYTHON@
 
 # Copyright (C) 2010  Internet Systems Consortium.
+# Copyright (C) 2010  CZ NIC
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -27,19 +28,24 @@
 import os
 from isc.config.ccsession import *
 from isc.log.log import *
-from isc.cc import SessionError
+from isc.cc import SessionError, SessionTimeout
 from isc.notify import notify_out
+import isc.util.process
 import socket
 import select
 import errno
 from optparse import OptionParser, OptionValueError
+from isc.util import socketserver_mixin
+
 try:
     from libxfr_python import *
-    from libdns_python import *
+    from pydnspp import *
 except ImportError as e:
     # C++ loadable module may not be installed; even so the xfrout process
     # must keep running, so we warn about it and move forward.
     sys.stderr.write('[b10-xfrout] failed to import DNS or XFR module: %s\n' % str(e))
+
+isc.util.process.rename()
 
 if "B10_FROM_BUILD" in os.environ:
     SPECFILE_PATH = os.environ["B10_FROM_BUILD"] + "/src/bin/xfrout"
@@ -57,47 +63,89 @@
 MAX_TRANSFERS_OUT = 10
 VERBOSE_MODE = False
 
+
+XFROUT_MAX_MESSAGE_SIZE = 65535
+
+def get_rrset_len(rrset):
+    """Returns the wire length of the given RRset"""
+    bytes = bytearray()
+    rrset.to_wire(bytes)
+    return len(bytes)
+
+
 class XfroutSession(BaseRequestHandler):
-    def __init__(self, request, client_address, server, log):
+    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)
@@ -112,39 +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):
-        #obuf = output_buffer(0)
-        #render = message_render(obuf)
+    def _send_message(self, sock_fd, msg):
         render = MessageRenderer()
-        render.set_length_limit(65535)
+        render.set_length_limit(XFROUT_MAX_MESSAGE_SIZE)
         msg.to_wire(render)
         header_len = struct.pack('H', socket.htons(render.get_length()))
-        self._send_data(sock, header_len)
-        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):
@@ -154,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():
@@ -180,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])
@@ -226,97 +272,88 @@
         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):
+
+    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 .
         '''
-
-        render = MessageRenderer()
-        msg.to_wire(render)
-        old_message_len = render.get_length()
-        msg.add_rrset(Section.ANSWER(), rrset_soa)
-
-        msg.to_wire(render)
-        message_len = render.get_length()
-
-        if message_len != old_message_len:
-            self._send_message(sock, msg)
+        rrset_len = get_rrset_len(rrset_soa)
+
+        if message_upper_len + rrset_len < XFROUT_MAX_MESSAGE_SIZE:
+            msg.add_rrset(Message.SECTION_ANSWER, rrset_soa)
         else:
+            self._send_message(sock_fd, msg)
             msg = self._clear_message(msg)
-            msg.add_rrset(Section.ANSWER(), rrset_soa)
-            self._send_message(sock, msg)
-
-    def _get_message_len(self, msg):
-        '''Get message length, every time need do like this? Actually there should be 
-        a better way, I need check with jinmei later.
-        '''
-
-        render = MessageRenderer()
-        msg.to_wire(render)
-        return render.get_length()
-
-
-    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)
-
-        old_message_len = 0
-        # TODO, Since add_rrset() return nothing when rrset can't be added, so I have to compare
-        # the message length to know if the rrset has been added sucessfully.
+        msg.add_rrset(Message.SECTION_ANSWER, rrset_soa)
+
+        message_upper_len = get_rrset_len(rrset_soa)
+
         for rr_data in sqlite3_ds.get_zone_datas(zone_name, self.server.get_db_file()):
             if  self.server._shutdown_event.is_set(): # Check if xfrout is shutdown
-                self._log.log_message("error", "shutdown!")
+                self._log.log_message("info", "xfrout process is being shutdown")
+                return
 
             # TODO: RRType.SOA() ?
             if RRType(rr_data[5]) == RRType("SOA"): #ignore soa record
                 continue
 
             rrset_ = self._create_rrset_from_db_record(rr_data)
-            msg.add_rrset(Section.ANSWER(), rrset_)
-            message_len = self._get_message_len(msg)
-            if message_len != old_message_len:
-                old_message_len = message_len
+
+            # We calculate the maximum size of the RRset (i.e. the
+            # size without compression) and use that to see if we
+            # may have reached the limit
+            rrset_len = get_rrset_len(rrset_)
+            if message_upper_len + rrset_len < XFROUT_MAX_MESSAGE_SIZE:
+                msg.add_rrset(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
-            old_message_len = 0
-
-        self._send_message_with_last_soa(msg, sock, rrset_soa)
-
-
-class UnixSockServer(ThreadingUnixStreamServer):
+            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_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.'''
 
     def __init__(self, sock_file, handle_class, shutdown_event, config_data, cc, log):
         self._remove_unused_sock_file(sock_file)
         self._sock_file = sock_file
+        socketserver_mixin.NoPollMixIn.__init__(self)
         ThreadingUnixStreamServer.__init__(self, sock_file, handle_class)
         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):
-            print("[b10-xfrout] Fail to start xfrout process, unix socket" 
-                  " file '%s' is being used by another xfrout process" % 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):
@@ -325,12 +362,12 @@
             try:
                 os.unlink(sock_file)
             except OSError as err:
-                print('[b10-xfrout] Fail to remove file ' + 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)
@@ -338,10 +375,11 @@
         except socket.error as err:
             return False
         else:
-            return True 
+            return True
 
     def shutdown(self):
-        ThreadingUnixStreamServer.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)
         except Exception as e:
@@ -383,35 +421,16 @@
         self._transfers_counter -= 1
         self._lock.release()
 
-def listen_on_xfr_query(unix_socket_server):
-    '''Listen xfr query in one single thread. Polls for shutdown 
-    every 0.1 seconds, is there a better time?
-    '''
-
-    while True:
-        try:
-            unix_socket_server.serve_forever(poll_interval = 0.1)
-        except select.error as err:
-            # serve_forever() calls select.select(), which can be 
-            # interrupted.
-            # If it is interrupted, it raises select.error with the 
-            # errno set to EINTR. We ignore this case, and let the
-            # normal program flow continue by trying serve_forever()
-            # again.
-            if err.args[0] != errno.EINTR: raise
-
-   
-
 class XfroutServer:
     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._cc.add_remote_config(AUTH_SPECFILE_LOCATION);
         self._config_data = self._cc.get_full_config()
         self._cc.start()
+        self._cc.add_remote_config(AUTH_SPECFILE_LOCATION);
         self._log = isc.log.NSLogger(self._config_data.get('log_name'), self._config_data.get('log_file'),
                                 self._config_data.get('log_severity'), self._config_data.get('log_versions'),
                                 self._config_data.get('log_max_bytes'), True)
@@ -420,18 +439,16 @@
 
     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 = listen_on_xfr_query, args = (self._unix_socket_server,))
+        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)
-        td = threading.Thread(target = notify_out.dispatcher, args = (self._notifier,))
-        td.daemon = True
-        td.start()
+        self._notifier.dispatcher()
 
     def send_notify(self, zone_name, zone_class):
         self._notifier.send_notify(zone_name, zone_class)
@@ -444,7 +461,7 @@
                 answer = create_answer(1, "Unknown config data: " + str(key))
                 continue
             self._config_data[key] = new_config[key]
-        
+
         if self._log:
             self._log.update_config(new_config)
 
@@ -462,9 +479,11 @@
         global xfrout_server
         xfrout_server = None #Avoid shutdown is called twice
         self._shutdown_event.set()
+        self._notifier.shutdown()
         if self._unix_socket_server:
             self._unix_socket_server.shutdown()
 
+        # Wait for all threads to terminate
         main_thread = threading.currentThread()
         for th in threading.enumerate():
             if th is main_thread:
@@ -476,27 +495,27 @@
             self._log.log_message("info", "Received shutdown command.")
             self.shutdown()
             answer = create_answer(0)
-        
+
         elif cmd == notify_out.ZONE_NEW_DATA_READY_CMD:
             zone_name = args.get('zone_name')
             zone_class = args.get('zone_class')
             if zone_name and zone_class:
-                self._log.log_message("info", "Receive notify command for zone:'%s/%s'" \
-                                     % (zone_name, zone_class))
+                self._log.log_message("info", "zone '%s/%s': receive notify others command" \
+                                       % (zone_name, zone_class))
                 self.send_notify(zone_name, zone_class)
                 answer = create_answer(0)
             else:
                 answer = create_answer(1, "Bad command parameter:" + str(args))
 
-        else: 
+        else:
             answer = create_answer(1, "Unknown command:" + str(cmd))
 
-        return answer    
+        return answer
 
     def run(self):
         '''Get and process all commands sent from cfgmgr or other modules. '''
         while not self._shutdown_event.is_set():
-            self._cc.check_command()
+            self._cc.check_command(False)
 
 
 xfrout_server = None
@@ -525,12 +544,15 @@
         xfrout_server = XfroutServer()
         xfrout_server.run()
     except KeyboardInterrupt:
-        sys.stderr.write("[b10-xfrout] exit xfrout process")
+        sys.stderr.write("[b10-xfrout] exit xfrout process\n")
     except SessionError as e:
-        sys.stderr.write("[b10-xfrout] Error creating xfrout," 
-                           "is the command channel daemon running?")
+        sys.stderr.write("[b10-xfrout] Error creating xfrout, "
+                           "is the command channel daemon running?\n")
+    except SessionTimeout as e:
+        sys.stderr.write("[b10-xfrout] Error creating xfrout, "
+                           "is the configuration manager running?\n")
     except ModuleCCSessionError as e:
-        sys.stderr.write("info", '[b10-xfrout] exit xfrout process:', e)
+        sys.stderr.write("[b10-xfrout] exit xfrout process:%s\n" % str(e))
 
     if xfrout_server:
         xfrout_server.shutdown()

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

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

Modified: experiments/327-sync/src/bin/zonemgr/tests/Makefile.am
==============================================================================
--- experiments/327-sync/src/bin/zonemgr/tests/Makefile.am (original)
+++ experiments/327-sync/src/bin/zonemgr/tests/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,5 +1,7 @@
 PYTESTS = zonemgr_test.py
 EXTRA_DIST = $(PYTESTS)
+
+CLEANFILES = initdb.file
 
 # later will have configure option to choose this, like: coverage run --branch
 PYCOVERAGE = $(PYTHON)

Modified: experiments/327-sync/src/bin/zonemgr/tests/zonemgr_test.py
==============================================================================
--- experiments/327-sync/src/bin/zonemgr/tests/zonemgr_test.py (original)
+++ experiments/327-sync/src/bin/zonemgr/tests/zonemgr_test.py Tue Nov  9 10:38:17 2010
@@ -27,6 +27,11 @@
 ZONE_NAME_CLASS1_CH = ("sd.cn.", "CH")
 ZONE_NAME_CLASS2_IN = ("tw.cn", "IN")
 
+MAX_TRANSFER_TIMEOUT = 14400
+LOWERBOUND_REFRESH = 10
+LOWERBOUND_RETRY = 5 
+JITTER_SCOPE = 0.10
+
 class ZonemgrTestException(Exception):
     pass
 
@@ -40,25 +45,39 @@
 
 class MyZonemgrRefresh(ZonemgrRefresh):
     def __init__(self):
-        self._cc = MySession()
-        self._db_file = "initdb.file"
+        class FakeConfig:
+            def get(self, name):
+                if name == 'lowerbound_refresh':
+                    return LOWERBOUND_REFRESH
+                elif name == 'lowerbound_retry':
+                    return LOWERBOUND_RETRY
+                elif name == 'max_transfer_timeout':
+                    return MAX_TRANSFER_TIMEOUT
+                elif name == 'jitter_scope':
+                    return JITTER_SCOPE
+                else:
+                    raise ValueError('Uknown config option')
+        self._master_socket, self._slave_socket = socket.socketpair()
+        ZonemgrRefresh.__init__(self, MySession(), "initdb.file",
+            self._slave_socket, FakeConfig())
+        current_time = time.time()
         self._zonemgr_refresh_info = { 
          ('sd.cn.', 'IN'): {
-         'last_refresh_time': 1280474398.822142,
-         'next_refresh_time': 1280481598.822153, 
+         'last_refresh_time': current_time,
+         'next_refresh_time': current_time + 6500, 
          'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600', 
          'zone_state': 0},
          ('tw.cn', 'CH'): {
-         'last_refresh_time': 1280474399.116421, 
-         'next_refresh_time': 1280481599.116433, 
+         'last_refresh_time': current_time, 
+         'next_refresh_time': current_time + 6900, 
          'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073112 7200 3600 2419200 21600', 
          'zone_state': 0}
         } 
 
 class TestZonemgrRefresh(unittest.TestCase):
     def setUp(self):
-        self.stdout_backup = sys.stdout
-        sys.stdout = open(os.devnull, 'w')
+        self.stderr_backup = sys.stderr
+        sys.stderr = open(os.devnull, 'w')
         self.zone_refresh = MyZonemgrRefresh()
 
     def test_random_jitter(self):
@@ -91,7 +110,7 @@
         time2 = time.time()
         self.assertTrue((time1 + 7200 * 3 / 4) <= zone_timeout)
         self.assertTrue(zone_timeout <= time2 + 7200)
-        
+
     def test_set_zone_retry_timer(self):
         time1 = time.time()
         self.zone_refresh._set_zone_retry_timer(ZONE_NAME_CLASS1_IN)
@@ -137,6 +156,8 @@
          
     def test_zonemgr_reload_zone(self):
         soa_rdata = 'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600'
+        # We need to restore this not to harm other tests
+        old_get_zone_soa = sqlite3_ds.get_zone_soa
         def get_zone_soa(zone_name, db_file):
             return (1, 2, 'sd.cn.', 'cn.sd.', 21600, 'SOA', None, 
                     'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600')
@@ -144,6 +165,7 @@
 
         self.zone_refresh.zonemgr_reload_zone(ZONE_NAME_CLASS1_IN)
         self.assertEqual(soa_rdata, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_soa_rdata"])
+        sqlite3_ds.get_zone_soa = old_get_zone_soa
 
     def test_get_zone_notifier_master(self):
         notify_master = "192.168.1.1"
@@ -221,6 +243,9 @@
 
     def test_zonemgr_add_zone(self):
         soa_rdata = 'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600'
+        # This needs to be restored. The following test actually failed if we left
+        # this unclean
+        old_get_zone_soa = sqlite3_ds.get_zone_soa
 
         def get_zone_soa(zone_name, db_file):
             return (1, 2, 'sd.cn.', 'cn.sd.', 21600, 'SOA', None, 
@@ -241,7 +266,8 @@
             return None
         sqlite3_ds.get_zone_soa = get_zone_soa2
         self.assertRaises(ZonemgrException, self.zone_refresh.zonemgr_add_zone, \
-                                          ZONE_NAME_CLASS1_IN)
+                                         ZONE_NAME_CLASS1_IN)
+        sqlite3_ds.get_zone_soa = old_get_zone_soa
 
     def test_build_zonemgr_refresh_info(self):
         soa_rdata = 'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600'
@@ -311,6 +337,11 @@
         self.assertTrue((time1 + 3 * 3600 / 4) <= next_refresh_time)
         self.assertTrue(next_refresh_time <= time2 + 3600)
         self.assertEqual(ZONE_OK, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"])
+
+        self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["last_refresh_time"] = time1 - 2419200 
+        self.zone_refresh.zone_refresh_fail(ZONE_NAME_CLASS1_IN)
+        self.assertEqual(ZONE_EXPIRED, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"])
+
         self.assertRaises(ZonemgrException, self.zone_refresh.zone_refresh_fail, ("org.cn.", "CH"))
         self.assertRaises(ZonemgrException, self.zone_refresh.zone_refresh_fail, ZONE_NAME_CLASS3_IN) 
 
@@ -332,17 +363,6 @@
         zone_need_refresh = self.zone_refresh._find_need_do_refresh_zone()
         self.assertEqual(ZONE_NAME_CLASS1_IN, zone_need_refresh)
 
-        self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["last_refresh_time"] = time1 - 2419200
-        self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"] = ZONE_EXPIRED
-        zone_need_refresh = self.zone_refresh._find_need_do_refresh_zone()
-        self.assertEqual(None, zone_need_refresh)
-
-        self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"] = ZONE_REFRESHING
-        self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["notify_master"] = "192.168.0.1"
-        zone_need_refresh = self.zone_refresh._find_need_do_refresh_zone()
-        self.assertEqual(ZONE_NAME_CLASS1_IN, zone_need_refresh)
-        self.assertEqual(ZONE_EXPIRED, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"])
-
         self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS2_CH]["refresh_timeout"] = time1 
         zone_need_refresh = self.zone_refresh._find_need_do_refresh_zone()
         self.assertEqual(ZONE_NAME_CLASS2_CH, zone_need_refresh)
@@ -378,7 +398,7 @@
         """This case will run timer in daemon thread. 
         The zone's next_refresh_time is less than now, so zonemgr will do zone refresh 
         immediately. The zone's state will become "refreshing". 
-        Then closing the socket ,the timer will stop, and throw a ZonemgrException."""
+        """
         time1 = time.time()
         self.zone_refresh._zonemgr_refresh_info = {
                 ("sd.cn.", "IN"):{
@@ -387,24 +407,38 @@
                     'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600', 
                     'zone_state': ZONE_OK}
                 }
-        master_socket, slave_socket = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM)
-        self.zone_refresh._socket = master_socket 
-        master_socket.close()
-        self.assertRaises(ZonemgrException, self.zone_refresh.run_timer)
-
-        self.zone_refresh._socket = slave_socket
-        listener = threading.Thread(target = self.zone_refresh.run_timer, args = ())
-        listener.setDaemon(True)
-        listener.start()
-        time.sleep(1)
-
+        self.zone_refresh._check_sock = self.zone_refresh._master_socket 
+        listener = self.zone_refresh.run_timer(daemon=True)
+        # Shut down the timer thread
+        self.zone_refresh.shutdown()
+        # After running timer, the zone's state should become "refreshing".
         zone_state = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"]
         self.assertTrue("refresh_timeout" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
         self.assertTrue(zone_state == ZONE_REFRESHING)
 
+    def test_update_config_data(self):
+        config_data = {
+                    "lowerbound_refresh" : 60,
+                    "lowerbound_retry" : 30,
+                    "max_transfer_timeout" : 19800,
+                    "jitter_scope" : 0.25
+                }
+        self.zone_refresh.update_config_data(config_data)
+        self.assertEqual(60, self.zone_refresh._lowerbound_refresh)
+        self.assertEqual(30, self.zone_refresh._lowerbound_retry)
+        self.assertEqual(19800, self.zone_refresh._max_transfer_timeout)
+        self.assertEqual(0.25, self.zone_refresh._jitter_scope)
+
+    def test_shutdown(self):
+        self.zone_refresh._check_sock = self.zone_refresh._master_socket 
+        listener = self.zone_refresh.run_timer()
+        self.assertTrue(listener.is_alive())
+        # Shut down the timer thread
+        self.zone_refresh.shutdown()
+        self.assertFalse(listener.is_alive())
 
     def tearDown(self):
-        sys.stdout = self.stdout_backup
+        sys.stderr= self.stderr_backup
 
 
 class MyCCSession():
@@ -422,10 +456,16 @@
 
     def __init__(self):
         self._db_file = "initdb.file"
+        self._zone_refresh = None
         self._shutdown_event = threading.Event()
         self._cc = MySession()
         self._module_cc = MyCCSession()
-        self._config_data = {"zone_name" : "org.cn", "zone_class" : "CH", "master" : "127.0.0.1"}
+        self._config_data = {
+                    "lowerbound_refresh" : 10, 
+                    "lowerbound_retry" : 5, 
+                    "max_transfer_timeout" : 14400,
+                    "jitter_scope" : 0.1
+                    }
 
     def _start_zone_refresh_timer(self):
         pass
@@ -436,12 +476,21 @@
         self.zonemgr = MyZonemgr()
 
     def test_config_handler(self):
-        config_data1 = {"zone_name" : "sd.cn.", "zone_class" : "CH", "master" : "192.168.1.1"}
+        config_data1 = {
+                    "lowerbound_refresh" : 60, 
+                    "lowerbound_retry" : 30, 
+                    "max_transfer_timeout" : 14400,
+                    "jitter_scope" : 0.1
+                    }
         self.zonemgr.config_handler(config_data1)
         self.assertEqual(config_data1, self.zonemgr._config_data)
         config_data2 = {"zone_name" : "sd.cn.", "port" : "53", "master" : "192.168.1.1"}
         self.zonemgr.config_handler(config_data2)
         self.assertEqual(config_data1, self.zonemgr._config_data)
+        # jitter should not be bigger than half of the original value
+        config_data3 = {"jitter_scope" : 0.7}
+        self.zonemgr.config_handler(config_data3)
+        self.assertEqual(0.5, self.zonemgr._config_data.get("jitter_scope"))
 
     def test_get_db_file(self):
         self.assertEqual("initdb.file", self.zonemgr.get_db_file())
@@ -457,6 +506,15 @@
         params1 = {"zone_class" : "CH"}
         self.assertRaises(ZonemgrException, self.zonemgr._parse_cmd_params, params2, ZONE_NOTIFY_COMMAND)
 
+    def test_config_data_check(self):
+        # jitter should not be bigger than half of the original value
+        config_data2 = {"jitter_scope" : 0.2}
+        config_data3 = {"jitter_scope" : 0.6}
+        self.zonemgr._config_data_check(config_data2)
+        self.assertEqual(0.2, config_data2.get("jitter_scope"))
+        self.zonemgr._config_data_check(config_data3)
+        self.assertEqual(0.5, config_data3.get("jitter_scope"))
+
     def tearDown(self):
         pass
 

Modified: experiments/327-sync/src/bin/zonemgr/zonemgr.py.in
==============================================================================
--- experiments/327-sync/src/bin/zonemgr/zonemgr.py.in (original)
+++ experiments/327-sync/src/bin/zonemgr/zonemgr.py.in Tue Nov  9 10:38:17 2010
@@ -1,6 +1,7 @@
 #!@PYTHON@
 
 # Copyright (C) 2010  Internet Systems Consortium.
+# Copyright (C) 2010  CZ NIC
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -15,7 +16,7 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-"""\
+"""
 This file implements the Secondary Manager program.
 
 The secondary manager is one of the co-operating processes
@@ -36,6 +37,9 @@
 from isc.datasrc import sqlite3_ds
 from optparse import OptionParser, OptionValueError
 from isc.config.ccsession import *
+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
@@ -69,13 +73,6 @@
 ZONE_REFRESHING = 1
 ZONE_EXPIRED = 2
 
-# smallest refresh timeout
-LOWERBOUND_REFRESH = 10
-# smallest retry timeout
-LOWERBOUND_RETRY = 5
-# max zone transfer timeout
-MAX_TRANSFER_TIMEOUT = 14400
-
 # offsets of fields in the SOA RDATA
 REFRESH_OFFSET = 3
 RETRY_OFFSET = 4
@@ -93,21 +90,26 @@
 
 class ZonemgrRefresh:
     """This class will maintain and manage zone refresh info.
-    It also provides methods to keep track of zone timers and 
+    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):
+    def __init__(self, cc, db_file, slave_socket, config_data):
         self._cc = cc
-        self._socket = slave_socket 
+        self._check_sock = slave_socket
         self._db_file = db_file
-        self._zonemgr_refresh_info = {} 
+        self.update_config_data(config_data)
+        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:
@@ -118,29 +120,30 @@
         return time.time()
 
     def _set_zone_timer(self, zone_name_class, max, jitter):
-        """Set zone next refresh time."""
+        """Set zone next refresh time.
+        jitter should not be bigger than half the original value."""
         self._set_zone_next_refresh_time(zone_name_class, self._get_current_time() + \
                                             self._random_jitter(max, jitter))
 
     def _set_zone_refresh_timer(self, zone_name_class):
         """Set zone next refresh time after zone refresh success.
-           now + refresh*3/4 <= next_refresh_time <= now + refresh
+           now + refresh - jitter  <= next_refresh_time <= now + refresh
            """
         zone_refresh_time = float(self._get_zone_soa_rdata(zone_name_class).split(" ")[REFRESH_OFFSET])
-        zone_refresh_time = max(LOWERBOUND_REFRESH, zone_refresh_time)
-        self._set_zone_timer(zone_name_class, zone_refresh_time, (1 * zone_refresh_time) / 4)
+        zone_refresh_time = max(self._lowerbound_refresh, zone_refresh_time)
+        self._set_zone_timer(zone_name_class, zone_refresh_time, self._jitter_scope * zone_refresh_time)
 
     def _set_zone_retry_timer(self, zone_name_class):
         """Set zone next refresh time after zone refresh fail.
-           now + retry*3/4 <= next_refresh_time <= now + retry
+           now + retry - jitter <= next_refresh_time <= now + retry
            """
         zone_retry_time = float(self._get_zone_soa_rdata(zone_name_class).split(" ")[RETRY_OFFSET])
-        zone_retry_time = max(LOWERBOUND_RETRY, zone_retry_time)
-        self._set_zone_timer(zone_name_class, zone_retry_time, (1 * zone_retry_time) / 4)
+        zone_retry_time = max(self._lowerbound_retry, zone_retry_time)
+        self._set_zone_timer(zone_name_class, zone_retry_time, self._jitter_scope * zone_retry_time)
 
     def _set_zone_notify_timer(self, zone_name_class):
         """Set zone next refresh time after receiving notify
-           next_refresh_time = now 
+           next_refresh_time = now
         """
         self._set_zone_timer(zone_name_class, 0, 0)
 
@@ -153,8 +156,8 @@
     def zone_refresh_success(self, zone_name_class):
         """Update zone info after zone refresh success"""
         if (self._zone_not_exist(zone_name_class)):
-            raise ZonemgrException("[b10-zonemgr] Zone (%s, %s) doesn't \
-                                    belong to zonemgr" % zone_name_class)
+            raise ZonemgrException("[b10-zonemgr] Zone (%s, %s) doesn't "
+                                   "belong to zonemgr" % zone_name_class)
             return
         self.zonemgr_reload_zone(zone_name_class)
         self._set_zone_refresh_timer(zone_name_class)
@@ -164,17 +167,21 @@
     def zone_refresh_fail(self, zone_name_class):
         """Update zone info after zone refresh fail"""
         if (self._zone_not_exist(zone_name_class)):
-            raise ZonemgrException("[b10-zonemgr] Zone (%s, %s) doesn't \
-                                    belong to zonemgr" % zone_name_class)
+            raise ZonemgrException("[b10-zonemgr] Zone (%s, %s) doesn't "
+                                   "belong to zonemgr" % zone_name_class)
             return
-        self._set_zone_state(zone_name_class, ZONE_OK)
+        # Is zone expired?
+        if (self._zone_is_expired(zone_name_class)):
+            self._set_zone_state(zone_name_class, ZONE_EXPIRED)
+        else:
+            self._set_zone_state(zone_name_class, ZONE_OK)
         self._set_zone_retry_timer(zone_name_class)
 
     def zone_handle_notify(self, zone_name_class, master):
         """Handle zone notify"""
         if (self._zone_not_exist(zone_name_class)):
-            raise ZonemgrException("[b10-zonemgr] Notified zone (%s, %s) doesn't \
-                                    belong to zonemgr" % zone_name_class)
+            raise ZonemgrException("[b10-zonemgr] Notified zone (%s, %s) "
+                                   "doesn't belong to zonemgr" % zone_name_class)
             return
         self._set_zone_notifier_master(zone_name_class, master)
         self._set_zone_notify_timer(zone_name_class)
@@ -192,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
@@ -226,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
 
@@ -241,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"]
@@ -261,7 +268,7 @@
         try:
             self._cc.group_sendmsg(msg, module_name)
         except socket.error:
-            sys.err.write("[b10-zonemgr] Failed to send to module %s, the session has been closed." % module_name) 
+            sys.stderr.write("[b10-zonemgr] Failed to send to module %s, the session has been closed." % module_name)
 
     def _find_need_do_refresh_zone(self):
         """Find the first zone need do refresh, if no zone need
@@ -269,26 +276,15 @@
         """
         zone_need_refresh = None
         for zone_name_class in self._zonemgr_refresh_info.keys():
-            # Does the zone expired?
-            if (ZONE_EXPIRED != self._get_zone_state(zone_name_class) and 
-                self._zone_is_expired(zone_name_class)):
-                log_msg("Zone (%s, %s) is expired." % zone_name_class)
-                self._set_zone_state(zone_name_class, ZONE_EXPIRED)
-
             zone_state = self._get_zone_state(zone_name_class)
-            # If zone is expired and doesn't receive notify, skip the zone
-            if (ZONE_EXPIRED == zone_state and 
-                (not self._get_zone_notifier_master(zone_name_class))):
-                continue
-
             # If hasn't received refresh response but are within refresh timeout, skip the zone
             if (ZONE_REFRESHING == zone_state and
                 (self._get_zone_refresh_timeout(zone_name_class) > self._get_current_time())):
                 continue
-                    
-            # Get the zone with minimum next_refresh_time 
-            if ((None == zone_need_refresh) or 
-                (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
 
@@ -296,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() + 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:
@@ -311,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:
@@ -327,62 +323,117 @@
 
         return False
 
-    def run_timer(self):
-        """Keep track of zone timers."""
-        while True:
-            # Zonemgr has no zone.
+    def _run_timer(self, start_event):
+        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():
-                time.sleep(LOWERBOUND_RETRY) # A better time?
-                continue
-
-            zone_need_refresh = self._find_need_do_refresh_zone()
-            # If don't get zone with minimum next refresh time, set timer timeout = LOWERBOUND_REFRESH
-            if not zone_need_refresh:
-                timeout = LOWERBOUND_RETRY
+                timeout = self._lowerbound_retry
             else:
-                timeout = self._get_zone_next_refresh_time(zone_need_refresh) - self._get_current_time()
-                if (timeout < 0):
-                    self._do_refresh(zone_need_refresh)
-                    continue
-
-            """ Wait for the socket notification for a maximum time of timeout 
+                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 not zone_need_refresh:
+                    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
             in seconds (as float)."""
             try:
-                (rlist, wlist, xlist) = select.select([self._socket], [], [], timeout)
-                if rlist:
-                    self._socket.recv(32)
-            except ValueError as e:
-                raise ZonemgrException("[b10-zonemgr] Socket has been closed\n")
-                break
+                rlist, wlist, xlist = select.select([self._check_sock, self._read_sock], [], [], timeout)
             except select.error as e:
                 if e.args[0] == errno.EINTR:
                     (rlist, wlist, xlist) = ([], [], [])
                 else:
-                    raise ZonemgrException("[b10-zonemgr] Error with select(): %s\n" % e)
+                    sys.stderr.write("[b10-zonemgr] Error with select(); %s\n" % e)
                     break
 
+            for fd in rlist:
+                if fd == self._read_sock: # awaken by shutdown socket
+                    # self._running will be False by now, if it is not a false
+                    # 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)
+
+    def run_timer(self, daemon=False):
+        """
+        Keep track of zone timers. Spawns and starts a thread. The thread object is returned.
+
+        You can stop it by calling shutdown().
+        """
+        # Small sanity check
+        if self._running:
+            raise RuntimeError("Trying to run the timers twice at the same time")
+
+        # Prepare the launch
+        self._running = True
+        (self._read_sock, self._write_sock) = socket.socketpair()
+        start_event = threading.Event()
+
+        # Start the thread
+        self._thread = threading.Thread(target = self._run_timer,
+            args = (start_event,))
+        if daemon:
+            self._thread.setDaemon(True)
+        self._thread.start()
+        start_event.wait()
+
+        # Return the thread to anyone interested
+        return self._thread
+
+    def shutdown(self):
+        """
+        Stop the run_timer() thread. Block until it finished. This must be
+        called from a different thread.
+        """
+        if not self._running:
+            raise RuntimeError("Trying to shutdown, but not running")
+
+        # Ask the thread to stop
+        self._running = False
+        self._write_sock.send(b'shutdown') # make self._read_sock readble
+        # Wait for it to actually finnish
+        self._thread.join()
+        # Wipe out what we do not need
+        self._thread = None
+        self._read_sock = None
+        self._write_sock = None
+
+    def update_config_data(self, new_config):
+        """ update ZonemgrRefresh config """
+        self._lowerbound_refresh = new_config.get('lowerbound_refresh')
+        self._lowerbound_retry = new_config.get('lowerbound_retry')
+        self._max_transfer_timeout = new_config.get('max_transfer_timeout')
+        self._jitter_scope = new_config.get('jitter_scope')
 
 class Zonemgr:
     """Zone manager class."""
     def __init__(self):
+        self._zone_refresh = None
         self._setup_session()
         self._db_file = self.get_db_file()
-        # Create socket pair for communicating between main thread and zonemgr timer thread 
+        # 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._start_zone_refresh_timer()
+        self._zone_refresh = ZonemgrRefresh(self._cc, self._db_file, self._slave_socket, self._config_data)
+        self._zone_refresh.run_timer()
 
         self._lock = threading.Lock()
         self._shutdown_event = threading.Event()
-
-    def _start_zone_refresh_timer(self):
-        """Start a new thread to keep track of zone timers"""
-        listener = threading.Thread(target = self._zone_refresh.run_timer, args = ())
-        listener.setDaemon(True)
-        listener.start()
+        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()
@@ -391,6 +442,7 @@
                                                   self.command_handler)
         self._module_cc.add_remote_config(AUTH_SPECFILE_LOCATION)
         self._config_data = self._module_cc.get_full_config()
+        self._config_data_check(self._config_data)
         self._module_cc.start()
 
     def get_db_file(self):
@@ -405,26 +457,37 @@
     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()
         self._master_socket.close()
-
         self._shutdown_event.set()
-        main_thread = threading.currentThread()
-        for th in threading.enumerate():
-            if th is main_thread:
-                continue
-            th.join()
+        self.running = False
 
     def config_handler(self, new_config):
-        """Update config data."""
+        """ Update config data. """
         answer = create_answer(0)
         for key in new_config:
             if key not in self._config_data:
                 answer = create_answer(1, "Unknown config data: " + str(key))
                 continue
             self._config_data[key] = new_config[key]
+
+        self._config_data_check(self._config_data)
+        if (self._zone_refresh):
+            self._zone_refresh.update_config_data(self._config_data)
+
         return answer
+
+    def _config_data_check(self, config_data):
+        """Check whether the new config data is valid or 
+        not. """ 
+        # jitter should not be bigger than half of the original value
+        if config_data.get('jitter_scope') > 0.5:
+            config_data['jitter_scope'] = 0.5
+            log_msg("[b10-zonemgr] jitter_scope is too big, its value will "
+                      "be set to 0.5") 
 
     def _parse_cmd_params(self, args, command):
         zone_name = args.get("zone_name")
@@ -447,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)
@@ -459,21 +522,21 @@
             with self._lock:
                 self._zone_refresh.zone_handle_notify(zone_name_class, master)
             # Send notification to zonemgr timer thread
-            self._master_socket.send(b" ")
+            self._master_socket.send(b" ")# make self._slave_socket readble
 
         elif command == ZONE_XFRIN_SUCCESS_COMMAND:
             """ Handle xfrin success command"""
             zone_name_class = self._parse_cmd_params(args, command)
             with self._lock:
                 self._zone_refresh.zone_refresh_success(zone_name_class)
-            self._master_socket.send(b" ")
+            self._master_socket.send(b" ")# make self._slave_socket readble
 
         elif command == ZONE_XFRIN_FAILED_COMMAND:
             """ Handle xfrin fail command"""
             zone_name_class = self._parse_cmd_params(args, command)
             with self._lock:
                 self._zone_refresh.zone_refresh_fail(zone_name_class)
-            self._master_socket.send(b" ")
+            self._master_socket.send(b" ")# make self._slave_socket readble
 
         elif command == "shutdown":
             self.shutdown()
@@ -484,8 +547,9 @@
         return answer
 
     def run(self):
+        self.running = True
         while not self._shutdown_event.is_set():
-            self._module_cc.check_command()
+            self._module_cc.check_command(False)
 
 zonemgrd = None
 
@@ -513,13 +577,16 @@
         zonemgrd = Zonemgr()
         zonemgrd.run()
     except KeyboardInterrupt:
-        sys.stderr.write("[b10-zonemgr] exit zonemgr process")
+        sys.stderr.write("[b10-zonemgr] exit zonemgr process\n")
     except isc.cc.session.SessionError as e:
-        sys.stderr.write("[b10-zonemgr] Error creating zonemgr, " 
-                           "is the command channel daemon running?")
+        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, "
+                           "is the configuration manager running?\n")
     except isc.config.ModuleCCSessionError as e:
-        sys.stderr.write("info", "[b10-zonemgr] exit zonemgr process:", e)
-
-    if zonemgrd:
+        sys.stderr.write("[b10-zonemgr] exit zonemgr process: %s\n" % str(e))
+
+    if zonemgrd and zonemgrd.running:
         zonemgrd.shutdown()
 

Modified: experiments/327-sync/src/bin/zonemgr/zonemgr.spec.pre.in
==============================================================================
--- experiments/327-sync/src/bin/zonemgr/zonemgr.spec.pre.in (original)
+++ experiments/327-sync/src/bin/zonemgr/zonemgr.spec.pre.in Tue Nov  9 10:38:17 2010
@@ -2,6 +2,30 @@
   "module_spec": {
      "module_name": "Zonemgr",
       "config_data":[
+       {
+         "item_name": "lowerbound_refresh",
+         "item_type": "integer",
+         "item_optional": false,
+         "item_default": 10
+       },
+       {
+         "item_name": "lowerbound_retry",
+         "item_type": "integer",
+         "item_optional": false,
+         "item_default": 5 
+       },
+       {
+         "item_name": "max_transfer_timeout",
+         "item_type": "integer",
+         "item_optional": false,
+         "item_default": 14400 
+       },
+       {
+         "item_name": "jitter_scope",
+         "item_type": "real",
+         "item_optional": false,
+         "item_default": 0.25
+       }
       ],
       "commands": [
         {

Modified: experiments/327-sync/src/lib/bench/Makefile.am
==============================================================================
--- experiments/327-sync/src/lib/bench/Makefile.am (original)
+++ experiments/327-sync/src/lib/bench/Makefile.am Tue Nov  9 10:38:17 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: experiments/327-sync/src/lib/bench/benchmark_util.cc
==============================================================================
--- experiments/327-sync/src/lib/bench/benchmark_util.cc (original)
+++ experiments/327-sync/src/lib/bench/benchmark_util.cc Tue Nov  9 10:38:17 2010
@@ -26,6 +26,8 @@
 #include <dns/name.h>
 #include <dns/message.h>
 #include <dns/messagerenderer.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
 #include <dns/rrtype.h>
 #include <dns/rrclass.h>
 #include <dns/question.h>

Modified: experiments/327-sync/src/lib/bench/example/search_bench.cc
==============================================================================
--- experiments/327-sync/src/lib/bench/example/search_bench.cc (original)
+++ experiments/327-sync/src/lib/bench/example/search_bench.cc Tue Nov  9 10:38:17 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: experiments/327-sync/src/lib/bench/tests/Makefile.am
==============================================================================
--- experiments/327-sync/src/lib/bench/tests/Makefile.am (original)
+++ experiments/327-sync/src/lib/bench/tests/Makefile.am Tue Nov  9 10:38:17 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: experiments/327-sync/src/lib/bench/tests/loadquery_unittest.cc
==============================================================================
--- experiments/327-sync/src/lib/bench/tests/loadquery_unittest.cc (original)
+++ experiments/327-sync/src/lib/bench/tests/loadquery_unittest.cc Tue Nov  9 10:38:17 2010
@@ -22,6 +22,8 @@
 #include <dns/buffer.h>
 #include <dns/message.h>
 #include <dns/name.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
 #include <dns/rrclass.h>
 #include <dns/rrtype.h>
 
@@ -80,13 +82,12 @@
         EXPECT_EQ(0, message.getQid());
         EXPECT_EQ(Opcode::QUERY(), message.getOpcode());
         EXPECT_EQ(Rcode::NOERROR(), message.getRcode());
-        EXPECT_EQ(Rcode::NOERROR(), message.getRcode());
-        EXPECT_FALSE(message.getHeaderFlag(MessageFlag::QR()));
-        EXPECT_FALSE(message.getHeaderFlag(MessageFlag::AA()));
-        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: experiments/327-sync/src/lib/cc/Makefile.am
==============================================================================
--- experiments/327-sync/src/lib/cc/Makefile.am (original)
+++ experiments/327-sync/src/lib/cc/Makefile.am Tue Nov  9 10:38:17 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: experiments/327-sync/src/lib/cc/data.cc
==============================================================================
--- experiments/327-sync/src/lib/cc/data.cc (original)
+++ experiments/327-sync/src/lib/cc/data.cc Tue Nov  9 10:38:17 2010
@@ -184,7 +184,8 @@
 
 namespace {
 inline void
-throwJSONError(const std::string& error, const std::string& file, int line, int pos)
+throwJSONError(const std::string& error, const std::string& file, int line,
+               int pos)
 {
     std::stringstream ss;
     ss << error << " in " + file + ":" << line << ":" << pos;
@@ -427,13 +428,15 @@
 }
 
 ElementPtr
-from_stringstream_string(std::istream& in, const std::string& file, int& line, int& pos)
+from_stringstream_string(std::istream& in, const std::string& file, int& line,
+                         int& pos)
 {
     return (Element::create(str_from_stringstream(in, file, line, pos)));
 }
 
 ElementPtr
-from_stringstream_list(std::istream &in, const std::string& file, int& line, int& pos)
+from_stringstream_list(std::istream &in, const std::string& file, int& line,
+                       int& pos)
 {
     char c = 0;
     ElementPtr list = Element::createList();
@@ -484,8 +487,7 @@
 }
 
 std::string
-Element::typeToName(Element::types type)
-{
+Element::typeToName(Element::types type) {
     switch (type) {
     case Element::integer:
         return (std::string("integer"));
@@ -538,14 +540,16 @@
 }
 
 ElementPtr
-Element::fromJSON(std::istream& in, const std::string& file_name) throw(JSONError)
+Element::fromJSON(std::istream& in, const std::string& file_name)
+    throw(JSONError)
 {
     int line = 1, pos = 1;
     return (fromJSON(in, file_name, line, pos));
 }
 
 ElementPtr
-Element::fromJSON(std::istream &in, const std::string& file, int& line, int& pos) throw(JSONError)
+Element::fromJSON(std::istream &in, const std::string& file, int& line,
+                  int& pos) throw(JSONError)
 {
     char c = 0;
     ElementPtr element;
@@ -892,7 +896,7 @@
         isc_throw(TypeError, "merge arguments not MapElements");
     }
     
-    std::map<std::string, ConstElementPtr> m = other->mapValue();
+    const std::map<std::string, ConstElementPtr>& m = other->mapValue();
     for (std::map<std::string, ConstElementPtr>::const_iterator it = m.begin();
          it != m.end() ; ++it) {
         if ((*it).second && (*it).second->getType() != Element::null) {

Modified: experiments/327-sync/src/lib/cc/tests/Makefile.am
==============================================================================
--- experiments/327-sync/src/lib/cc/tests/Makefile.am (original)
+++ experiments/327-sync/src/lib/cc/tests/Makefile.am Tue Nov  9 10:38:17 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
@@ -18,8 +22,7 @@
 # (TODO: these need to be completed and moved to tests/)
 run_unittests_SOURCES = data_unittests.cc session_unittests.cc run_unittests.cc
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
-# TODO: remove PTHREAD_LDFLAGS (and from configure too)
-run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) $(PTHREAD_LDFLAGS)
+run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
 
 run_unittests_LDADD = $(GTEST_LDADD)
 run_unittests_LDADD +=  $(top_builddir)/src/lib/cc/libcc.la

Modified: experiments/327-sync/src/lib/cc/tests/data_unittests.cc
==============================================================================
--- experiments/327-sync/src/lib/cc/tests/data_unittests.cc (original)
+++ experiments/327-sync/src/lib/cc/tests/data_unittests.cc Tue Nov  9 10:38:17 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: experiments/327-sync/src/lib/cc/tests/run_unittests.cc
==============================================================================
--- experiments/327-sync/src/lib/cc/tests/run_unittests.cc (original)
+++ experiments/327-sync/src/lib/cc/tests/run_unittests.cc Tue Nov  9 10:38:17 2010
@@ -17,8 +17,7 @@
 #include <gtest/gtest.h>
 
 int
-main(int argc, char* argv[])
-{
+main(int argc, char* argv[]) {
     ::testing::InitGoogleTest(&argc, argv);
     return (RUN_ALL_TESTS());
 }

Modified: experiments/327-sync/src/lib/config/Makefile.am
==============================================================================
--- experiments/327-sync/src/lib/config/Makefile.am (original)
+++ experiments/327-sync/src/lib/config/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,52 +1,11 @@
-SUBDIRS = . testdata tests
+SUBDIRS = . tests
 
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += -I$(top_builddir)/src/lib/cc
+AM_CPPFLAGS += $(BOOST_INCLUDES)
 AM_CXXFLAGS = $(B10_CXXFLAGS) -Wno-strict-aliasing
 
 lib_LTLIBRARIES = libcfgclient.la
 libcfgclient_la_SOURCES = config_data.h config_data.cc module_spec.h module_spec.cc ccsession.cc ccsession.h
 
 CLEANFILES = *.gcno *.gcda
-
-EXTRA_DIST =  testdata/b10-config-bad1.db
-EXTRA_DIST += testdata/b10-config-bad2.db
-EXTRA_DIST += testdata/b10-config-bad3.db
-EXTRA_DIST += testdata/b10-config-bad4.db
-EXTRA_DIST += testdata/b10-config.db.master #.db will be auto-generated
-EXTRA_DIST += testdata/data22_1.data
-EXTRA_DIST += testdata/data22_2.data
-EXTRA_DIST += testdata/data22_3.data
-EXTRA_DIST += testdata/data22_4.data
-EXTRA_DIST += testdata/data22_5.data
-EXTRA_DIST += testdata/data22_6.data
-EXTRA_DIST += testdata/data22_7.data
-EXTRA_DIST += testdata/data22_8.data
-EXTRA_DIST += testdata/spec1.spec
-EXTRA_DIST += testdata/spec2.spec
-EXTRA_DIST += testdata/spec3.spec
-EXTRA_DIST += testdata/spec4.spec
-EXTRA_DIST += testdata/spec5.spec
-EXTRA_DIST += testdata/spec6.spec
-EXTRA_DIST += testdata/spec7.spec
-EXTRA_DIST += testdata/spec8.spec
-EXTRA_DIST += testdata/spec9.spec
-EXTRA_DIST += testdata/spec10.spec
-EXTRA_DIST += testdata/spec11.spec
-EXTRA_DIST += testdata/spec12.spec
-EXTRA_DIST += testdata/spec13.spec
-EXTRA_DIST += testdata/spec14.spec
-EXTRA_DIST += testdata/spec15.spec
-EXTRA_DIST += testdata/spec16.spec
-EXTRA_DIST += testdata/spec17.spec
-EXTRA_DIST += testdata/spec18.spec
-EXTRA_DIST += testdata/spec19.spec
-EXTRA_DIST += testdata/spec20.spec
-EXTRA_DIST += testdata/spec21.spec
-EXTRA_DIST += testdata/spec22.spec
-EXTRA_DIST += testdata/spec23.spec
-EXTRA_DIST += testdata/spec24.spec
-EXTRA_DIST += testdata/spec25.spec
-EXTRA_DIST += testdata/spec26.spec
-EXTRA_DIST += testdata/spec27.spec
-EXTRA_DIST += testdata/spec28.spec

Modified: experiments/327-sync/src/lib/config/ccsession.cc
==============================================================================
--- experiments/327-sync/src/lib/config/ccsession.cc (original)
+++ experiments/327-sync/src/lib/config/ccsession.cc Tue Nov  9 10:38:17 2010
@@ -45,6 +45,7 @@
 using namespace std;
 
 using isc::data::Element;
+using isc::data::ConstElementPtr;
 using isc::data::ElementPtr;
 using isc::data::JSONError;
 
@@ -333,8 +334,7 @@
 }
 
 std::string
-ModuleCCSession::addRemoteConfig(const std::string& spec_file_name)
-{
+ModuleCCSession::addRemoteConfig(const std::string& spec_file_name) {
     ModuleSpec rmod_spec = readModuleSpecification(spec_file_name);
     std::string module_name = rmod_spec.getFullSpec()->get("module_name")->stringValue();
     ConfigData rmod_config = ConfigData(rmod_spec);
@@ -362,8 +362,7 @@
 }
 
 void
-ModuleCCSession::removeRemoteConfig(const std::string& module_name)
-{
+ModuleCCSession::removeRemoteConfig(const std::string& module_name) {
     std::map<std::string, ConfigData>::iterator it;
 
     it = remote_module_configs_.find(module_name);

Modified: experiments/327-sync/src/lib/config/ccsession.h
==============================================================================
--- experiments/327-sync/src/lib/config/ccsession.h (original)
+++ experiments/327-sync/src/lib/config/ccsession.h Tue Nov  9 10:38:17 2010
@@ -31,7 +31,7 @@
 /// \brief Creates a standard config/command level success answer message
 ///        (i.e. of the form { "result": [ 0 ] }
 /// \return Standard command/config success answer message
-ConstElementPtr createAnswer();
+isc::data::ConstElementPtr createAnswer();
 
 ///
 /// \brief Creates a standard config/command level answer message
@@ -43,7 +43,8 @@
 ///            Element type. For rcode == 1, this argument is mandatory,
 ///            and must be a StringElement containing an error description
 /// \return Standard command/config answer message
-ConstElementPtr createAnswer(const int rcode, ConstElementPtr arg);
+isc::data::ConstElementPtr createAnswer(const int rcode,
+                                        isc::data::ConstElementPtr arg);
 
 ///
 /// \brief Creates a standard config/command level answer message
@@ -52,7 +53,8 @@
 /// \param rcode The return code (0 for success)
 /// \param arg A string to put into the StringElement argument
 /// \return Standard command/config answer message
-ConstElementPtr createAnswer(const int rcode, const std::string& arg);
+isc::data::ConstElementPtr createAnswer(const int rcode,
+                                        const std::string& arg);
 
 ///
 /// Parses a standard config/command level answer message
@@ -63,7 +65,8 @@
 /// \return The optional argument in the message, or an empty ElementPtr
 ///         if there was no argument. If rcode != 0, this contains a
 ///         StringElement with the error description.
-ConstElementPtr parseAnswer(int &rcode, ConstElementPtr msg);
+isc::data::ConstElementPtr parseAnswer(int &rcode,
+                                       isc::data::ConstElementPtr msg);
 
 ///
 /// \brief Creates a standard config/command command message with no
@@ -71,7 +74,7 @@
 /// 
 /// \param command The command string
 /// \return The created message
-ConstElementPtr createCommand(const std::string& command);
+isc::data::ConstElementPtr createCommand(const std::string& command);
 
 ///
 /// \brief Creates a standard config/command command message with the
@@ -81,7 +84,8 @@
 /// \param arg The optional argument for the command. This can be of 
 ///        any Element type, but it should conform to the .spec file.
 /// \return The created message
-ConstElementPtr createCommand(const std::string& command, ConstElementPtr arg);
+isc::data::ConstElementPtr createCommand(const std::string& command,
+                                         isc::data::ConstElementPtr arg);
 
 ///
 /// \brief Parses the given command into a string containing the actual
@@ -92,7 +96,8 @@
 /// \param command The command message containing the command (as made
 ///        by createCommand()
 /// \return The command string
-std::string parseCommand(ConstElementPtr& arg, ConstElementPtr command);
+std::string parseCommand(isc::data::ConstElementPtr& arg,
+                         isc::data::ConstElementPtr command);
 
 
 ///
@@ -225,8 +230,9 @@
      * \param identifier The identifier of the config value
      * \return The configuration setting at the given identifier
      */
-    ConstElementPtr getRemoteConfigValue(const std::string& module_name,
-                                         const std::string& identifier) const;
+    isc::data::ConstElementPtr getRemoteConfigValue(
+        const std::string& module_name,
+        const std::string& identifier) const;
     
 private:
     ModuleSpec readModuleSpecification(const std::string& filename);
@@ -235,7 +241,8 @@
     std::string module_name_;
     isc::cc::AbstractSession& session_;
     ModuleSpec module_specification_;
-    ConstElementPtr handleConfigUpdate(ConstElementPtr new_config);
+    isc::data::ConstElementPtr handleConfigUpdate(
+        isc::data::ConstElementPtr new_config);
 
     isc::data::ConstElementPtr(*config_handler_)(
         isc::data::ConstElementPtr new_config);
@@ -245,7 +252,7 @@
 
     std::map<std::string, ConfigData> remote_module_configs_;
     void updateRemoteConfig(const std::string& module_name,
-                            ConstElementPtr new_config);
+                            isc::data::ConstElementPtr new_config);
 };
 
 }

Modified: experiments/327-sync/src/lib/config/config_data.h
==============================================================================
--- experiments/327-sync/src/lib/config/config_data.h (original)
+++ experiments/327-sync/src/lib/config/config_data.h Tue Nov  9 10:38:17 2010
@@ -39,12 +39,14 @@
 public:
     /// Constructs a ConfigData option with no specification and an
     /// empty configuration.
-    ConfigData() { _config = Element::createMap(); };
+    ConfigData() { _config = isc::data::Element::createMap(); };
 
     /// Constructs a ConfigData option with the given specification
     /// and an empty configuration.
     /// \param module_spec A ModuleSpec for the relevant module
-    ConfigData(const ModuleSpec& module_spec) : _module_spec(module_spec) { _config = Element::createMap(); }
+    ConfigData(const ModuleSpec& module_spec) : _module_spec(module_spec) {
+        _config = isc::data::Element::createMap();
+    }
 
     virtual ~ConfigData() {};
 
@@ -55,7 +57,7 @@
     /// Raises a DataNotFoundError if the identifier is bad.
     /// \param identifier The identifier pointing to the configuration
     ///        value that is to be returned
-    ConstElementPtr getValue(const std::string& identifier) const;
+    isc::data::ConstElementPtr getValue(const std::string& identifier) const;
 
     /// Returns the value currently set for the given identifier
     /// If no value is set, the default value (as specified by the
@@ -67,8 +69,8 @@
     ///                   false otherwise
     /// \param identifier The identifier pointing to the configuration
     ///        value that is to be returned
-    ConstElementPtr getValue(bool& is_default,
-                             const std::string& identifier) const;
+    isc::data::ConstElementPtr getValue(bool& is_default,
+                                        const std::string& identifier) const;
 
     /// Returns the ModuleSpec associated with this ConfigData object
     const ModuleSpec& getModuleSpec() const { return (_module_spec); }
@@ -80,12 +82,12 @@
     /// \param config An ElementPtr pointing to a MapElement containing
     ///        *all* non-default configuration values. Existing values
     ///        will be removed.
-    void setLocalConfig(ElementPtr config) { _config = config; }
+    void setLocalConfig(isc::data::ElementPtr config) { _config = config; }
 
     /// Returns the local (i.e. non-default) configuration.
     /// \returns An ElementPtr pointing to a MapElement containing all
     ///          non-default configuration options.
-    ElementPtr getLocalConfig() { return (_config); }
+    isc::data::ElementPtr getLocalConfig() { return (_config); }
 
     /// Returns a list of all possible configuration options as specified
     ///         by the ModuleSpec.
@@ -97,18 +99,18 @@
     ///         StringElements that specify the identifiers at the given
     ///         location (or all possible identifiers if identifier==""
     ///         and recurse==false)
-    ConstElementPtr getItemList(const std::string& identifier = "",
-                                bool recurse = false) const;
+    isc::data::ConstElementPtr getItemList(const std::string& identifier = "",
+                                           bool recurse = false) const;
 
     /// Returns all current configuration settings (both non-default and default).
     /// \return An ElementPtr pointing to a MapElement containing
     ///         string->value elements, where the string is the
     ///         full identifier of the configuration option and the
     ///         value is an ElementPtr with the value.
-    ConstElementPtr getFullConfig() const;
+    isc::data::ConstElementPtr getFullConfig() const;
 
 private:
-    ElementPtr _config;
+    isc::data::ElementPtr _config;
     ModuleSpec _module_spec;
 };
 

Modified: experiments/327-sync/src/lib/config/module_spec.cc
==============================================================================
--- experiments/327-sync/src/lib/config/module_spec.cc (original)
+++ experiments/327-sync/src/lib/config/module_spec.cc Tue Nov  9 10:38:17 2010
@@ -24,6 +24,7 @@
 
 // todo: add more context to thrown ModuleSpecErrors?
 
+using namespace isc::data;
 using namespace isc::config;
 
 namespace {

Modified: experiments/327-sync/src/lib/config/module_spec.h
==============================================================================
--- experiments/327-sync/src/lib/config/module_spec.h (original)
+++ experiments/327-sync/src/lib/config/module_spec.h Tue Nov  9 10:38:17 2010
@@ -19,8 +19,6 @@
 #include <cc/data.h>
 
 #include <sstream>
-
-using namespace isc::data;
 
 namespace isc { namespace config {
 
@@ -55,24 +53,27 @@
         /// Create a \c ModuleSpec instance with the given data as
         /// the specification
         /// \param e The Element containing the data specification
-        explicit ModuleSpec(ConstElementPtr e, const bool check = true)
+        explicit ModuleSpec(isc::data::ConstElementPtr e,
+                            const bool check = true)
             throw(ModuleSpecError);
 
         /// Returns the commands part of the specification as an
         /// ElementPtr, returns an empty ElementPtr if there is none
         /// \return ElementPtr Shared pointer to the commands
         ///                    part of the specification
-        ConstElementPtr getCommandsSpec() const;
+        isc::data::ConstElementPtr getCommandsSpec() const;
 
         /// Returns the configuration part of the specification as an
         /// ElementPtr
         /// \return ElementPtr Shared pointer to the configuration
         ///                    part of the specification
-        ConstElementPtr getConfigSpec() const;
+        isc::data::ConstElementPtr getConfigSpec() const;
 
         /// Returns the full module specification as an ElementPtr
         /// \return ElementPtr Shared pointer to the specification
-        ConstElementPtr getFullSpec() const { return module_specification; }
+        isc::data::ConstElementPtr getFullSpec() const {
+            return module_specification;
+        }
 
         /// Returns the module name as specified by the specification
         const std::string getModuleName() const;
@@ -87,22 +88,28 @@
         /// \param data The base \c Element of the data to check
         /// \return true if the data conforms to the specification,
         /// false otherwise.
-        bool validate_config(ConstElementPtr data,
+        bool validate_config(isc::data::ConstElementPtr data,
                              const bool full = false) const;
 
         /// errors must be of type ListElement
-        bool validate_config(ConstElementPtr data, const bool full,
-                             ElementPtr errors) const;
+        bool validate_config(isc::data::ConstElementPtr data, const bool full,
+                             isc::data::ElementPtr errors) const;
 
     private:
-        bool validate_item(ConstElementPtr spec, ConstElementPtr data,
-                           const bool full, ElementPtr errors) const;
-        bool validate_spec(ConstElementPtr spec, ConstElementPtr data,
-                           const bool full, ElementPtr errors) const;
-        bool validate_spec_list(ConstElementPtr spec, ConstElementPtr data,
-                                const bool full, ElementPtr errors) const;
+        bool validate_item(isc::data::ConstElementPtr spec,
+                           isc::data::ConstElementPtr data,
+                           const bool full,
+                           isc::data::ElementPtr errors) const;
+        bool validate_spec(isc::data::ConstElementPtr spec,
+                           isc::data::ConstElementPtr data,
+                           const bool full,
+                           isc::data::ElementPtr errors) const;
+        bool validate_spec_list(isc::data::ConstElementPtr spec,
+                                isc::data::ConstElementPtr data,
+                                const bool full,
+                                isc::data::ElementPtr errors) const;
 
-        ConstElementPtr module_specification;
+        isc::data::ConstElementPtr module_specification;
     };
 
     /// Creates a \c ModuleSpec instance from the contents
@@ -115,7 +122,7 @@
     /// is checked to be of the correct form
     ModuleSpec
     moduleSpecFromFile(const std::string& file_name, const bool check = true)
-                       throw(JSONError, ModuleSpecError);
+        throw(isc::data::JSONError, ModuleSpecError);
 
     /// Creates a \c ModuleSpec instance from the given input
     /// stream that contains the contents of a .spec file.
@@ -127,7 +134,7 @@
     /// to be of the correct form
     ModuleSpec
     moduleSpecFromFile(std::ifstream& in, const bool check = true)
-                       throw(JSONError, ModuleSpecError);
+                       throw(isc::data::JSONError, ModuleSpecError);
 } }
 
 #endif // _DATA_DEF_H

Modified: experiments/327-sync/src/lib/config/tests/Makefile.am
==============================================================================
--- experiments/327-sync/src/lib/config/tests/Makefile.am (original)
+++ experiments/327-sync/src/lib/config/tests/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,4 +1,7 @@
+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
@@ -23,13 +26,10 @@
 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 += libfake_session.la
 run_unittests_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
-# link *only* to data.o from lib/cc (more importantly, don't link in
-# the session class provided there, since we use our own fake_session
-# here)
-run_unittests_LDADD += $(top_builddir)/src/lib/cc/data.o
 
 endif
 

Modified: experiments/327-sync/src/lib/config/tests/ccsession_unittests.cc
==============================================================================
--- experiments/327-sync/src/lib/config/tests/ccsession_unittests.cc (original)
+++ experiments/327-sync/src/lib/config/tests/ccsession_unittests.cc Tue Nov  9 10:38:17 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;
@@ -164,11 +164,10 @@
     EXPECT_EQ(0, session.getMsgQueue()->size());
 }
 
-TEST_F(CCSessionTest, session2)
-{
-    EXPECT_EQ(false, session.haveSubscription("Spec2", "*"));
+TEST_F(CCSessionTest, session2) {
+    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;
@@ -212,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;
@@ -236,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;
@@ -341,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
@@ -388,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: experiments/327-sync/src/lib/config/tests/data_def_unittests_config.h.in
==============================================================================
--- experiments/327-sync/src/lib/config/tests/data_def_unittests_config.h.in (original)
+++ experiments/327-sync/src/lib/config/tests/data_def_unittests_config.h.in Tue Nov  9 10:38:17 2010
@@ -12,4 +12,4 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-#define TEST_DATA_PATH "@abs_srcdir@/../testdata"
+#define TEST_DATA_PATH "@abs_srcdir@/testdata"

Modified: experiments/327-sync/src/lib/config/tests/module_spec_unittests.cc
==============================================================================
--- experiments/327-sync/src/lib/config/tests/module_spec_unittests.cc (original)
+++ experiments/327-sync/src/lib/config/tests/module_spec_unittests.cc Tue Nov  9 10:38:17 2010
@@ -105,8 +105,7 @@
                    "badname is not a valid type name");
 }
 
-TEST(ModuleSpec, SpecfileConfigData)
-{
+TEST(ModuleSpec, SpecfileConfigData) {
     module_spec_error("spec7.spec",
                    "module_name missing in {  }");
     module_spec_error("spec8.spec",
@@ -117,8 +116,7 @@
                    "commands is not a list of elements");
 }
 
-TEST(ModuleSpec, SpecfileCommands)
-{
+TEST(ModuleSpec, SpecfileCommands) {
     module_spec_error("spec17.spec",
                    "command_name missing in { \"command_args\": [ { \"item_default\": \"\", \"item_name\": \"message\", \"item_optional\": false, \"item_type\": \"string\" } ], \"command_description\": \"Print the given message to stdout\" }");
     module_spec_error("spec18.spec",

Modified: experiments/327-sync/src/lib/config/tests/run_unittests.cc
==============================================================================
--- experiments/327-sync/src/lib/config/tests/run_unittests.cc (original)
+++ experiments/327-sync/src/lib/config/tests/run_unittests.cc Tue Nov  9 10:38:17 2010
@@ -17,8 +17,7 @@
 #include <gtest/gtest.h>
 
 int
-main(int argc, char* argv[])
-{
+main(int argc, char* argv[]) {
     ::testing::InitGoogleTest(&argc, argv);
     return (RUN_ALL_TESTS());
 }

Modified: experiments/327-sync/src/lib/datasrc/Makefile.am
==============================================================================
--- experiments/327-sync/src/lib/datasrc/Makefile.am (original)
+++ experiments/327-sync/src/lib/datasrc/Makefile.am Tue Nov  9 10:38:17 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)

Modified: experiments/327-sync/src/lib/datasrc/data_source.cc
==============================================================================
--- experiments/327-sync/src/lib/datasrc/data_source.cc (original)
+++ experiments/327-sync/src/lib/datasrc/data_source.cc Tue Nov  9 10:38:17 2010
@@ -32,6 +32,7 @@
 #include <dns/buffer.h>
 #include <dns/message.h>
 #include <dns/name.h>
+#include <dns/rcode.h>
 #include <dns/rdataclass.h>
 #include <dns/rrset.h>
 #include <dns/rrsetlist.h>
@@ -100,14 +101,14 @@
             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))); 
         }
@@ -164,7 +165,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)));
 }
 
@@ -206,6 +207,11 @@
         if (!hit || !rrset || (flags & DataSrc::CNAME_FOUND) != 0) {
             hit = cache.retrieve(task.qname, task.qclass, RRType::CNAME(),
                                  rrset, flags);
+            if (!rrset) {
+                // If we don't have a positive cache, forget it; otherwise the
+                // intermediate result may confuse the subsequent processing.
+                hit = false;
+            }
         }
 
         if (hit) {
@@ -467,16 +473,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());
         }
     }
@@ -492,7 +501,7 @@
         if (rrset->getType() == RRType::DS() && !q.wantDnssec()) {
             continue;
         }
-        addToMessage(q, Section::AUTHORITY(), rrset);
+        addToMessage(q, Message::SECTION_AUTHORITY, rrset);
         getAdditional(q, rrset);
     }
 }
@@ -554,11 +563,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()));
@@ -576,7 +585,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);
@@ -593,7 +602,7 @@
         return (DataSrc::ERROR);
     }
 
-    addToMessage(q, Section::AUTHORITY(),
+    addToMessage(q, Message::SECTION_AUTHORITY,
                  soa.findRRset(RRType::SOA(), q.qclass()));
     return (DataSrc::SUCCESS);
 }
@@ -605,7 +614,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()));
     }
 
@@ -674,7 +683,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) {
@@ -699,7 +708,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;
             }
         }
@@ -714,7 +723,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);
@@ -772,7 +781,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) {
@@ -814,13 +823,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;
@@ -849,7 +858,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();
@@ -976,19 +985,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);
                 }
@@ -1057,13 +1066,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);
             }
         }
     }

Modified: experiments/327-sync/src/lib/datasrc/query.cc
==============================================================================
--- experiments/327-sync/src/lib/datasrc/query.cc (original)
+++ experiments/327-sync/src/lib/datasrc/query.cc Tue Nov  9 10:38:17 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: experiments/327-sync/src/lib/datasrc/query.h
==============================================================================
--- experiments/327-sync/src/lib/datasrc/query.h (original)
+++ experiments/327-sync/src/lib/datasrc/query.h Tue Nov  9 10:38:17 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: experiments/327-sync/src/lib/datasrc/static_datasrc.cc
==============================================================================
--- experiments/327-sync/src/lib/datasrc/static_datasrc.cc (original)
+++ experiments/327-sync/src/lib/datasrc/static_datasrc.cc Tue Nov  9 10:38:17 2010
@@ -110,14 +110,12 @@
                                "0 28800 7200 604800 86400"));
 }
 
-StaticDataSrc::StaticDataSrc()
-{
+StaticDataSrc::StaticDataSrc() {
     setClass(RRClass::CH());
     impl_ = new StaticDataSrcImpl;
 }
 
-StaticDataSrc::~StaticDataSrc()
-{
+StaticDataSrc::~StaticDataSrc() {
     delete impl_;
 }
 

Modified: experiments/327-sync/src/lib/datasrc/tests/Makefile.am
==============================================================================
--- experiments/327-sync/src/lib/datasrc/tests/Makefile.am (original)
+++ experiments/327-sync/src/lib/datasrc/tests/Makefile.am Tue Nov  9 10:38:17 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)

Modified: experiments/327-sync/src/lib/datasrc/tests/datasrc_unittest.cc
==============================================================================
--- experiments/327-sync/src/lib/datasrc/tests/datasrc_unittest.cc (original)
+++ experiments/327-sync/src/lib/datasrc/tests/datasrc_unittest.cc Tue Nov  9 10:38:17 2010
@@ -26,6 +26,8 @@
 #include <dns/message.h>
 #include <dns/messagerenderer.h>
 #include <dns/question.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
 #include <dns/rdata.h>
 #include <dns/rdataclass.h>
 #include <dns/rrclass.h>
@@ -77,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);
@@ -90,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);
 }
 
@@ -100,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
@@ -115,7 +117,7 @@
 
     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());
@@ -129,7 +131,7 @@
 
     // XXX: also check ANSWER RRSIG
 
-    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());
@@ -145,7 +147,7 @@
     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());
@@ -169,9 +171,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.
@@ -184,7 +186,7 @@
                           RRType::NS());
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 0, 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::NS(), rrset->getType());
@@ -207,7 +209,7 @@
                           RRType::NS());
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 0, 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::NS(), rrset->getType());
@@ -228,7 +230,7 @@
                           RRType::NS());
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 0, 6);
 
-    rit = msg.beginSection(Section::ANSWER());
+    rit = msg.beginSection(Message::SECTION_ANSWER);
     rrset = *rit;
     EXPECT_EQ(Name("example.com"), rrset->getName());
     EXPECT_EQ(RRType::NS(), rrset->getType());
@@ -250,7 +252,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());
@@ -265,7 +267,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());
@@ -274,7 +276,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());
@@ -287,7 +289,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());
@@ -299,7 +301,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());
@@ -314,9 +316,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) {
@@ -325,7 +327,7 @@
 
     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());
@@ -337,7 +339,7 @@
     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());
@@ -360,7 +362,7 @@
     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());
@@ -397,7 +399,7 @@
 
     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());
@@ -422,7 +424,7 @@
     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());
@@ -445,7 +447,7 @@
     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());
@@ -465,7 +467,7 @@
                           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());
@@ -477,7 +479,7 @@
     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());
@@ -497,7 +499,7 @@
                           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());
@@ -509,7 +511,7 @@
     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());
@@ -535,7 +537,7 @@
 
     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());
@@ -547,7 +549,7 @@
     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());
@@ -563,7 +565,7 @@
     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());
@@ -582,7 +584,7 @@
 
     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());
@@ -596,7 +598,7 @@
 
     // 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());
@@ -612,7 +614,7 @@
     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());
@@ -640,7 +642,7 @@
 
     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());
@@ -659,7 +661,7 @@
 
     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());
@@ -673,7 +675,7 @@
 
     // 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());
@@ -686,7 +688,7 @@
 
     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());
@@ -698,7 +700,7 @@
     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());
@@ -711,7 +713,7 @@
 
     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());
@@ -723,7 +725,7 @@
     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());
@@ -742,7 +744,7 @@
 
     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());
@@ -754,7 +756,7 @@
     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());
@@ -780,13 +782,13 @@
 
     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());
+    rit = msg.beginSection(Message::SECTION_AUTHORITY);
     rrset = *rit;
     EXPECT_EQ(Name("example.com"), rrset->getName());
     EXPECT_EQ(RRType::NS(), rrset->getType());
@@ -808,7 +810,7 @@
                           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());
@@ -820,7 +822,7 @@
     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());
@@ -839,13 +841,13 @@
 
     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());
+    rit = msg.beginSection(Message::SECTION_AUTHORITY);
     rrset = *rit;
     EXPECT_EQ(Name("example.com"), rrset->getName());
     EXPECT_EQ(RRType::NS(), rrset->getType());
@@ -870,7 +872,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.
@@ -881,7 +883,7 @@
 
     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());
@@ -895,7 +897,7 @@
     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());
@@ -912,6 +914,24 @@
 TEST_F(DataSrcTest, RootDSQuery) {
     EXPECT_NO_THROW(createAndProcessQuery(Name("."), RRClass::IN(),
                                           RRType::DS()));
+    headerCheck(msg, Rcode::REFUSED(), true, false, true, 0, 0, 0);
+}
+
+TEST_F(DataSrcTest, DSQueryFromCache) {
+    // explicitly enable hot spot cache
+    cache.setEnabled(true);
+
+    // The first query will create a negative cache for example.org/CNAME
+    createAndProcessQuery(Name("example.org"), RRClass::IN(), RRType::SOA());
+
+    // the cached CNAME shouldn't confuse subsequent query.
+    // there may be several different possible cases that could trigger a bug,
+    // but DS query is the only known example.
+    msg.clear(Message::PARSE);
+    createAndProcessQuery(Name("example.org"), RRClass::IN(), RRType::DS());
+
+    // returning refused is probably a bad behavior, but it's a different
+    // issue -- see Trac Ticket #306.
     headerCheck(msg, Rcode::REFUSED(), true, false, true, 0, 0, 0);
 }
 
@@ -922,7 +942,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: experiments/327-sync/src/lib/datasrc/tests/query_unittest.cc
==============================================================================
--- experiments/327-sync/src/lib/datasrc/tests/query_unittest.cc (original)
+++ experiments/327-sync/src/lib/datasrc/tests/query_unittest.cc Tue Nov  9 10:38:17 2010
@@ -19,6 +19,7 @@
 #include <dns/buffer.h>
 #include <dns/message.h>
 #include <dns/name.h>
+#include <dns/opcode.h>
 #include <dns/rrtype.h>
 #include <dns/rrclass.h>
 
@@ -37,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: experiments/327-sync/src/lib/datasrc/tests/run_unittests.cc
==============================================================================
--- experiments/327-sync/src/lib/datasrc/tests/run_unittests.cc (original)
+++ experiments/327-sync/src/lib/datasrc/tests/run_unittests.cc Tue Nov  9 10:38:17 2010
@@ -19,8 +19,7 @@
 #include <dns/tests/unittest_util.h>
 
 int
-main(int argc, char* argv[])
-{
+main(int argc, char* argv[]) {
     ::testing::InitGoogleTest(&argc, argv);
     isc::UnitTestUtil::addDataPath(TEST_DATA_DIR);
 

Modified: experiments/327-sync/src/lib/dns/Makefile.am
==============================================================================
--- experiments/327-sync/src/lib/dns/Makefile.am (original)
+++ experiments/327-sync/src/lib/dns/Makefile.am Tue Nov  9 10:38:17 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
@@ -63,11 +64,14 @@
 libdns___la_SOURCES += util/base16_from_binary.h util/binary_from_base16.h
 libdns___la_SOURCES += buffer.h
 libdns___la_SOURCES += dnssectime.h dnssectime.cc
+libdns___la_SOURCES += edns.h edns.cc
 libdns___la_SOURCES += exceptions.h exceptions.cc
 libdns___la_SOURCES += util/hex.h
 libdns___la_SOURCES += message.h message.cc
 libdns___la_SOURCES += messagerenderer.h messagerenderer.cc
 libdns___la_SOURCES += name.h name.cc
+libdns___la_SOURCES += opcode.h opcode.cc
+libdns___la_SOURCES += rcode.h rcode.cc
 libdns___la_SOURCES += rdata.h rdata.cc
 libdns___la_SOURCES += rrclass.cc
 libdns___la_SOURCES += rrparamregistry.h
@@ -88,8 +92,8 @@
 rrclass.h rrtype.h rrparamregistry.cc rdataclass.h rdataclass.cc: Makefile
 	./gen-rdatacode.py
 
-libdns++_includedir = $(includedir)/dns
-libdns++_include_HEADERS = \
+libdns___includedir = $(includedir)/dns
+libdns___include_HEADERS = \
 	buffer.h \
 	dnssectime.h \
 	exceptions.h \

Modified: experiments/327-sync/src/lib/dns/exceptions.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/exceptions.cc (original)
+++ experiments/327-sync/src/lib/dns/exceptions.cc Tue Nov  9 10:38:17 2010
@@ -15,7 +15,7 @@
 // $Id$
 
 #include <dns/exceptions.h>
-#include <dns/message.h>
+#include <dns/rcode.h>
 
 namespace isc {
 namespace dns {

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

Modified: experiments/327-sync/src/lib/dns/message.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/message.cc (original)
+++ experiments/327-sync/src/lib/dns/message.cc Tue Nov  9 10:38:17 2010
@@ -28,10 +28,13 @@
 #include <exceptions/exceptions.h>
 
 #include <dns/buffer.h>
+#include <dns/edns.h>
 #include <dns/exceptions.h>
 #include <dns/message.h>
 #include <dns/messagerenderer.h>
 #include <dns/name.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
 #include <dns/question.h>
 #include <dns/rdataclass.h>
 #include <dns/rrclass.h>
@@ -41,118 +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;
-
-//
-// EDNS related constants
-//
-const flags_t EXTFLAG_MASK = 0xffff;
-const flags_t EXTFLAG_DO = 0x8000;
-const uint32_t EXTRCODE_MASK = 0xff000000; 
-const uint32_t EDNSVERSION_MASK = 0x00ff0000;
 
 const unsigned int OPCODE_MASK = 0x7800;
 const unsigned int OPCODE_SHIFT = 11;
 const unsigned int RCODE_MASK = 0x000f;
-const unsigned int FLAG_MASK = 0x8ff0;
-
-const unsigned int MESSAGE_REPLYPRESERVE = (FLAG_RD | FLAG_CD);
-
-const Rcode rcodes[] = {
-    Rcode::NOERROR(),
-    Rcode::FORMERR(),
-    Rcode::SERVFAIL(),
-    Rcode::NXDOMAIN(),
-    Rcode::NOTIMP(),
-    Rcode::REFUSED(),
-    Rcode::YXDOMAIN(),
-    Rcode::YXRRSET(),
-    Rcode::NXRRSET(),
-    Rcode::NOTAUTH(),
-    Rcode::NOTZONE(),
-    Rcode::RESERVED11(),
-    Rcode::RESERVED12(),
-    Rcode::RESERVED13(),
-    Rcode::RESERVED14(),
-    Rcode::RESERVED15(),
-    Rcode::BADVERS()
-};
-
-const char *rcodetext[] = {
-    "NOERROR",
-    "FORMERR",
-    "SERVFAIL",
-    "NXDOMAIN",
-    "NOTIMP",
-    "REFUSED",
-    "YXDOMAIN",
-    "YXRRSET",
-    "NXRRSET",
-    "NOTAUTH",
-    "NOTZONE",
-    "RESERVED11",
-    "RESERVED12",
-    "RESERVED13",
-    "RESERVED14",
-    "RESERVED15",
-    "BADVERS"
-};
-
-const Opcode* opcodes[] = {
-    &Opcode::QUERY(),
-    &Opcode::IQUERY(),
-    &Opcode::STATUS(),
-    &Opcode::RESERVED3(),
-    &Opcode::NOTIFY(),
-    &Opcode::UPDATE(),
-    &Opcode::RESERVED6(),
-    &Opcode::RESERVED7(),
-    &Opcode::RESERVED8(),
-    &Opcode::RESERVED9(),
-    &Opcode::RESERVED10(),
-    &Opcode::RESERVED11(),
-    &Opcode::RESERVED12(),
-    &Opcode::RESERVED13(),
-    &Opcode::RESERVED14(),
-    &Opcode::RESERVED15()
-};
-
-const char *opcodetext[] = {
-    "QUERY",
-    "IQUERY",
-    "STATUS",
-    "RESERVED3",
-    "NOTIFY",
-    "UPDATE",
-    "RESERVED6",
-    "RESERVED7",
-    "RESERVED8",
-    "RESERVED9",
-    "RESERVED10",
-    "RESERVED11",
-    "RESERVED12",
-    "RESERVED13",
-    "RESERVED14",
-    "RESERVED15"
-};
+
+// 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",
@@ -160,37 +87,6 @@
     "AUTHORITY",
     "ADDITIONAL"
 };
-}
-
-string
-Opcode::toText() const {
-    return (opcodetext[code_]);
-}
-
-Rcode::Rcode(uint16_t code) : code_(code) {
-    if (code_ > MAX_RCODE) {
-        isc_throw(OutOfRange, "Rcode is too large to construct");
-    }
-}
-
-string
-Rcode::toText() const {
-    if (code_ < sizeof(rcodetext) / sizeof (const char *)) {
-        return (rcodetext[code_]);
-    }
-
-    ostringstream oss;
-    oss << code_;
-    return (oss.str());
-}
-
-namespace {
-inline unsigned int
-sectionCodeToId(const Section& section) {
-    unsigned int code = section.getCode();
-    assert(code > 0);
-    return (section.getCode() - 1);
-}
 }
 
 class MessageImpl {
@@ -200,20 +96,24 @@
     // for efficiency?
     Message::Mode mode_;
     qid_t qid_;
-    Rcode rcode_;
+
+    // We want to use NULL for [op,r]code_ to mean the code being not
+    // correctly parsed or set.  We store the real code object in
+    // xxcode_placeholder_ and have xxcode_ refer to it when the object
+    // is valid.
+    const Rcode* rcode_;
+    Rcode rcode_placeholder_;
     const Opcode* opcode_;
-    flags_t flags_;
-    bool dnssec_ok_;
+    Opcode opcode_placeholder_;
+
+    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];
-    RRsetPtr remote_edns_;
-    uint16_t remote_udpsize_;
-    RRsetPtr local_edns_;
-    uint16_t udpsize_;
+    vector<RRsetPtr> rrsets_[NUM_SECTIONS];
+    ConstEDNSPtr edns_;
 
 #ifdef notyet
     // tsig/sig0: TODO
@@ -221,12 +121,16 @@
 #endif
 
     void init();
+    void setOpcode(const Opcode& opcode);
+    void setRcode(const Rcode& rcode);
     int parseQuestion(InputBuffer& buffer);
-    int parseSection(const Section& section, InputBuffer& buffer);
+    int parseSection(const Message::Section section, InputBuffer& buffer);
 };
 
 MessageImpl::MessageImpl(Message::Mode mode) :
-    mode_(mode), rcode_(Rcode::NOERROR())
+    mode_(mode),
+    rcode_placeholder_(Rcode(0)), // as a placeholder the value doesn't matter
+    opcode_placeholder_(Opcode(0)) // ditto
 {
     init();
 }
@@ -235,23 +139,31 @@
 MessageImpl::init() {
     flags_ = 0;
     qid_ = 0;
-    rcode_ = Rcode::NOERROR();  // XXX
+    rcode_ = NULL;
     opcode_ = NULL;
-    dnssec_ok_ = false;
-    remote_edns_ = RRsetPtr();
-    remote_udpsize_ = Message::DEFAULT_MAX_UDPSIZE;
-    local_edns_ = RRsetPtr();
-    udpsize_ = Message::DEFAULT_MAX_UDPSIZE;
-
-    for (int i = 0; i < SECTION_MAX; ++i) {
+    edns_ = EDNSPtr();
+
+    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
+MessageImpl::setOpcode(const Opcode& opcode) {
+    opcode_placeholder_ = opcode;
+    opcode_ = &opcode_placeholder_;
+}
+
+void
+MessageImpl::setRcode(const Rcode& rcode) {
+    rcode_placeholder_ = rcode;
+    rcode_ = &rcode_placeholder_;
 }
 
 Message::Message(Mode mode) :
@@ -263,58 +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();
-}
-
-bool
-Message::isDNSSECSupported() const {
-    return (impl_->dnssec_ok_);
-}
-
-void
-Message::setDNSSECSupported(bool on) {
-    if (impl_->mode_ != Message::RENDER) {
-        isc_throw(InvalidMessageOperation,
-                  "setDNSSECSupported performed in non-render mode");
-    }
-    impl_->dnssec_ok_ = on;
-}
-
-uint16_t
-Message::getUDPSize() const {
-    return (impl_->udpsize_);
-}
-
-void
-Message::setUDPSize(uint16_t size) {
-    if (impl_->mode_ != Message::RENDER) {
-        isc_throw(InvalidMessageOperation,
-                  "setUDPSize performed in non-render mode");
-    }
-    if (size < DEFAULT_MAX_UDPSIZE) {
-        isc_throw(InvalidMessageUDPSize,
-                  "Specified UDP message size is too small");
-    }
-    impl_->udpsize_ = size;
+    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
@@ -333,7 +218,10 @@
 
 const Rcode&
 Message::getRcode() const {
-    return (impl_->rcode_);
+    if (impl_->rcode_ == NULL) {
+        isc_throw(InvalidMessageOperation, "getRcode attempted before set");
+    }
+    return (*impl_->rcode_);
 }
 
 void
@@ -342,11 +230,14 @@
         isc_throw(InvalidMessageOperation,
                   "setRcode performed in non-render mode");
     }
-    impl_->rcode_ = rcode;
+    impl_->setRcode(rcode);
 }
 
 const Opcode&
 Message::getOpcode() const {
+    if (impl_->opcode_ == NULL) {
+        isc_throw(InvalidMessageOperation, "getOpcode attempted before set");
+    }
     return (*impl_->opcode_);
 }
 
@@ -356,39 +247,64 @@
         isc_throw(InvalidMessageOperation,
                   "setOpcode performed in non-render mode");
     }
-    impl_->opcode_ = &opcode;
+    impl_->setOpcode(opcode);
+}
+
+ConstEDNSPtr
+Message::getEDNS() const {
+    return (impl_->edns_);
+}
+
+void
+Message::setEDNS(ConstEDNSPtr edns) {
+    if (impl_->mode_ != Message::RENDER) {
+        isc_throw(InvalidMessageOperation,
+                  "setEDNS performed in non-render mode");
+    }
+    impl_->edns_ = edns;
 }
 
 unsigned int
-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);
-
         }
     }
 
@@ -403,7 +319,7 @@
     }
 
     impl_->questions_.push_back(question);
-    ++impl_->counts_[Section::QUESTION().getCode()];
+    ++impl_->counts_[SECTION_QUESTION];
 }
 
 void
@@ -441,59 +357,19 @@
 };
 }
 
-namespace {
-bool
-addEDNS(MessageImpl* mimpl, MessageRenderer& renderer) {
-    const bool is_query = ((mimpl->flags_ & MessageFlag::QR().getBit()) == 0); 
-
-    // If this is a reply, add EDNS either when the request had it, or
-    // if the Rcode is BADVERS, which is EDNS specific.
-    // XXX: this logic is tricky.  We should revisit this later.
-    if (!is_query) {
-        if (mimpl->remote_edns_ == NULL && mimpl->rcode_ != Rcode::BADVERS()) {
-            return (false);
-        }
-    } else {
-        // For queries, we add EDNS only when necessary:
-        // Local UDP size is not the default value, or
-        // DNSSEC DO bit is to be set, or
-        // Extended Rcode is to be specified.
-        if (mimpl->udpsize_ == Message::DEFAULT_MAX_UDPSIZE &&
-            !mimpl->dnssec_ok_ &&
-            mimpl->rcode_.getCode() < 0x10) {
-            return (false);
-        }
-    }
-
-    // If adding the OPT RR would exceed the size limit, don't do it.
-    // 11 = len(".") + type(2byte) + class(2byte) + TTL(4byte) + RDLEN(2byte)
-    // (RDATA is empty in this simple implementation)
-    if (renderer.getLength() + 11 > renderer.getLengthLimit()) {
-        return (false);
-    }
-
-    // Render EDNS OPT RR
-    uint32_t extrcode_flags = ((mimpl->rcode_.getCode() & 0xff0) << 24);
-    if (mimpl->dnssec_ok_) {
-        extrcode_flags |= 0x8000; // set DO bit
-    }
-    mimpl->local_edns_ = RRsetPtr(new RRset(Name::ROOT_NAME(),
-                                            RRClass(mimpl->udpsize_),
-                                            RRType::OPT(),
-                                            RRTTL(extrcode_flags)));
-    // We don't support any options in this simple implementation
-    mimpl->local_edns_->addRdata(ConstRdataPtr(new generic::OPT()));
-    mimpl->local_edns_->toWire(renderer);
-
-    return (true);
-}
-}
-
 void
 Message::toWire(MessageRenderer& renderer) {
     if (impl_->mode_ != Message::RENDER) {
         isc_throw(InvalidMessageOperation,
                   "Message rendering attempted in non render mode");
+    }
+    if (impl_->rcode_ == NULL) {
+        isc_throw(InvalidMessageOperation,
+                  "Message rendering attempted without Rcode set");
+    }
+    if (impl_->opcode_ == NULL) {
+        isc_throw(InvalidMessageOperation,
+                  "Message rendering attempted without Opcode set");
     }
 
     // reserve room for the header
@@ -507,42 +383,50 @@
     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();
     }
 
-    // Added EDNS OPT RR if necessary (we want to avoid hardcoding specialized
-    // logic, see the parser case)
-    if (!renderer.isTruncated() && addEDNS(this->impl_, renderer)) {
-        ++arcount;
-    }
-
+    // Add EDNS OPT RR if necessary.  Basically, we add it only when EDNS
+    // has been explicitly set.  However, if the RCODE would require it and
+    // no EDNS has been set we generate a temporary local EDNS and use it.
+    if (!renderer.isTruncated()) {
+        ConstEDNSPtr local_edns = impl_->edns_;
+        if (!local_edns && impl_->rcode_->getExtendedCode() != 0) {
+            local_edns = ConstEDNSPtr(new EDNS());
+        }
+        if (local_edns) {
+            arcount += local_edns->toWire(renderer,
+                                          impl_->rcode_->getExtendedCode());
+        }
+    }
+ 
     // Adjust the counter buffer.
     // XXX: these may not be equal to the number of corresponding entries
     // in rrsets_[] or questions_ if truncation occurred or an EDNS OPT RR
     // 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.
 
@@ -553,8 +437,8 @@
 
     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_->rcode_->getCode() & RCODE_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)
@@ -582,13 +466,13 @@
 
     impl_->qid_ = buffer.readUint16();
     const uint16_t codes_and_flags = buffer.readUint16();
-    impl_->opcode_ = opcodes[((codes_and_flags & OPCODE_MASK) >> OPCODE_SHIFT)];
-    impl_->rcode_ = rcodes[(codes_and_flags & RCODE_MASK)];
-    impl_->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_->setOpcode(Opcode((codes_and_flags & OPCODE_MASK) >> OPCODE_SHIFT));
+    impl_->setRcode(Rcode(codes_and_flags & RCODE_MASK));
+    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;
 }
@@ -604,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
@@ -619,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);
 
@@ -631,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;
@@ -657,17 +540,49 @@
 };
 }
 
+// Note about design decision:
+// we need some type specific processing here, including EDNS and TSIG.
+// how much we should generalize/hardcode the special logic is subject
+// to discussion.  In terms of modularity it would be ideal to introduce
+// an abstract class (say "MessageAttribute") and let other such
+// concrete notions as EDNS or TSIG inherit from it.  Then we would
+// just do:
+// message->addAttribute(rrtype, rrclass, buffer);
+// to create and attach type-specific concrete object to the message.
+//
+// A major downside of this approach is, as usual, complexity due to
+// indirection and performance penalty.  Also, it may not be so easy
+// to separate the processing logic because in many cases we'll need
+// parse context for which the message class is responsible (e.g.
+// to check the EDNS OPT RR only appears in the additional section,
+// and appears only once).
+//
+// Another point to consider is that we may not need so many special
+// types other than EDNS and TSIG (and when and if we implement it,
+// SIG(0)); newer optional attributes of the message would more likely
+// be standardized as new flags or options of EDNS.  If that's the case,
+// introducing an abstract class with all the overhead and complexity
+// may not make much sense.
+//
+// Conclusion: don't over-generalize type-specific logic for now.
+// introduce separate concrete classes, and move context-independent
+// logic to that class; processing logic dependent on parse context
+// is hardcoded here.
 int
-MessageImpl::parseSection(const Section& section, InputBuffer& buffer) {
+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");
         }
@@ -678,60 +593,35 @@
         const size_t rdlen = buffer.readUint16();
         ConstRdataPtr rdata = createRdata(rrtype, rrclass, buffer, rdlen);
 
-        // XXX: we wanted to avoid hardcoding type-specific logic here,
-        // but this would be the fastest way for a proof-of-concept
-        // implementation.  We'll revisit this part later.
         if (rrtype == RRType::OPT()) {
-            if (section != Section::ADDITIONAL()) {
+            if (section != Message::SECTION_ADDITIONAL) {
                 isc_throw(DNSMessageFORMERR,
                           "EDNS OPT RR found in an invalid section");
             }
-            if (remote_edns_ != NULL) {
+            if (edns_) {
                 isc_throw(DNSMessageFORMERR, "multiple EDNS OPT RR found");
             }
-            if (((ttl.getValue() & EDNSVERSION_MASK) >> 16) >
-                Message::EDNS_SUPPORTED_VERSION) {
-                // XXX: we should probably not reject the message yet, because
-                // it's better to let the requestor know the responder-side
-                // highest version as indicated in Section 4.6 of RFC2671.
-                // This is probably because why BIND 9 does the version check
-                // in the client code.
-                // This is a TODO item.  Right now we simply reject it.
-                const unsigned int ver =
-                    (ttl.getValue() & EDNSVERSION_MASK) >> 16;
-                isc_throw(DNSMessageBADVERS, "unsupported EDNS version: " <<
-                          ver);
+
+            uint8_t extended_rcode;
+            edns_ = ConstEDNSPtr(createEDNSFromRR(name, rrclass, rrtype, ttl,
+                                                  *rdata, extended_rcode));
+            setRcode(Rcode(rcode_->getCode(), extended_rcode));
+            continue;
+        } else {
+            vector<RRsetPtr>::iterator it =
+                find_if(rrsets_[section].begin(), rrsets_[section].end(),
+                        MatchRR(name, rrtype, rrclass));
+            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_[section].push_back(rrset);
             }
-            if (name != Name::ROOT_NAME()) {
-                isc_throw(DNSMessageFORMERR,
-                          "invalid owner name for EDNS OPT RR");
-            }
-
-            remote_edns_ = RRsetPtr(new RRset(name, rrclass, rrtype, ttl));
-            remote_edns_->addRdata(rdata);
-
-            dnssec_ok_ = (((ttl.getValue() & EXTFLAG_MASK) & EXTFLAG_DO) != 0);
-            if (rrclass.getCode() > Message::DEFAULT_MAX_UDPSIZE) {
-                udpsize_ = rrclass.getCode();
-            }
-            rcode_ = Rcode(((ttl.getValue() & EXTRCODE_MASK) >> 20) |
-                           rcode_.getCode());
-            continue;
+            ++added;
         }
-
-        vector<RRsetPtr>::iterator it =
-            find_if(rrsets_[sectionCodeToId(section)].begin(),
-                    rrsets_[sectionCodeToId(section)].end(),
-                    MatchRR(name, rrtype, rrclass));
-        if (it != rrsets_[sectionCodeToId(section)].end()) {
-            (*it)->setTTL(min((*it)->getTTL(), ttl));
-            (*it)->addRdata(rdata);
-        } else {
-            RRsetPtr rrset = RRsetPtr(new RRset(name, rrclass, rrtype, ttl)); 
-            rrset->addRdata(rdata);
-            rrsets_[sectionCodeToId(section)].push_back(rrset);
-        }
-        ++added;
     }
 
     return (added);
@@ -740,105 +630,105 @@
 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_;
 };
 }
 
 string
 Message::toText() const {
+    if (impl_->rcode_ == NULL) {
+        isc_throw(InvalidMessageOperation,
+                  "Message::toText() attempted without Rcode set");
+    }
+    if (impl_->opcode_ == NULL) {
+        isc_throw(InvalidMessageOperation,
+                  "Message::toText() attempted without Opcode set");
+    }
+
     string s;
 
     s += ";; ->>HEADER<<- opcode: " + impl_->opcode_->toText();
     // for simplicity we don't consider extended rcode (unlike BIND9)
-    s += ", status: " + impl_->rcode_.toText();
+    s += ", status: " + impl_->rcode_->toText();
     s += ", id: " + boost::lexical_cast<string>(impl_->qid_);
     s += "\n;; flags: ";
-    if (getHeaderFlag(MessageFlag::QR()))
+    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()];
-    RRsetPtr edns_rrset;
-    if (!getHeaderFlag(MessageFlag::QR()) && impl_->remote_edns_ != NULL) {
-        edns_rrset = impl_->remote_edns_;
+        lexical_cast<string>(impl_->counts_[SECTION_AUTHORITY]);
+
+    unsigned int arcount = impl_->counts_[SECTION_ADDITIONAL];
+    if (impl_->edns_ != NULL) {
         ++arcount;
     }
     s += ", ADDITIONAL: " + lexical_cast<string>(arcount) + "\n";
 
-    if (edns_rrset != NULL) {
+    if (impl_->edns_ != NULL) {
         s += "\n;; OPT PSEUDOSECTION:\n";
-        s += "; EDNS: version: ";
-        s += lexical_cast<string>(
-            (edns_rrset->getTTL().getValue() & 0x00ff0000) >> 16);
-        s += ", flags:";
-        if ((edns_rrset->getTTL().getValue() & 0x8000) != 0) {
-            s += " do";
-        }
-        const uint32_t mbz = edns_rrset->getTTL().getValue() & ~0x8000 & 0xffff;
-        if (mbz != 0) {
-            s += "; MBZ: " + lexical_cast<string>(mbz) + ", udp: ";
-        } else {
-            s += "; udp: " +
-                lexical_cast<string>(edns_rrset->getClass().getCode());
-        }
-        s += "\n";
+        s += impl_->edns_->toText();
     }
 
     if (!impl_->questions_.empty()) {
         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);
@@ -851,8 +741,7 @@
 }
 
 void
-Message::makeResponse()
-{
+Message::makeResponse() {
     if (impl_->mode_ != Message::PARSE) {
         isc_throw(InvalidMessageOperation,
                   "makeResponse() is performed in non-parse mode");
@@ -860,20 +749,16 @@
 
     impl_->mode_ = Message::RENDER;
 
-    impl_->dnssec_ok_ = false;
-    impl_->remote_udpsize_ = impl_->udpsize_;
-    impl_->local_edns_ = RRsetPtr();
-    impl_->udpsize_ = DEFAULT_MAX_UDPSIZE;
-
+    impl_->edns_ = EDNSPtr();
     impl_->flags_ &= MESSAGE_REPLYPRESERVE;
-    setHeaderFlag(MessageFlag::QR());
-
-    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;
 }
 
 ///
@@ -981,43 +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())));
-}
-
-ostream&
-operator<<(ostream& os, const Opcode& opcode) {
-    return (os << opcode.toText());
-}
-
-ostream&
-operator<<(ostream& os, const Rcode& rcode) {
-    return (os << rcode.toText());
+    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: experiments/327-sync/src/lib/dns/message.h
==============================================================================
--- experiments/327-sync/src/lib/dns/message.h (original)
+++ experiments/327-sync/src/lib/dns/message.h Tue Nov  9 10:38:17 2010
@@ -25,6 +25,7 @@
 
 #include <exceptions/exceptions.h>
 
+#include <dns/edns.h>
 #include <dns/question.h>
 #include <dns/rrset.h>
 
@@ -81,451 +82,11 @@
 class MessageRenderer;
 class Message;
 class MessageImpl;
+class Opcode;
+class Rcode;
 
 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 Opcode class objects represent standard OPCODEs
-/// of the header section of DNS messages.
-///
-/// Note: since there are only 15 possible values, it may make more sense to
-/// simply define an enum type to represent these values.
-///
-/// Constant objects are defined for standard flags.
-class Opcode {
-public:
-    uint16_t getCode() const { return (code_); }
-    bool operator==(const Opcode& other) const
-    { return (code_ == other.code_); }
-    bool operator!=(const Opcode& other) const
-    { return (code_ != other.code_); }
-    std::string toText() const;
-    static const Opcode& QUERY();
-    static const Opcode& IQUERY();
-    static const Opcode& STATUS();
-    static const Opcode& RESERVED3();
-    static const Opcode& NOTIFY();
-    static const Opcode& UPDATE();
-    static const Opcode& RESERVED6();
-    static const Opcode& RESERVED7();
-    static const Opcode& RESERVED8();
-    static const Opcode& RESERVED9();
-    static const Opcode& RESERVED10();
-    static const Opcode& RESERVED11();
-    static const Opcode& RESERVED12();
-    static const Opcode& RESERVED13();
-    static const Opcode& RESERVED14();
-    static const Opcode& RESERVED15();
-private:
-    Opcode(uint16_t code) : code_(code) {}
-    uint16_t code_;
-};
-
-inline const Opcode&
-Opcode::QUERY()
-{
-    static Opcode c(0);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::IQUERY()
-{
-    static Opcode c(1);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::STATUS()
-{
-    static Opcode c(2);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED3()
-{
-    static Opcode c(3);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::NOTIFY()
-{
-    static Opcode c(4);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::UPDATE()
-{
-    static Opcode c(5);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED6()
-{
-    static Opcode c(6);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED7()
-{
-    static Opcode c(7);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED8()
-{
-    static Opcode c(8);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED9()
-{
-    static Opcode c(9);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED10()
-{
-    static Opcode c(10);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED11()
-{
-    static Opcode c(11);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED12()
-{
-    static Opcode c(12);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED13()
-{
-    static Opcode c(13);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED14()
-{
-    static Opcode c(14);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED15()
-{
-    static Opcode c(15);
-    return (c);
-}
-
-/// \brief The \c Rcode class objects represent standard Response Codes
-/// (RCODEs) of the header section of DNS messages, and extended response
-/// codes as defined in the EDNS specification.
-///
-/// Constant objects are defined for standard flags.
-class Rcode {
-public:
-    Rcode(uint16_t code);
-    uint16_t getCode() const { return (code_); }
-    bool operator==(const Rcode& other) const { return (code_ == other.code_); }
-    bool operator!=(const Rcode& other) const { return (code_ != other.code_); }
-    std::string toText() const;
-    static const Rcode& NOERROR();
-    static const Rcode& FORMERR();
-    static const Rcode& SERVFAIL();
-    static const Rcode& NXDOMAIN();
-    static const Rcode& NOTIMP();
-    static const Rcode& REFUSED();
-    static const Rcode& YXDOMAIN();
-    static const Rcode& YXRRSET();
-    static const Rcode& NXRRSET();
-    static const Rcode& NOTAUTH();
-    static const Rcode& NOTZONE();
-    static const Rcode& RESERVED11();
-    static const Rcode& RESERVED12();
-    static const Rcode& RESERVED13();
-    static const Rcode& RESERVED14();
-    static const Rcode& RESERVED15();
-    // Extended Rcodes follow (EDNS required):
-    static const Rcode& BADVERS();
-private:
-    uint16_t code_;
-
-    // EDNS-extended RCODEs are 12-bit unsigned integers.
-    static const uint16_t MAX_RCODE = 0xfff;
-};
-
-inline const Rcode&
-Rcode::NOERROR()
-{
-    static Rcode c(0);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::FORMERR()
-{
-    static Rcode c(1);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::SERVFAIL()
-{
-    static Rcode c(2);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::NXDOMAIN()
-{
-    static Rcode c(3);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::NOTIMP()
-{
-    static Rcode c(4);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::REFUSED()
-{
-    static Rcode c(5);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::YXDOMAIN()
-{
-    static Rcode c(6);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::YXRRSET()
-{
-    static Rcode c(7);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::NXRRSET()
-{
-    static Rcode c(8);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::NOTAUTH()
-{
-    static Rcode c(9);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::NOTZONE()
-{
-    static Rcode c(10);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::RESERVED11()
-{
-    static Rcode c(11);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::RESERVED12()
-{
-    static Rcode c(12);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::RESERVED13()
-{
-    static Rcode c(13);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::RESERVED14()
-{
-    static Rcode c(14);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::RESERVED15()
-{
-    static Rcode c(15);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::BADVERS()
-{
-    static Rcode c(16);
-    return (c);
-}
-
-/// \brief The \c Section class objects represent DNS message sections such
-/// as the header, question, or answer.
-///
-/// 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.
@@ -586,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.
@@ -613,65 +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);
-
-    /// \brief Return whether the message sender indicates DNSSEC is supported.
-    /// If EDNS is included, this corresponds to the value of the DO bit.
-    /// Otherwise, DNSSEC is considered not supported.
-    bool isDNSSECSupported() const;
-
-    /// \brief Specify whether DNSSEC is supported in the message.
-    ///
-    /// Only allowed in the \c RENDER mode.
-    /// If EDNS is included in the message, the DO bit is set or cleared
-    /// according to the specified value of this method.
-    void setDNSSECSupported(bool on);
-
-    /// \brief Return the maximum buffer size of UDP messages for the sender
-    /// of the message.
-    ///
-    /// The semantics of this value is different based on the mode:
-    /// In the \c PARSE mode, it means the buffer size of the remote node;
-    /// in the \c RENDER mode, it means the buffer size of the local node.
-    ///
-    /// In either case, its value is the value of the UDP payload size field
-    /// of EDNS (when it's included) or \c DEFAULT_MAX_UDPSIZE.
-    ///
-    /// Note: this interface may be confusing and may have to be revisited.
-    uint16_t getUDPSize() const;
-
-    /// \brief Specify the maximum buffer size of UDP messages of the local
-    /// node.
-    ///
-    /// Only allowed in the \c RENDER mode.
-    /// If EDNS OPT RR is included in the message, its UDP payload size field
-    /// will be set to the specified value.
-    ///
-    /// Unless explicitly specified, \c DEFAULT_MAX_UDPSIZE will be assumed
-    /// for the maximum buffer size, regardless of whether EDNS OPT RR is
-    /// included or not.  This means if an application wants to send a message
-    /// with an EDNS OPT RR for specifying a larger UDP size, it must explicitly
-    /// specify the value using this method.
-    void setUDPSize(uint16_t size);
+    ///
+    /// 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.
@@ -680,25 +317,80 @@
     /// included).  In the \c PARSE mode, if the received message contains
     /// an EDNS OPT RR, the corresponding extended code is identified and
     /// returned.
+    ///
+    /// The message must have been properly parsed (in the case of the
+    /// \c PARSE mode) or an \c Rcode has been set (in the case of the
+    /// \c RENDER mode) beforehand.  Otherwise, an exception of class
+    /// \c InvalidMessageOperation will be thrown.
     const Rcode& getRcode() const;
 
-    /// \brief Return the Response Code of the message.
-    ///
-    /// Only allowed in the \c RENDER mode.
+    /// \brief Set the Response Code of the message.
+    ///
+    /// 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.
     void setRcode(const Rcode& rcode);
 
     /// \brief Return the OPCODE given in the header section of the message.
+    ///
+    /// The message must have been properly parsed (in the case of the
+    /// \c PARSE mode) or an \c Opcode has been set (in the case of the
+    /// \c RENDER mode) beforehand.  Otherwise, an exception of class
+    /// \c InvalidMessageOperation will be thrown.
     const Opcode& getOpcode() const;
 
     /// \brief Set the OPCODE of the header section of the message.
     ///
-    /// Only allowed in the \c RENDER mode.
+    /// 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.
+    ///
+    /// This method never throws an exception.
+    ///
+    /// \return A shared pointer to the EDNS.  This will be a null shared
+    /// pointer if the message is not associated with EDNS.
+    ConstEDNSPtr getEDNS() const;
+
+    /// \brief Set EDNS for the message.
+    ///
+    /// 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.
@@ -710,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.
@@ -729,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
@@ -738,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.
@@ -768,10 +481,19 @@
     void makeResponse();
 
     /// \brief Convert the Message to a string.
+    ///
+    /// At least \c Opcode and \c Rcode must be validly set in the \c Message
+    /// (as a result of parse in the \c PARSE mode or by explicitly setting
+    /// in the \c RENDER mode);  otherwise, an exception of
+    /// class \c InvalidMessageOperation will be thrown.
     std::string toText() const;
 
     /// \brief Render the message in wire formant into a \c MessageRenderer
     /// object.
+    ///
+    /// This \c Message must be in the \c RENDER mode and both \c Opcode and
+    /// \c Rcode must have been set beforehand; otherwise, an exception of
+    /// class \c InvalidMessageOperation will be thrown.
     void toWire(MessageRenderer& renderer);
 
     /// \brief Parse the header section of the \c Message.
@@ -789,15 +511,13 @@
     ///
     /// 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:
     MessageImpl* impl_;
 };
 
+<<<<<<< .working
 /// \brief Pointer-like type pointing to a \c Message
 ///
 /// This type is expected to be used as an argument in asynchronous
@@ -808,6 +528,8 @@
 
 std::ostream& operator<<(std::ostream& os, const Opcode& opcode);
 std::ostream& operator<<(std::ostream& os, const Rcode& rcode);
+=======
+>>>>>>> .merge-right.r3495
 std::ostream& operator<<(std::ostream& os, const Message& message);
 }
 }

Modified: experiments/327-sync/src/lib/dns/name.h
==============================================================================
--- experiments/327-sync/src/lib/dns/name.h (original)
+++ experiments/327-sync/src/lib/dns/name.h Tue Nov  9 10:38:17 2010
@@ -143,8 +143,8 @@
     ///
     /// This constructor simply initializes the object in the straightforward
     /// way.
-    explicit NameComparisonResult(int order, unsigned int nlabels,
-                                  NameRelation relation) :
+    NameComparisonResult(int order, unsigned int nlabels,
+                         NameRelation relation) :
         order_(order), nlabels_(nlabels), relation_(relation) {}
     //@}
 

Modified: experiments/327-sync/src/lib/dns/python/Makefile.am
==============================================================================
--- experiments/327-sync/src/lib/dns/python/Makefile.am (original)
+++ experiments/327-sync/src/lib/dns/python/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,26 +1,24 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
 AM_CXXFLAGS = $(B10_CXXFLAGS)
 
-#lib_LTLIBRARIES = libdns_python_name.la libdns_python_rrset.la
-#libdns_python_name_la_SOURCES = name_python.cc
-#libdns_python_name_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
-#libdns_python_name_la_LDFLAGS = $(PYTHON_LDFLAGS)
-
-#lib_LTLIBRARIES = libdns_python_name.la libdns_python_rrset.la
-pyexec_LTLIBRARIES = libdns_python.la
-libdns_python_la_SOURCES = libdns_python.cc libdns_python_common.cc
-libdns_python_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
-libdns_python_la_LDFLAGS = $(PYTHON_LDFLAGS)
+pyexec_LTLIBRARIES = pydnspp.la
+pydnspp_la_SOURCES = pydnspp.cc pydnspp_common.cc
+pydnspp_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
+pydnspp_la_LDFLAGS = $(PYTHON_LDFLAGS)
 
 # directly included from source files, so these don't have their own
 # rules
-EXTRA_DIST = libdns_python_common.h
+EXTRA_DIST = pydnspp_common.h
+EXTRA_DIST += edns_python.cc
 EXTRA_DIST += messagerenderer_python.cc
 EXTRA_DIST += message_python.cc
 EXTRA_DIST += rrclass_python.cc
 EXTRA_DIST += name_python.cc
+EXTRA_DIST += opcode_python.cc
+EXTRA_DIST += rcode_python.cc
 EXTRA_DIST += rrset_python.cc
 EXTRA_DIST += question_python.cc
 EXTRA_DIST += rrttl_python.cc
@@ -29,7 +27,7 @@
 
 # Python prefers .so, while some OSes (specifically MacOS) use a different
 # suffix for dynamic objects.  -module is necessary to work this around.
-libdns_python_la_LDFLAGS += -module
-libdns_python_la_LIBADD = $(top_builddir)/src/lib/dns/libdns++.la
-libdns_python_la_LIBADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
-libdns_python_la_LIBADD += $(PYTHON_LIB)
+pydnspp_la_LDFLAGS += -module
+pydnspp_la_LIBADD = $(top_builddir)/src/lib/dns/libdns++.la
+pydnspp_la_LIBADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
+pydnspp_la_LIBADD += $(PYTHON_LIB)

Modified: experiments/327-sync/src/lib/dns/python/README
==============================================================================
--- experiments/327-sync/src/lib/dns/python/README (original)
+++ experiments/327-sync/src/lib/dns/python/README Tue Nov  9 10:38:17 2010
@@ -1,14 +1,14 @@
 
 This is an implementation of the python wrappers for isc::dns.
 
-Currently, when compiled the module is called libdns_python. If we
+When compiled the module is called pydnspp. If we
 decide to always need it we can add a default import under
 lib/python/isc.
 
 To use it from the source tree, you must add src/lib/dns/python/.libs
 to your PYTHONPATH environment variable. Within python you can then use
-> import libdns_python
-> rrc = libdns_python.RRClass("IN")
+> import pydnspp
+> rrc = pydnspp.RRClass("IN")
 etc.
 
 Notes:
@@ -26,8 +26,8 @@
 If you have specific functionality you do need, please ask for it and we
 will add it.
 
-The 'main' module is defined in libdns_python.cc.
-There is a libdns_python_common.[cc|h] for helper functions.
+The 'main' module is defined in pydnspp.cc.
+There is a pydnspp_common.[cc|h] for helper functions.
 
 Implementation notes:
 
@@ -87,7 +87,7 @@
 
 Finally we define the function to add the class, constants, exceptions,
 and enums to the module. This function is called from the init function
-in libdns_python.cc, has the name
+in pydnspp.cc, has the name
 initModulePart_<c++ class name>, returns a boolean
 (true on success, false on failure), and takes the module as a
 PyObject*. There is a convenience function called addClassVariable to

Modified: experiments/327-sync/src/lib/dns/python/message_python.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/python/message_python.cc (original)
+++ experiments/327-sync/src/lib/dns/python/message_python.cc Tue Nov  9 10:38:17 2010
@@ -14,6 +14,7 @@
 
 // $Id$
 
+#include <exceptions/exceptions.h>
 #include <dns/message.h>
 using namespace isc::dns;
 
@@ -26,7 +27,6 @@
 static PyObject* po_InvalidMessageSection;
 static PyObject* po_InvalidMessageOperation;
 static PyObject* po_InvalidMessageUDPSize;
-static PyObject* po_DNSMessageBADVERS;
 
 //
 // Definition of the classes
@@ -36,920 +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)
-    "libdns_python.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
-//
-
-
-//
-// Opcode
-//
-class s_Opcode : public PyObject {
-public:
-    const Opcode* opcode;
-};
-
-static int Opcode_init(s_Opcode* self, PyObject* args);
-static void Opcode_destroy(s_Opcode* self);
-
-static PyObject* Opcode_getCode(s_Opcode* self);
-static PyObject* Opcode_toText(s_Opcode* self);
-static PyObject* Opcode_str(PyObject* self);
-static PyObject* Opcode_QUERY(s_Opcode* self);
-static PyObject* Opcode_IQUERY(s_Opcode* self);
-static PyObject* Opcode_STATUS(s_Opcode* self);
-static PyObject* Opcode_RESERVED3(s_Opcode* self);
-static PyObject* Opcode_NOTIFY(s_Opcode* self);
-static PyObject* Opcode_UPDATE(s_Opcode* self);
-static PyObject* Opcode_RESERVED6(s_Opcode* self);
-static PyObject* Opcode_RESERVED7(s_Opcode* self);
-static PyObject* Opcode_RESERVED8(s_Opcode* self);
-static PyObject* Opcode_RESERVED9(s_Opcode* self);
-static PyObject* Opcode_RESERVED10(s_Opcode* self);
-static PyObject* Opcode_RESERVED11(s_Opcode* self);
-static PyObject* Opcode_RESERVED12(s_Opcode* self);
-static PyObject* Opcode_RESERVED13(s_Opcode* self);
-static PyObject* Opcode_RESERVED14(s_Opcode* self);
-static PyObject* Opcode_RESERVED15(s_Opcode* self);
-static PyObject* Opcode_richcmp(s_Opcode* self, s_Opcode* other, int op);
-
-static PyMethodDef Opcode_methods[] = {
-    { "get_code", reinterpret_cast<PyCFunction>(Opcode_getCode), METH_NOARGS, "Returns the code value" },
-    { "to_text", reinterpret_cast<PyCFunction>(Opcode_toText), METH_NOARGS, "Returns the text representation" },
-    { "QUERY", reinterpret_cast<PyCFunction>(Opcode_QUERY), METH_NOARGS | METH_STATIC, "Creates a QUERY Opcode" },
-    { "IQUERY", reinterpret_cast<PyCFunction>(Opcode_IQUERY), METH_NOARGS | METH_STATIC, "Creates a IQUERY Opcode" },
-    { "STATUS", reinterpret_cast<PyCFunction>(Opcode_STATUS), METH_NOARGS | METH_STATIC, "Creates a STATUS Opcode" },
-    { "RESERVED3", reinterpret_cast<PyCFunction>(Opcode_RESERVED3), METH_NOARGS | METH_STATIC, "Creates a RESERVED3 Opcode" },
-    { "NOTIFY", reinterpret_cast<PyCFunction>(Opcode_NOTIFY), METH_NOARGS | METH_STATIC, "Creates a NOTIFY Opcode" },
-    { "UPDATE", reinterpret_cast<PyCFunction>(Opcode_UPDATE), METH_NOARGS | METH_STATIC, "Creates a UPDATE Opcode" },
-    { "RESERVED6", reinterpret_cast<PyCFunction>(Opcode_RESERVED6), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
-    { "RESERVED7", reinterpret_cast<PyCFunction>(Opcode_RESERVED7), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
-    { "RESERVED8", reinterpret_cast<PyCFunction>(Opcode_RESERVED8), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
-    { "RESERVED9", reinterpret_cast<PyCFunction>(Opcode_RESERVED9), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
-    { "RESERVED10", reinterpret_cast<PyCFunction>(Opcode_RESERVED10), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
-    { "RESERVED11", reinterpret_cast<PyCFunction>(Opcode_RESERVED11), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
-    { "RESERVED12", reinterpret_cast<PyCFunction>(Opcode_RESERVED12), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
-    { "RESERVED13", reinterpret_cast<PyCFunction>(Opcode_RESERVED13), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
-    { "RESERVED14", reinterpret_cast<PyCFunction>(Opcode_RESERVED14), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
-    { "RESERVED15", reinterpret_cast<PyCFunction>(Opcode_RESERVED15), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
-    { NULL, NULL, 0, NULL }
-};
-
-static PyTypeObject opcode_type = {
-    PyVarObject_HEAD_INIT(NULL, 0)
-    "libdns_python.Opcode",
-    sizeof(s_Opcode),                   // tp_basicsize
-    0,                                  // tp_itemsize
-    (destructor)Opcode_destroy,         // tp_dealloc
-    NULL,                               // tp_print
-    NULL,                               // tp_getattr
-    NULL,                               // tp_setattr
-    NULL,                               // tp_reserved
-    NULL,                               // tp_repr
-    NULL,                               // tp_as_number
-    NULL,                               // tp_as_sequence
-    NULL,                               // tp_as_mapping
-    NULL,                               // tp_hash 
-    NULL,                               // tp_call
-    Opcode_str,                         // tp_str
-    NULL,                               // tp_getattro
-    NULL,                               // tp_setattro
-    NULL,                               // tp_as_buffer
-    Py_TPFLAGS_DEFAULT,                 // tp_flags
-    "The Opcode class objects represent standard OPCODEs "
-    "of the header section of DNS messages.",
-    NULL,                               // tp_traverse
-    NULL,                               // tp_clear
-    (richcmpfunc)Opcode_richcmp,        // tp_richcompare
-    0,                                  // tp_weaklistoffset
-    NULL,                               // tp_iter
-    NULL,                               // tp_iternext
-    Opcode_methods,                     // tp_methods
-    NULL,                               // tp_members
-    NULL,                               // tp_getset
-    NULL,                               // tp_base
-    NULL,                               // tp_dict
-    NULL,                               // tp_descr_get
-    NULL,                               // tp_descr_set
-    0,                                  // tp_dictoffset
-    (initproc)Opcode_init,              // tp_init
-    NULL,                               // tp_alloc
-    PyType_GenericNew,                  // tp_new
-    NULL,                               // tp_free
-    NULL,                               // tp_is_gc
-    NULL,                               // tp_bases
-    NULL,                               // tp_mro
-    NULL,                               // tp_cache
-    NULL,                               // tp_subclasses
-    NULL,                               // tp_weaklist
-    NULL,                               // tp_del
-    0                                   // tp_version_tag
-};
-
-
-static int
-Opcode_init(s_Opcode* self UNUSED_PARAM, PyObject* args UNUSED_PARAM) {
-    PyErr_SetString(PyExc_NotImplementedError,
-                    "Opcode can't be built directly");
-    return (-1);
-}
-
-static void
-Opcode_destroy(s_Opcode* self) {
-    // We only use the consts from Opcode, so don't
-    // delete self->opcode here
-    self->opcode = NULL;
-    Py_TYPE(self)->tp_free(self);
-}
-
-static PyObject*
-Opcode_getCode(s_Opcode* self) {
-    return (Py_BuildValue("I", self->opcode->getCode()));
-}
-
-static PyObject*
-Opcode_toText(s_Opcode* self) {
-    return (Py_BuildValue("s", self->opcode->toText().c_str()));
-}
-
-static PyObject*
-Opcode_str(PyObject* self) {
-    // Simply call the to_text method we already defined
-    return (PyObject_CallMethod(self,
-                               const_cast<char*>("to_text"),
-                                const_cast<char*>("")));
-}
-
-static PyObject*
-Opcode_createStatic(const Opcode& opcode) {
-    s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
-    if (ret != NULL) {
-        ret->opcode = &opcode;
-    }
-    return (ret);
-}
-
-static PyObject*
-Opcode_QUERY(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::QUERY()));
-}
-
-static PyObject*
-Opcode_IQUERY(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::IQUERY()));
-}
-
-static PyObject*
-Opcode_STATUS(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::STATUS()));
-}
-
-static PyObject*
-Opcode_RESERVED3(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED3()));
-}
-
-static PyObject*
-Opcode_NOTIFY(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::NOTIFY()));
-}
-
-static PyObject*
-Opcode_UPDATE(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::UPDATE()));
-}
-
-static PyObject*
-Opcode_RESERVED6(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED6()));
-}
-
-static PyObject*
-Opcode_RESERVED7(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED7()));
-}
-
-static PyObject*
-Opcode_RESERVED8(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED8()));
-}
-
-static PyObject*
-Opcode_RESERVED9(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED9()));
-}
-
-static PyObject*
-Opcode_RESERVED10(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED10()));
-}
-
-static PyObject*
-Opcode_RESERVED11(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED11()));
-}
-
-static PyObject*
-Opcode_RESERVED12(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED12()));
-}
-
-static PyObject*
-Opcode_RESERVED13(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED13()));
-}
-
-static PyObject*
-Opcode_RESERVED14(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED14()));
-}
-
-static PyObject*
-Opcode_RESERVED15(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED15()));
-}
-
-static PyObject* 
-Opcode_richcmp(s_Opcode* self, s_Opcode* other, int op) {
-    bool c = false;
-
-    // Check for null and if the types match. If different type,
-    // simply return False
-    if (!other || (self->ob_type != other->ob_type)) {
-        Py_RETURN_FALSE;
-    }
-
-    // Only equals and not equals here, unorderable type
-    switch (op) {
-    case Py_LT:
-        PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
-        return (NULL);
-        break;
-    case Py_LE:
-        PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
-        return (NULL);
-        break;
-    case Py_EQ:
-        c = (*self->opcode == *other->opcode);
-        break;
-    case Py_NE:
-        c = (*self->opcode != *other->opcode);
-        break;
-    case Py_GT:
-        PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
-        return (NULL);
-        break;
-    case Py_GE:
-        PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
-        return (NULL);
-        break;
-    }
-    if (c)
-        Py_RETURN_TRUE;
-    else
-        Py_RETURN_FALSE;
-}
-
-//
-// End of Opcode wrapper
-//
-
-//
-// Rcode
-//
-
-// We added a helper variable static_code here
-// Since we can create Rcodes dynamically with Rcode(int), but also
-// use the static globals (Rcode::NOERROR() etc), we use this
-// variable to see if the code came from one of the latter, in which
-// case Rcode_destroy should not free it (the other option is to
-// allocate new Rcodes for every use of the static ones, but this
-// seems more efficient).
-class s_Rcode : public PyObject {
-public:
-    const Rcode* rcode;
-    bool static_code;
-};
-
-static int Rcode_init(s_Rcode* self, PyObject* args);
-static void Rcode_destroy(s_Rcode* self);
-
-static PyObject* Rcode_getCode(s_Rcode* self);
-static PyObject* Rcode_toText(s_Rcode* self);
-static PyObject* Rcode_str(PyObject* self);
-static PyObject* Rcode_NOERROR(s_Rcode* self);
-static PyObject* Rcode_FORMERR(s_Rcode* self);
-static PyObject* Rcode_SERVFAIL(s_Rcode* self);
-static PyObject* Rcode_NXDOMAIN(s_Rcode* self);
-static PyObject* Rcode_NOTIMP(s_Rcode* self);
-static PyObject* Rcode_REFUSED(s_Rcode* self);
-static PyObject* Rcode_YXDOMAIN(s_Rcode* self);
-static PyObject* Rcode_YXRRSET(s_Rcode* self);
-static PyObject* Rcode_NXRRSET(s_Rcode* self);
-static PyObject* Rcode_NOTAUTH(s_Rcode* self);
-static PyObject* Rcode_NOTZONE(s_Rcode* self);
-static PyObject* Rcode_RESERVED11(s_Rcode* self);
-static PyObject* Rcode_RESERVED12(s_Rcode* self);
-static PyObject* Rcode_RESERVED13(s_Rcode* self);
-static PyObject* Rcode_RESERVED14(s_Rcode* self);
-static PyObject* Rcode_RESERVED15(s_Rcode* self);
-static PyObject* Rcode_BADVERS(s_Rcode* self);
-static PyObject* Rcode_richcmp(s_Rcode* self, s_Rcode* other, int op);
-
-static PyMethodDef Rcode_methods[] = {
-    { "get_code", reinterpret_cast<PyCFunction>(Rcode_getCode), METH_NOARGS, "Returns the code value" },
-    { "to_text", reinterpret_cast<PyCFunction>(Rcode_toText), METH_NOARGS, "Returns the text representation" },
-    { "NOERROR", reinterpret_cast<PyCFunction>(Rcode_NOERROR), METH_NOARGS | METH_STATIC, "Creates a NOERROR Rcode" },
-    { "FORMERR", reinterpret_cast<PyCFunction>(Rcode_FORMERR), METH_NOARGS | METH_STATIC, "Creates a FORMERR Rcode" },
-    { "SERVFAIL", reinterpret_cast<PyCFunction>(Rcode_SERVFAIL), METH_NOARGS | METH_STATIC, "Creates a SERVFAIL Rcode" },
-    { "NXDOMAIN", reinterpret_cast<PyCFunction>(Rcode_NXDOMAIN), METH_NOARGS | METH_STATIC, "Creates a NXDOMAIN Rcode" },
-    { "NOTIMP", reinterpret_cast<PyCFunction>(Rcode_NOTIMP), METH_NOARGS | METH_STATIC, "Creates a NOTIMP Rcode" },
-    { "REFUSED", reinterpret_cast<PyCFunction>(Rcode_REFUSED), METH_NOARGS | METH_STATIC, "Creates a REFUSED Rcode" },
-    { "YXDOMAIN", reinterpret_cast<PyCFunction>(Rcode_YXDOMAIN), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
-    { "YXRRSET", reinterpret_cast<PyCFunction>(Rcode_YXRRSET), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
-    { "NXRRSET", reinterpret_cast<PyCFunction>(Rcode_NXRRSET), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
-    { "NOTAUTH", reinterpret_cast<PyCFunction>(Rcode_NOTAUTH), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
-    { "NOTZONE", reinterpret_cast<PyCFunction>(Rcode_NOTZONE), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
-    { "RESERVED11", reinterpret_cast<PyCFunction>(Rcode_RESERVED11), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
-    { "RESERVED12", reinterpret_cast<PyCFunction>(Rcode_RESERVED12), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
-    { "RESERVED13", reinterpret_cast<PyCFunction>(Rcode_RESERVED13), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
-    { "RESERVED14", reinterpret_cast<PyCFunction>(Rcode_RESERVED14), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
-    { "RESERVED15", reinterpret_cast<PyCFunction>(Rcode_RESERVED15), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
-    { "BADVERS", reinterpret_cast<PyCFunction>(Rcode_BADVERS), METH_NOARGS | METH_STATIC, "Creates a BADVERS Rcode" },
-    { NULL, NULL, 0, NULL }
-};
-
-static PyTypeObject rcode_type = {
-    PyVarObject_HEAD_INIT(NULL, 0)
-    "libdns_python.Rcode",
-    sizeof(s_Rcode),                    // tp_basicsize
-    0,                                  // tp_itemsize
-    (destructor)Rcode_destroy,          // tp_dealloc
-    NULL,                               // tp_print
-    NULL,                               // tp_getattr
-    NULL,                               // tp_setattr
-    NULL,                               // tp_reserved
-    NULL,                               // tp_repr
-    NULL,                               // tp_as_number
-    NULL,                               // tp_as_sequence
-    NULL,                               // tp_as_mapping
-    NULL,                               // tp_hash 
-    NULL,                               // tp_call
-    Rcode_str,                          // tp_str
-    NULL,                               // tp_getattro
-    NULL,                               // tp_setattro
-    NULL,                               // tp_as_buffer
-    Py_TPFLAGS_DEFAULT,                 // tp_flags
-    "The Rcode class objects represent standard RCODEs"
-    "of the header section of DNS messages.",
-    NULL,                               // tp_traverse
-    NULL,                               // tp_clear
-    (richcmpfunc)Rcode_richcmp,         // tp_richcompare
-    0,                                  // tp_weaklistoffset
-    NULL,                               // tp_iter
-    NULL,                               // tp_iternext
-    Rcode_methods,                      // tp_methods
-    NULL,                               // tp_members
-    NULL,                               // tp_getset
-    NULL,                               // tp_base
-    NULL,                               // tp_dict
-    NULL,                               // tp_descr_get
-    NULL,                               // tp_descr_set
-    0,                                  // tp_dictoffset
-    (initproc)Rcode_init,               // tp_init
-    NULL,                               // tp_alloc
-    PyType_GenericNew,                  // tp_new
-    NULL,                               // tp_free
-    NULL,                               // tp_is_gc
-    NULL,                               // tp_bases
-    NULL,                               // tp_mro
-    NULL,                               // tp_cache
-    NULL,                               // tp_subclasses
-    NULL,                               // tp_weaklist
-    NULL,                               // tp_del
-    0                                   // tp_version_tag
-};
-
-
-static int
-Rcode_init(s_Rcode* self UNUSED_PARAM, PyObject* args UNUSED_PARAM) {
-    uint16_t code = 0;
-    if (PyArg_ParseTuple(args, "h", &code)) {
-        try {
-            self->rcode = new Rcode(code);
-            self->static_code = false;
-        } catch (const isc::OutOfRange&) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "rcode out of range");
-            return (-1);
-        }
-        return (0);
-    } else {
-        return (-1);
-    }
-}
-
-static void
-Rcode_destroy(s_Rcode* self) {
-    // Depending on whether we created the rcode or are referring
-    // to a global static one, we do or do not delete self->rcode here
-    if (!self->static_code) {
-        delete self->rcode;
-    }
-    self->rcode = NULL;
-    Py_TYPE(self)->tp_free(self);
-}
-
-static PyObject*
-Rcode_getCode(s_Rcode* self) {
-    return (Py_BuildValue("I", self->rcode->getCode()));
-}
-
-static PyObject*
-Rcode_toText(s_Rcode* self) {
-    return (Py_BuildValue("s", self->rcode->toText().c_str()));
-}
-
-static PyObject*
-Rcode_str(PyObject* self) {
-    // Simply call the to_text method we already defined
-    return (PyObject_CallMethod(self,
-                               const_cast<char*>("to_text"),
-                                const_cast<char*>("")));
-}
-
-static PyObject*
-Rcode_createStatic(const Rcode& rcode) {
-    s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
-    if (ret != NULL) {
-        ret->rcode = &rcode;
-        ret->static_code = true;
-    }
-    return (ret);
-}
-
-static PyObject*
-Rcode_NOERROR(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::NOERROR()));
-}
-
-static PyObject*
-Rcode_FORMERR(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::FORMERR()));
-}
-
-static PyObject*
-Rcode_SERVFAIL(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::SERVFAIL()));
-}
-
-static PyObject*
-Rcode_NXDOMAIN(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::NXDOMAIN()));
-}
-
-static PyObject*
-Rcode_NOTIMP(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::NOTIMP()));
-}
-
-static PyObject*
-Rcode_REFUSED(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::REFUSED()));
-}
-
-static PyObject*
-Rcode_YXDOMAIN(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::YXDOMAIN()));
-}
-
-static PyObject*
-Rcode_YXRRSET(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::YXRRSET()));
-}
-
-static PyObject*
-Rcode_NXRRSET(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::NXRRSET()));
-}
-
-static PyObject*
-Rcode_NOTAUTH(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::NOTAUTH()));
-}
-
-static PyObject*
-Rcode_NOTZONE(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::NOTZONE()));
-}
-
-static PyObject*
-Rcode_RESERVED11(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::RESERVED11()));
-}
-
-static PyObject*
-Rcode_RESERVED12(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::RESERVED12()));
-}
-
-static PyObject*
-Rcode_RESERVED13(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::RESERVED13()));
-}
-
-static PyObject*
-Rcode_RESERVED14(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::RESERVED14()));
-}
-
-static PyObject*
-Rcode_RESERVED15(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::RESERVED15()));
-}
-
-static PyObject*
-Rcode_BADVERS(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::BADVERS()));
-}
-
-static PyObject* 
-Rcode_richcmp(s_Rcode* self, s_Rcode* other, int op) {
-    bool c = false;
-
-    // Check for null and if the types match. If different type,
-    // simply return False
-    if (!other || (self->ob_type != other->ob_type)) {
-        Py_RETURN_FALSE;
-    }
-
-    // Only equals and not equals here, unorderable type
-    switch (op) {
-    case Py_LT:
-        PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
-        return (NULL);
-        break;
-    case Py_LE:
-        PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
-        return (NULL);
-        break;
-    case Py_EQ:
-        c = (*self->rcode == *other->rcode);
-        break;
-    case Py_NE:
-        c = (*self->rcode != *other->rcode);
-        break;
-    case Py_GT:
-        PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
-        return (NULL);
-        break;
-    case Py_GE:
-        PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
-        return (NULL);
-        break;
-    }
-    if (c)
-        Py_RETURN_TRUE;
-    else
-        Py_RETURN_FALSE;
-}
-
-//
-// End of Rcode wrapper
-//
-
-
 //
 // Section
 //
-
-// 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)
-    "libdns_python.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
@@ -972,17 +61,14 @@
 
 static PyObject* Message_getHeaderFlag(s_Message* self, PyObject* args);
 static PyObject* Message_setHeaderFlag(s_Message* self, PyObject* args);
-static PyObject* Message_clearHeaderFlag(s_Message* self, PyObject* args);
-static PyObject* Message_isDNSSECSupported(s_Message* self);
-static PyObject* Message_setDNSSECSupported(s_Message* self, PyObject* args);
-static PyObject* Message_getUDPSize(s_Message* self);
-static PyObject* Message_setUDPSize(s_Message* self, PyObject* args);
 static PyObject* Message_getQid(s_Message* self);
 static PyObject* Message_setQid(s_Message* self, PyObject* args);
 static PyObject* Message_getRcode(s_Message* self);
 static PyObject* Message_setRcode(s_Message* self, PyObject* args);
 static PyObject* Message_getOpcode(s_Message* self);
 static PyObject* Message_setOpcode(s_Message* self, PyObject* args);
+static PyObject* Message_getEDNS(s_Message* self);
+static PyObject* Message_setEDNS(s_Message* self, PyObject* args);
 static PyObject* Message_getRRCount(s_Message* self, PyObject* args);
 // use direct iterators for these? (or simply lists for now?)
 static PyObject* Message_getQuestion(s_Message* self);
@@ -1008,46 +94,15 @@
 // 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." },
-    { "is_dnssec_supported", reinterpret_cast<PyCFunction>(Message_isDNSSECSupported), METH_NOARGS,
-      "Returns True if the message sender indicates DNSSEC is supported. "
-      "If EDNS is included, this corresponds to the value of the DO bit. "
-      "Otherwise, DNSSEC is considered not supported." },
-    { "set_dnssec_supported", reinterpret_cast<PyCFunction>(Message_setDNSSECSupported), METH_VARARGS,
-      "Specify whether DNSSEC is supported in the message. "
-      "The message must be in RENDER mode. If not, an "
-      "InvalidMessageOperation is raised."
-      "If EDNS is included in the message, the DO bit is set or cleared "
-      "according to given argument (True or False) of this method."},
-    { "get_udp_size", reinterpret_cast<PyCFunction>(Message_getUDPSize), METH_NOARGS,
-      "Return the maximum buffer size of UDP messages for the sender "
-      "of the message.\n\n"
-      "The semantics of this value is different based on the mode:\n"
-      "In the PARSE mode, it means the buffer size of the remote node;\n"
-      "in the RENDER mode, it means the buffer size of the local node.\n\n"
-      "In either case, its value is the value of the UDP payload size field "
-      "of EDNS (when it's included) or DEFAULT_MAX_UDPSIZE." },
-    { "set_udp_size", reinterpret_cast<PyCFunction>(Message_setUDPSize), METH_VARARGS,
-      "Specify the maximum buffer size of UDP messages of the local "
-      "node. If the message is not in RENDER mode, an "
-      "InvalidMessageOperation is raised.\n\n"
-      "If EDNS OPT RR is included in the message, its UDP payload size field "
-      "will be set to the specified value.\n"
-      "Unless explicitly specified, DEFAULT_MAX_UDPSIZE will be assumed "
-      "for the maximum buffer size, regardless of whether EDNS OPT RR is "
-      "included or not.  This means if an application wants to send a message "
-      "with an EDNS OPT RR for specifying a larger UDP size, it must explicitly "
-      "specify the value using this method. "},
     { "get_qid", reinterpret_cast<PyCFunction>(Message_getQid), METH_NOARGS,
       "Returns the query id" },
     { "set_qid", reinterpret_cast<PyCFunction>(Message_setQid), METH_VARARGS,
@@ -1066,6 +121,12 @@
       "Sets the message opcode (an Opcode object).\n"
       "If the message is not in RENDER mode, an "
       "InvalidMessageOperation is raised."},
+    { "get_edns", reinterpret_cast<PyCFunction>(Message_getEDNS), METH_NOARGS,
+      "Return, if any, the EDNS associated with the message."
+    },
+    { "set_edns", reinterpret_cast<PyCFunction>(Message_setEDNS), METH_VARARGS,
+      "Set EDNS for the message."
+    },
     { "get_rr_count", reinterpret_cast<PyCFunction>(Message_getRRCount), METH_VARARGS,
       "Returns the number of RRs contained in the given section." },
     { "get_question", reinterpret_cast<PyCFunction>(Message_getQuestion), METH_NOARGS,
@@ -1117,7 +178,7 @@
 // Most of the functions are not actually implemented and NULL here.
 static PyTypeObject message_type = {
     PyVarObject_HEAD_INIT(NULL, 0)
-    "libdns_python.Message",
+    "pydnspp.Message",
     sizeof(s_Message),                  // tp_basicsize
     0,                                  // tp_itemsize
     (destructor)Message_destroy,        // tp_dealloc
@@ -1168,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();
@@ -1199,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;
@@ -1213,87 +276,31 @@
 
 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;
-}
-
-static PyObject*
-Message_isDNSSECSupported(s_Message* self) {
-    if (self->message->isDNSSECSupported()) {
-        Py_RETURN_TRUE;
-    } else {
-        Py_RETURN_FALSE;
-    }
-}
-
-static PyObject*
-Message_setDNSSECSupported(s_Message* self, PyObject* args) {
-    PyObject *b;
-    if (!PyArg_ParseTuple(args, "O!", &PyBool_Type, &b)) {
-        return (NULL);
-    }
-    try {
-        if (b == Py_True) {
-            self->message->setDNSSECSupported(true);
-        } else {
-            self->message->setDNSSECSupported(false);
-        }
-        Py_RETURN_NONE;
-    } catch (const InvalidMessageOperation& imo) {
-        PyErr_SetString(po_InvalidMessageOperation, imo.what());
-        return (NULL);
-    }
-}
-
-static PyObject*
-Message_getUDPSize(s_Message* self) {
-    return (Py_BuildValue("I", self->message->getUDPSize()));
-}
-
-static PyObject*
-Message_setUDPSize(s_Message* self, PyObject* args) {
-    uint16_t size;
-    if (!PyArg_ParseTuple(args, "H", &size)) {
-        return (NULL);
-    }
-    try {
-        self->message->setUDPSize(size);
-        Py_RETURN_NONE;
-    } catch (const InvalidMessageUDPSize& imus) {
-        PyErr_SetString(po_InvalidMessageUDPSize, imus.what());
-        return (NULL);
-    } catch (const InvalidMessageOperation& imo) {
-        PyErr_SetString(po_InvalidMessageOperation, imo.what());
+    } catch (const isc::InvalidParameter& ip) {
+        PyErr_Clear();
+        PyErr_SetString(po_InvalidParameter, ip.what());
         return (NULL);
     }
 }
@@ -1324,12 +331,18 @@
 
     rcode = static_cast<s_Rcode*>(rcode_type.tp_alloc(&rcode_type, 0));
     if (rcode != NULL) {
-        rcode->rcode = new Rcode(self->message->getRcode());
-        if (rcode->rcode == NULL)
-          {
+        rcode->rcode = NULL;
+        try {
+            rcode->rcode = new Rcode(self->message->getRcode());
+        } catch (const InvalidMessageOperation& imo) {
+            PyErr_SetString(po_InvalidMessageOperation, imo.what());
+        } catch (...) {
+            PyErr_SetString(po_IscException, "Unexpected exception");
+        }
+        if (rcode->rcode == NULL) {
             Py_DECREF(rcode);
             return (NULL);
-          }
+        }
     }
 
     return (rcode);
@@ -1356,15 +369,18 @@
 
     opcode = static_cast<s_Opcode*>(opcode_type.tp_alloc(&opcode_type, 0));
     if (opcode != NULL) {
-        // Note that we do not new and delete for opcodes.
-        // all rcodes point to the statics defined in
-        // message.cc
-        opcode->opcode = &self->message->getOpcode();
-        if (opcode->opcode == NULL)
-          {
+        opcode->opcode = NULL;
+        try {
+            opcode->opcode = new Opcode(self->message->getOpcode());
+        } catch (const InvalidMessageOperation& imo) {
+            PyErr_SetString(po_InvalidMessageOperation, imo.what());
+        } catch (...) {
+            PyErr_SetString(po_IscException, "Unexpected exception");
+        }
+        if (opcode->opcode == NULL) {
             Py_DECREF(opcode);
             return (NULL);
-          }
+        }
     }
 
     return (opcode);
@@ -1386,59 +402,143 @@
 }
 
 static PyObject*
+Message_getEDNS(s_Message* self) {
+    s_EDNS* edns;
+    EDNS* edns_body;
+    ConstEDNSPtr src = self->message->getEDNS();
+
+    if (!src) {
+        Py_RETURN_NONE;
+    }
+    if ((edns_body = new(nothrow) EDNS(*src)) == NULL) {
+        return (PyErr_NoMemory());
+    }
+    edns = static_cast<s_EDNS*>(opcode_type.tp_alloc(&edns_type, 0));
+    if (edns != NULL) {
+        edns->edns = edns_body;
+    }
+
+    return (edns);
+}
+
+static PyObject*
+Message_setEDNS(s_Message* self, PyObject* args) {
+    s_EDNS* edns;
+    if (!PyArg_ParseTuple(args, "O!", &edns_type, &edns)) {
+        return (NULL);
+    }
+    try {
+        self->message->setEDNS(EDNSPtr(new EDNS(*edns->edns)));
+        Py_RETURN_NONE;
+    } catch (const InvalidMessageOperation& imo) {
+        PyErr_SetString(po_InvalidMessageOperation, imo.what());
+        return (NULL);
+    }
+}
+
+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);
@@ -1467,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) {
@@ -1503,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 {
@@ -1520,7 +621,16 @@
 static PyObject*
 Message_toText(s_Message* self) {
     // Py_BuildValue makes python objects from native data
-    return (Py_BuildValue("s", self->message->toText().c_str()));
+    try {
+        return (Py_BuildValue("s", self->message->toText().c_str()));
+    } catch (const InvalidMessageOperation& imo) {
+        PyErr_Clear();
+        PyErr_SetString(po_InvalidMessageOperation, imo.what());
+        return (NULL);
+    } catch (...) {
+        PyErr_SetString(po_IscException, "Unexpected exception");
+        return (NULL);
+    }
 }
 
 static PyObject*
@@ -1535,7 +645,7 @@
 Message_toWire(s_Message* self, PyObject* args) {
     s_MessageRenderer* mr;
     
-    if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+    if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
         try {
             self->message->toWire(*mr->messagerenderer);
             // If we return NULL it is seen as an error, so use this for
@@ -1583,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("libdns_python.MessageTooShort", NULL, NULL);
+    po_MessageTooShort = PyErr_NewException("pydnspp.MessageTooShort", NULL,
+                                            NULL);
     PyModule_AddObject(mod, "MessageTooShort", po_MessageTooShort);
-    po_InvalidMessageSection = PyErr_NewException("libdns_python.InvalidMessageSection", NULL, NULL);
+    po_InvalidMessageSection =
+        PyErr_NewException("pydnspp.InvalidMessageSection", NULL, NULL);
     PyModule_AddObject(mod, "InvalidMessageSection", po_InvalidMessageSection);
-    po_InvalidMessageOperation = PyErr_NewException("libdns_python.InvalidMessageOperation", NULL, NULL);
-    PyModule_AddObject(mod, "InvalidMessageOperation", po_InvalidMessageOperation);
-    po_InvalidMessageUDPSize = PyErr_NewException("libdns_python.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("libdns_python.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: experiments/327-sync/src/lib/dns/python/messagerenderer_python.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/python/messagerenderer_python.cc (original)
+++ experiments/327-sync/src/lib/dns/python/messagerenderer_python.cc Tue Nov  9 10:38:17 2010
@@ -42,7 +42,7 @@
 // TODO: set/get compressmode
 static PyObject* MessageRenderer_setTruncated(s_MessageRenderer* self);
 static PyObject* MessageRenderer_setLengthLimit(s_MessageRenderer* self, PyObject* args);
-
+static PyObject* MessageRenderer_clear(s_MessageRenderer* self);
 
 static PyMethodDef MessageRenderer_methods[] = {
     { "get_data", reinterpret_cast<PyCFunction>(MessageRenderer_getData), METH_NOARGS,
@@ -57,12 +57,15 @@
       "Sets truncated to true" },
     { "set_length_limit", reinterpret_cast<PyCFunction>(MessageRenderer_setLengthLimit), METH_VARARGS,
       "Sets the length limit of the data to the given number" },
+    { "clear", reinterpret_cast<PyCFunction>(MessageRenderer_clear),
+      METH_NOARGS,
+      "Clear the internal buffer and other internal resources." },
     { NULL, NULL, 0, NULL }
 };
 
 static PyTypeObject messagerenderer_type = {
     PyVarObject_HEAD_INIT(NULL, 0)
-    "libdns_python.MessageRenderer",
+    "pydnspp.MessageRenderer",
     sizeof(s_MessageRenderer),          // tp_basicsize
     0,                                  // tp_itemsize
     (destructor)MessageRenderer_destroy,// tp_dealloc
@@ -175,6 +178,12 @@
     Py_RETURN_NONE;
 }
 
+static PyObject*
+MessageRenderer_clear(s_MessageRenderer* self) {
+    self->messagerenderer->clear();
+    Py_RETURN_NONE;
+}
+
 // end of MessageRenderer
 
 

Modified: experiments/327-sync/src/lib/dns/python/name_python.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/python/name_python.cc (original)
+++ experiments/327-sync/src/lib/dns/python/name_python.cc Tue Nov  9 10:38:17 2010
@@ -68,7 +68,7 @@
 
 static PyTypeObject name_comparison_result_type = {
     PyVarObject_HEAD_INIT(NULL, 0)
-    "libdns_python.NameComparisonResult",
+    "pydnspp.NameComparisonResult",
     sizeof(s_NameComparisonResult),           // tp_basicsize
     0,                                        // tp_itemsize
     (destructor)NameComparisonResult_destroy, // tp_dealloc
@@ -222,7 +222,7 @@
 
 static PyTypeObject name_type = {
     PyVarObject_HEAD_INIT(NULL, 0)
-    "libdns_python.Name",
+    "pydnspp.Name",
     sizeof(s_Name),                     // tp_basicsize
     0,                                  // tp_itemsize
     (destructor)Name_destroy,           // tp_dealloc
@@ -421,7 +421,7 @@
         // to prevent memory leak
         Py_DECREF(name_bytes);
         return (result);
-    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
         self->name->toWire(*mr->messagerenderer);
         // If we return NULL it is seen as an error, so use this for
         // None returns
@@ -437,7 +437,7 @@
 Name_compare(s_Name* self, PyObject* args) {
     s_Name* other;
 
-    if (!PyArg_ParseTuple(args, "O!", &name_type, (PyObject* *) &other))
+    if (!PyArg_ParseTuple(args, "O!", &name_type, &other))
         return (NULL);
 
     s_NameComparisonResult* ret = PyObject_New(s_NameComparisonResult, &name_comparison_result_type);
@@ -452,7 +452,7 @@
 Name_equals(s_Name* self, PyObject* args) {
     s_Name* other;
 
-    if (!PyArg_ParseTuple(args, "O!", &name_type, (PyObject* *) &other))
+    if (!PyArg_ParseTuple(args, "O!", &name_type, &other))
         return (NULL);
 
     if (self->name->equals(*other->name))
@@ -565,7 +565,7 @@
 Name_concatenate(s_Name* self, PyObject* args) {
     s_Name* other;
 
-    if (!PyArg_ParseTuple(args, "O!", &name_type, (PyObject**) &other))
+    if (!PyArg_ParseTuple(args, "O!", &name_type, &other))
         return (NULL);
 
     s_Name* ret = PyObject_New(s_Name, &name_type);
@@ -651,30 +651,30 @@
     
 
     // Add the exceptions to the module
-    po_EmptyLabel = PyErr_NewException("libdns_python.EmptyLabel", NULL, NULL);
+    po_EmptyLabel = PyErr_NewException("pydnspp.EmptyLabel", NULL, NULL);
     PyModule_AddObject(mod, "EmptyLabel", po_EmptyLabel);
 
-    po_TooLongName = PyErr_NewException("libdns_python.TooLongName", NULL, NULL);
+    po_TooLongName = PyErr_NewException("pydnspp.TooLongName", NULL, NULL);
     PyModule_AddObject(mod, "TooLongName", po_TooLongName);
 
-    po_TooLongLabel = PyErr_NewException("libdns_python.TooLongLabel", NULL, NULL);
+    po_TooLongLabel = PyErr_NewException("pydnspp.TooLongLabel", NULL, NULL);
     PyModule_AddObject(mod, "TooLongLabel", po_TooLongLabel);
 
-    po_BadLabelType = PyErr_NewException("libdns_python.BadLabelType", NULL, NULL);
+    po_BadLabelType = PyErr_NewException("pydnspp.BadLabelType", NULL, NULL);
     PyModule_AddObject(mod, "BadLabelType", po_BadLabelType);
 
-    po_BadEscape = PyErr_NewException("libdns_python.BadEscape", NULL, NULL);
+    po_BadEscape = PyErr_NewException("pydnspp.BadEscape", NULL, NULL);
     PyModule_AddObject(mod, "BadEscape", po_BadEscape);
 
-    po_IncompleteName = PyErr_NewException("libdns_python.IncompleteName", NULL, NULL);
+    po_IncompleteName = PyErr_NewException("pydnspp.IncompleteName", NULL, NULL);
     PyModule_AddObject(mod, "IncompleteName", po_IncompleteName);
 
-    po_InvalidBufferPosition = PyErr_NewException("libdns_python.InvalidBufferPosition", NULL, NULL);
+    po_InvalidBufferPosition = PyErr_NewException("pydnspp.InvalidBufferPosition", NULL, NULL);
     PyModule_AddObject(mod, "InvalidBufferPosition", po_InvalidBufferPosition);
 
     // This one could have gone into the message_python.cc file, but is
     // already needed here.
-    po_DNSMessageFORMERR = PyErr_NewException("libdns_python.DNSMessageFORMERR", NULL, NULL);
+    po_DNSMessageFORMERR = PyErr_NewException("pydnspp.DNSMessageFORMERR", NULL, NULL);
     PyModule_AddObject(mod, "DNSMessageFORMERR", po_DNSMessageFORMERR);
 
     return (true);

Modified: experiments/327-sync/src/lib/dns/python/question_python.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/python/question_python.cc (original)
+++ experiments/327-sync/src/lib/dns/python/question_python.cc Tue Nov  9 10:38:17 2010
@@ -76,7 +76,7 @@
 // Most of the functions are not actually implemented and NULL here.
 static PyTypeObject question_type = {
     PyVarObject_HEAD_INIT(NULL, 0)
-    "libdns_python.Question",
+    "pydnspp.Question",
     sizeof(s_Question),                 // tp_basicsize
     0,                                  // tp_itemsize
     (destructor)Question_destroy,       // tp_dealloc
@@ -254,8 +254,7 @@
         // to prevent memory leak
         Py_DECREF(n);
         return (result);
-    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type,
-                                reinterpret_cast<PyObject**>(&mr))) {
+    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
         self->question->toWire(*mr->messagerenderer);
         // If we return NULL it is seen as an error, so use this for
         // None returns

Modified: experiments/327-sync/src/lib/dns/python/rdata_python.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/python/rdata_python.cc (original)
+++ experiments/327-sync/src/lib/dns/python/rdata_python.cc Tue Nov  9 10:38:17 2010
@@ -92,7 +92,7 @@
 // Most of the functions are not actually implemented and NULL here.
 static PyTypeObject rdata_type = {
     PyVarObject_HEAD_INIT(NULL, 0)
-    "libdns_python.Rdata",
+    "pydnspp.Rdata",
     sizeof(s_Rdata),                    // tp_basicsize
     0,                                  // tp_itemsize
     (destructor)Rdata_destroy,          // tp_dealloc
@@ -146,11 +146,20 @@
     s_RRType* rrtype;
     s_RRClass* rrclass;
     const char* s;
-    
+    const char* data;
+    Py_ssize_t len;
+
+    // Create from string
     if (PyArg_ParseTuple(args, "O!O!s", &rrtype_type, &rrtype,
                                         &rrclass_type, &rrclass,
                                         &s)) {
         self->rdata = createRdata(*rrtype->rrtype, *rrclass->rrclass, s);
+        return (0);
+    } else if (PyArg_ParseTuple(args, "O!O!y#", &rrtype_type, &rrtype,
+                                &rrclass_type, &rrclass, &data, &len)) {
+        InputBuffer input_buffer(data, len);
+        self->rdata = createRdata(*rrtype->rrtype, *rrclass->rrclass,
+                                  input_buffer, len);
         return (0);
     }
 
@@ -195,7 +204,7 @@
         // to prevent memory leak
         Py_DECREF(rd_bytes);
         return (result);
-    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
         self->rdata->toWire(*mr->messagerenderer);
         // If we return NULL it is seen as an error, so use this for
         // None returns
@@ -267,13 +276,13 @@
                        reinterpret_cast<PyObject*>(&rdata_type));
 
     // Add the exceptions to the class
-    po_InvalidRdataLength = PyErr_NewException("libdns_python.InvalidRdataLength", NULL, NULL);
+    po_InvalidRdataLength = PyErr_NewException("pydnspp.InvalidRdataLength", NULL, NULL);
     PyModule_AddObject(mod, "InvalidRdataLength", po_InvalidRdataLength);
 
-    po_InvalidRdataText = PyErr_NewException("libdns_python.InvalidRdataText", NULL, NULL);
+    po_InvalidRdataText = PyErr_NewException("pydnspp.InvalidRdataText", NULL, NULL);
     PyModule_AddObject(mod, "InvalidRdataText", po_InvalidRdataText);
 
-    po_CharStringTooLong = PyErr_NewException("libdns_python.CharStringTooLong", NULL, NULL);
+    po_CharStringTooLong = PyErr_NewException("pydnspp.CharStringTooLong", NULL, NULL);
     PyModule_AddObject(mod, "CharStringTooLong", po_CharStringTooLong);
 
     

Modified: experiments/327-sync/src/lib/dns/python/rrclass_python.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/python/rrclass_python.cc (original)
+++ experiments/327-sync/src/lib/dns/python/rrclass_python.cc Tue Nov  9 10:38:17 2010
@@ -100,7 +100,7 @@
 // Most of the functions are not actually implemented and NULL here.
 static PyTypeObject rrclass_type = {
     PyVarObject_HEAD_INIT(NULL, 0)
-    "libdns_python.RRClass",
+    "pydnspp.RRClass",
     sizeof(s_RRClass),                  // tp_basicsize
     0,                                  // tp_itemsize
     (destructor)RRClass_destroy,        // tp_dealloc
@@ -236,7 +236,7 @@
         // to prevent memory leak
         Py_DECREF(n);
         return (result);
-    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
         self->rrclass->toWire(*mr->messagerenderer);
         // If we return NULL it is seen as an error, so use this for
         // None returns
@@ -332,10 +332,10 @@
 bool
 initModulePart_RRClass(PyObject* mod) {
     // Add the exceptions to the module
-    po_InvalidRRClass = PyErr_NewException("libdns_python.InvalidRRClass", NULL, NULL);
+    po_InvalidRRClass = PyErr_NewException("pydnspp.InvalidRRClass", NULL, NULL);
     Py_INCREF(po_InvalidRRClass);
     PyModule_AddObject(mod, "InvalidRRClass", po_InvalidRRClass);
-    po_IncompleteRRClass = PyErr_NewException("libdns_python.IncompleteRRClass", NULL, NULL);
+    po_IncompleteRRClass = PyErr_NewException("pydnspp.IncompleteRRClass", NULL, NULL);
     Py_INCREF(po_IncompleteRRClass);
     PyModule_AddObject(mod, "IncompleteRRClass", po_IncompleteRRClass);
 

Modified: experiments/327-sync/src/lib/dns/python/rrset_python.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/python/rrset_python.cc (original)
+++ experiments/327-sync/src/lib/dns/python/rrset_python.cc Tue Nov  9 10:38:17 2010
@@ -94,7 +94,7 @@
 
 static PyTypeObject rrset_type = {
     PyVarObject_HEAD_INIT(NULL, 0)
-    "libdns_python.RRset",
+    "pydnspp.RRset",
     sizeof(s_RRset),                    // tp_basicsize
     0,                                  // tp_itemsize
     (destructor)RRset_destroy,          // tp_dealloc
@@ -315,7 +315,7 @@
             // to prevent memory leak
             Py_DECREF(n);
             return (result);
-        } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+        } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
             self->rrset->toWire(*mr->messagerenderer);
             // If we return NULL it is seen as an error, so use this for
             // None returns
@@ -379,7 +379,7 @@
 bool
 initModulePart_RRset(PyObject* mod) {
     // Add the exceptions to the module
-    po_EmptyRRset = PyErr_NewException("libdns_python.EmptyRRset", NULL, NULL);
+    po_EmptyRRset = PyErr_NewException("pydnspp.EmptyRRset", NULL, NULL);
     PyModule_AddObject(mod, "EmptyRRset", po_EmptyRRset);
 
     // Add the enums to the module

Modified: experiments/327-sync/src/lib/dns/python/rrttl_python.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/python/rrttl_python.cc (original)
+++ experiments/327-sync/src/lib/dns/python/rrttl_python.cc Tue Nov  9 10:38:17 2010
@@ -91,7 +91,7 @@
 // Most of the functions are not actually implemented and NULL here.
 static PyTypeObject rrttl_type = {
     PyVarObject_HEAD_INIT(NULL, 0)
-    "libdns_python.RRTTL",
+    "pydnspp.RRTTL",
     sizeof(s_RRTTL),                    // tp_basicsize
     0,                                  // tp_itemsize
     (destructor)RRTTL_destroy,          // tp_dealloc
@@ -235,7 +235,7 @@
         // to prevent memory leak
         Py_DECREF(n);
         return (result);
-    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
         self->rrttl->toWire(*mr->messagerenderer);
         // If we return NULL it is seen as an error, so use this for
         // None returns
@@ -296,9 +296,9 @@
 bool
 initModulePart_RRTTL(PyObject* mod) {
     // Add the exceptions to the module
-    po_InvalidRRTTL = PyErr_NewException("libdns_python.InvalidRRTTL", NULL, NULL);
+    po_InvalidRRTTL = PyErr_NewException("pydnspp.InvalidRRTTL", NULL, NULL);
     PyModule_AddObject(mod, "InvalidRRTTL", po_InvalidRRTTL);
-    po_IncompleteRRTTL = PyErr_NewException("libdns_python.IncompleteRRTTL", NULL, NULL);
+    po_IncompleteRRTTL = PyErr_NewException("pydnspp.IncompleteRRTTL", NULL, NULL);
     PyModule_AddObject(mod, "IncompleteRRTTL", po_IncompleteRRTTL);
 
     // We initialize the static description object with PyType_Ready(),

Modified: experiments/327-sync/src/lib/dns/python/rrtype_python.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/python/rrtype_python.cc (original)
+++ experiments/327-sync/src/lib/dns/python/rrtype_python.cc Tue Nov  9 10:38:17 2010
@@ -130,7 +130,7 @@
 // Most of the functions are not actually implemented and NULL here.
 static PyTypeObject rrtype_type = {
     PyVarObject_HEAD_INIT(NULL, 0)
-    "libdns_python.RRType",
+    "pydnspp.RRType",
     sizeof(s_RRType),                   // tp_basicsize
     0,                                  // tp_itemsize
     (destructor)RRType_destroy,         // tp_dealloc
@@ -273,7 +273,7 @@
         // to prevent memory leak
         Py_DECREF(n);
         return (result);
-    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+    } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
         self->rrtype->toWire(*mr->messagerenderer);
         // If we return NULL it is seen as an error, so use this for
         // None returns
@@ -446,9 +446,9 @@
 bool
 initModulePart_RRType(PyObject* mod) {
     // Add the exceptions to the module
-    po_InvalidRRType = PyErr_NewException("libdns_python.InvalidRRType", NULL, NULL);
+    po_InvalidRRType = PyErr_NewException("pydnspp.InvalidRRType", NULL, NULL);
     PyModule_AddObject(mod, "InvalidRRType", po_InvalidRRType);
-    po_IncompleteRRType = PyErr_NewException("libdns_python.IncompleteRRType", NULL, NULL);
+    po_IncompleteRRType = PyErr_NewException("pydnspp.IncompleteRRType", NULL, NULL);
     PyModule_AddObject(mod, "IncompleteRRType", po_IncompleteRRType);
 
     // We initialize the static description object with PyType_Ready(),

Modified: experiments/327-sync/src/lib/dns/python/tests/Makefile.am
==============================================================================
--- experiments/327-sync/src/lib/dns/python/tests/Makefile.am (original)
+++ experiments/327-sync/src/lib/dns/python/tests/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,7 +1,10 @@
-PYTESTS = message_python_test.py
+PYTESTS = edns_python_test.py
+PYTESTS += message_python_test.py
 PYTESTS += messagerenderer_python_test.py
 PYTESTS += name_python_test.py
 PYTESTS += question_python_test.py
+PYTESTS += opcode_python_test.py
+PYTESTS += rcode_python_test.py
 PYTESTS += rdata_python_test.py
 PYTESTS += rrclass_python_test.py
 PYTESTS += rrset_python_test.py
@@ -9,6 +12,7 @@
 PYTESTS += rrtype_python_test.py
 
 EXTRA_DIST = $(PYTESTS)
+EXTRA_DIST += testutil.py
 
 # If necessary (rare cases), explicitly specify paths to dynamic libraries
 # required by loadable python modules.
@@ -23,8 +27,8 @@
 check-local:
 	for pytest in $(PYTESTS) ; do \
 	echo Running test: $$pytest ; \
-	env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/lib/dns/python/.libs \
-	TESTDATA_PATH=$(abs_top_srcdir)/src/lib/dns/tests/testdata \
+	env PYTHONPATH=$(abs_top_srcdir)/src/lib/dns/.libs:$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/lib/dns/python/.libs \
+	TESTDATA_PATH=$(abs_top_srcdir)/src/lib/dns/tests/testdata:$(abs_top_builddir)/src/lib/dns/tests/testdata \
 	$(LIBRARY_PATH_PLACEHOLDER) \
 	$(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
 	done

Modified: experiments/327-sync/src/lib/dns/python/tests/message_python_test.py
==============================================================================
--- experiments/327-sync/src/lib/dns/python/tests/message_python_test.py (original)
+++ experiments/327-sync/src/lib/dns/python/tests/message_python_test.py Tue Nov  9 10:38:17 2010
@@ -14,244 +14,19 @@
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 #
-# Tests for the message part of the libdns_python module
+# Tests for the message part of the pydnspp module
 #
 
 import unittest
 import os
-from libdns_python 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 OpcodeTest(unittest.TestCase):
-    def test_init(self):
-        self.assertRaises(NotImplementedError, Opcode)
-
-    def test_get_code(self):
-        self.assertEqual(0, Opcode.QUERY().get_code())
-        self.assertEqual(1, Opcode.IQUERY().get_code())
-        self.assertEqual(2, Opcode.STATUS().get_code())
-        self.assertEqual(3, Opcode.RESERVED3().get_code())
-        self.assertEqual(4, Opcode.NOTIFY().get_code())
-        self.assertEqual(5, Opcode.UPDATE().get_code())
-        self.assertEqual(6, Opcode.RESERVED6().get_code())
-        self.assertEqual(7, Opcode.RESERVED7().get_code())
-        self.assertEqual(8, Opcode.RESERVED8().get_code())
-        self.assertEqual(9, Opcode.RESERVED9().get_code())
-        self.assertEqual(10, Opcode.RESERVED10().get_code())
-        self.assertEqual(11, Opcode.RESERVED11().get_code())
-        self.assertEqual(12, Opcode.RESERVED12().get_code())
-        self.assertEqual(13, Opcode.RESERVED13().get_code())
-        self.assertEqual(14, Opcode.RESERVED14().get_code())
-        self.assertEqual(15, Opcode.RESERVED15().get_code())
-
-    def test_to_text(self):
-        self.assertEqual("QUERY", Opcode.QUERY().to_text())
-        self.assertEqual("QUERY", str(Opcode.QUERY()))
-        self.assertEqual("IQUERY", Opcode.IQUERY().to_text())
-        self.assertEqual("STATUS", Opcode.STATUS().to_text())
-        self.assertEqual("RESERVED3", Opcode.RESERVED3().to_text())
-        self.assertEqual("NOTIFY", Opcode.NOTIFY().to_text())
-        self.assertEqual("UPDATE", Opcode.UPDATE().to_text())
-        self.assertEqual("RESERVED6", Opcode.RESERVED6().to_text())
-        self.assertEqual("RESERVED7", Opcode.RESERVED7().to_text())
-        self.assertEqual("RESERVED8", Opcode.RESERVED8().to_text())
-        self.assertEqual("RESERVED9", Opcode.RESERVED9().to_text())
-        self.assertEqual("RESERVED10", Opcode.RESERVED10().to_text())
-        self.assertEqual("RESERVED11", Opcode.RESERVED11().to_text())
-        self.assertEqual("RESERVED12", Opcode.RESERVED12().to_text())
-        self.assertEqual("RESERVED13", Opcode.RESERVED13().to_text())
-        self.assertEqual("RESERVED14", Opcode.RESERVED14().to_text())
-        self.assertEqual("RESERVED15", Opcode.RESERVED15().to_text())
-
-    def test_richcmp(self):
-        o1 = Opcode.QUERY()
-        o2 = Opcode.NOTIFY()
-        o3 = Opcode.NOTIFY()
-        self.assertTrue(o2 == o3)
-        self.assertFalse(o2 != o3)
-        self.assertTrue(o1 != o2)
-        self.assertFalse(o1 == 1)
-        self.assertFalse(o1 == o2)
-        # can't use assertRaises here...
-        try:
-            o1 < o2
-            self.fail("operation that should have raised an error unexpectedly succeeded")
-        except Exception as err:
-            self.assertEqual(TypeError, type(err))
-        try:
-            o1 <= o2
-            self.fail("operation that should have raised an error unexpectedly succeeded")
-        except Exception as err:
-            self.assertEqual(TypeError, type(err))
-        try:
-            o1 > o2
-            self.fail("operation that should have raised an error unexpectedly succeeded")
-        except Exception as err:
-            self.assertEqual(TypeError, type(err))
-        try:
-            o1 >= o2
-            self.fail("operation that should have raised an error unexpectedly succeeded")
-        except Exception as err:
-            self.assertEqual(TypeError, type(err))
-
-class RcodeTest(unittest.TestCase):
-    def test_init(self):
-        self.assertRaises(TypeError, Rcode, "wrong")
-        self.assertRaises(OverflowError, Rcode, 65536)
-        self.assertEqual(Rcode(0).get_code(), 0)
-    
-        self.assertEqual(0, Rcode(0).get_code())
-        self.assertEqual(0xfff, Rcode(0xfff).get_code()) # possible max code
-    
-        # should fail on attempt of construction with an out of range code
-        self.assertRaises(OverflowError, Rcode, 0x1000)
-        self.assertRaises(OverflowError, Rcode, 0xffff)
-
-    def test_get_code(self):
-        self.assertEqual(0, Rcode.NOERROR().get_code())
-        self.assertEqual(1, Rcode.FORMERR().get_code())
-        self.assertEqual(2, Rcode.SERVFAIL().get_code())
-        self.assertEqual(3, Rcode.NXDOMAIN().get_code())
-        self.assertEqual(4, Rcode.NOTIMP().get_code())
-        self.assertEqual(5, Rcode.REFUSED().get_code())
-        self.assertEqual(6, Rcode.YXDOMAIN().get_code())
-        self.assertEqual(7, Rcode.YXRRSET().get_code())
-        self.assertEqual(8, Rcode.NXRRSET().get_code())
-        self.assertEqual(9, Rcode.NOTAUTH().get_code())
-        self.assertEqual(10, Rcode.NOTZONE().get_code())
-        self.assertEqual(11, Rcode.RESERVED11().get_code())
-        self.assertEqual(12, Rcode.RESERVED12().get_code())
-        self.assertEqual(13, Rcode.RESERVED13().get_code())
-        self.assertEqual(14, Rcode.RESERVED14().get_code())
-        self.assertEqual(15, Rcode.RESERVED15().get_code())
-        self.assertEqual(16, Rcode.BADVERS().get_code())
-
-    def test_to_text(self):
-        self.assertEqual("NOERROR", Rcode(0).to_text())
-        self.assertEqual("NOERROR", str(Rcode(0)))
-        self.assertEqual("FORMERR", Rcode(1).to_text())
-        self.assertEqual("SERVFAIL", Rcode(2).to_text())
-        self.assertEqual("NXDOMAIN", Rcode(3).to_text())
-        self.assertEqual("NOTIMP", Rcode(4).to_text())
-        self.assertEqual("REFUSED", Rcode(5).to_text())
-        self.assertEqual("YXDOMAIN", Rcode(6).to_text())
-        self.assertEqual("YXRRSET", Rcode(7).to_text())
-        self.assertEqual("NXRRSET", Rcode(8).to_text())
-        self.assertEqual("NOTAUTH", Rcode(9).to_text())
-        self.assertEqual("NOTZONE", Rcode(10).to_text())
-        self.assertEqual("RESERVED11", Rcode(11).to_text())
-        self.assertEqual("RESERVED12", Rcode(12).to_text())
-        self.assertEqual("RESERVED13", Rcode(13).to_text())
-        self.assertEqual("RESERVED14", Rcode(14).to_text())
-        self.assertEqual("RESERVED15", Rcode(15).to_text())
-        self.assertEqual("BADVERS", Rcode(16).to_text())
-        
-        self.assertEqual("17", Rcode(Rcode.BADVERS().get_code() + 1).to_text())
-        self.assertEqual("4095", Rcode(0xfff).to_text())
-
-    def test_richcmp(self):
-        r1 = Rcode.NOERROR()
-        r2 = Rcode.FORMERR()
-        r3 = Rcode.FORMERR()
-        self.assertTrue(r2 == r3)
-        self.assertTrue(r1 != r2)
-        self.assertFalse(r1 == r2)
-        self.assertFalse(r1 != 1)
-        # can't use assertRaises here...
-        try:
-            r1 < r2
-            self.fail("operation that should have raised an error unexpectedly succeeded")
-        except Exception as err:
-            self.assertEqual(TypeError, type(err))
-        try:
-            r1 <= r2
-            self.fail("operation that should have raised an error unexpectedly succeeded")
-        except Exception as err:
-            self.assertEqual(TypeError, type(err))
-        try:
-            r1 > r2
-            self.fail("operation that should have raised an error unexpectedly succeeded")
-        except Exception as err:
-            self.assertEqual(TypeError, type(err))
-        try:
-            r1 >= r2
-            self.fail("operation that should have raised an error unexpectedly succeeded")
-        except Exception as err:
-            self.assertEqual(TypeError, type(err))
-
-class SectionTest(unittest.TestCase):
-
-    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))
-        
+from pydnspp import *
+from testutil import *
 
 # helper functions for tests taken from c++ unittests
 if "TESTDATA_PATH" in os.environ:
     testdata_path = os.environ["TESTDATA_PATH"]
 else:
     testdata_path = "../tests/testdata"
-
-def read_wire_data(filename):
-    data = bytes()
-    file = open(testdata_path + os.sep + filename, "r")
-    for line in file:
-        line = line.strip()
-        if line == "" or line.startswith("#"):
-            pass
-        else:
-            cur_data = bytes.fromhex(line)
-            data += cur_data
-
-    return data
 
 def factoryFromFile(message, file):
     data = read_wire_data(file)
@@ -275,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
 
 
@@ -292,51 +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())
-
-    def test_set_DNSSEC_supported(self):
-        self.assertRaises(TypeError, self.r.set_dnssec_supported, "wrong")
-
-        self.assertFalse(self.r.is_dnssec_supported())
-        self.r.set_dnssec_supported(True)
-        self.assertTrue(self.r.is_dnssec_supported())
-        self.r.set_dnssec_supported(False)
-        self.assertFalse(self.r.is_dnssec_supported())
-
-        self.assertRaises(InvalidMessageOperation,
-                          self.p.set_dnssec_supported, True)
-        self.assertRaises(InvalidMessageOperation,
-                          self.p.set_dnssec_supported, False)
-
-    def test_set_udp_size(self):
-        self.assertRaises(TypeError, self.r.set_udp_size, "wrong")
-        self.assertRaises(InvalidMessageUDPSize, self.r.set_udp_size, 0)
-        self.assertRaises(InvalidMessageUDPSize, self.r.set_udp_size, 65536)
-        self.assertRaises(InvalidMessageOperation, self.p.set_udp_size, 1024)
-        self.r.set_udp_size(2048)
-        self.assertEqual(2048, self.r.get_udp_size())
+
+        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")
@@ -355,6 +136,7 @@
         self.assertRaises(InvalidMessageOperation,
                           self.p.set_rcode, rcode)
         
+        self.assertRaises(InvalidMessageOperation, self.p.get_rcode)
 
     def test_set_opcode(self):
         self.assertRaises(TypeError, self.r.set_opcode, "wrong")
@@ -366,52 +148,97 @@
         self.assertRaises(InvalidMessageOperation,
                           self.p.set_opcode, opcode)
 
+        self.assertRaises(InvalidMessageOperation, self.p.get_opcode)
+
+    def test_get_edns(self):
+        self.assertEqual(None, self.p.get_edns())
+
+        message_parse = Message(Message.PARSE)
+        factoryFromFile(message_parse, "message_fromWire10.wire")
+        edns = message_parse.get_edns()
+        self.assertEqual(0, edns.get_version())
+        self.assertEqual(4096, edns.get_udp_size())
+        self.assertTrue(edns.get_dnssec_awareness())
+
+    def test_set_edns(self):
+        self.assertRaises(InvalidMessageOperation, self.p.set_edns, EDNS())
+
+        edns = EDNS()
+        edns.set_udp_size(1024)
+        self.r.set_edns(edns)
+        self.assertEqual(1024, self.r.get_edns().get_udp_size())
+
+    def test_get_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))
@@ -429,6 +256,16 @@
         message_render.to_wire(renderer)
         self.assertEqual(b'\x105\x85\x00\x00\x01\x00\x02\x00\x00\x00\x00\x04test\x07example\x03com\x00\x00\x01\x00\x01\xc0\x0c\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x04\xc0\x00\x02\x01\xc0\x0c\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x04\xc0\x00\x02\x02',
                          renderer.get_data())
+
+    def test_to_wire_without_opcode(self):
+        self.r.set_rcode(Rcode.NOERROR())
+        self.assertRaises(InvalidMessageOperation, self.r.to_wire,
+                          MessageRenderer())
+
+    def test_to_wire_without_rcode(self):
+        self.r.set_opcode(Opcode.QUERY())
+        self.assertRaises(InvalidMessageOperation, self.r.to_wire,
+                          MessageRenderer())
 
     def test_to_text(self):
         message_render = create_message()
@@ -446,6 +283,14 @@
 """
         self.assertEqual(msg_str, message_render.to_text())
         self.assertEqual(msg_str, str(message_render))
+
+    def test_to_text_without_opcode(self):
+        self.r.set_rcode(Rcode.NOERROR())
+        self.assertRaises(InvalidMessageOperation, self.r.to_text)
+
+    def test_to_text_without_rcode(self):
+        self.r.set_opcode(Opcode.QUERY())
+        self.assertRaises(InvalidMessageOperation, self.r.to_text)
 
     def test_from_wire(self):
         self.assertRaises(TypeError, self.r.from_wire, 1)
@@ -461,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())
@@ -487,93 +332,15 @@
         self.assertEqual("192.0.2.2", rdata[1].to_text())
         self.assertEqual(2, len(rdata))
 
-    def test_GetEDNS0DOBit(self):
-        message_parse = Message(Message.PARSE)
-        ## Without EDNS0, DNSSEC is considered to be unsupported.
-        factoryFromFile(message_parse, "message_fromWire1")
-        self.assertFalse(message_parse.is_dnssec_supported())
-    
-        ## If DO bit is on, DNSSEC is considered to be supported.
-        message_parse.clear(Message.PARSE)
-        factoryFromFile(message_parse, "message_fromWire2")
-        self.assertTrue(message_parse.is_dnssec_supported())
-    
-        ## If DO bit is off, DNSSEC is considered to be unsupported.
-        message_parse.clear(Message.PARSE)
-        factoryFromFile(message_parse, "message_fromWire3")
-        self.assertFalse(message_parse.is_dnssec_supported())
-    
-    def test_SetEDNS0DOBit(self):
-        # By default, it's false, and we can enable/disable it.
-        message_parse = Message(Message.PARSE)
-        message_render = Message(Message.RENDER)
-        self.assertFalse(message_render.is_dnssec_supported())
-        message_render.set_dnssec_supported(True)
-        self.assertTrue(message_render.is_dnssec_supported())
-        message_render.set_dnssec_supported(False)
-        self.assertFalse(message_render.is_dnssec_supported())
-    
-        ## A message in the parse mode doesn't allow this flag to be set.
-        self.assertRaises(InvalidMessageOperation,
-                          message_parse.set_dnssec_supported,
-                          True)
-        ## Once converted to the render mode, it works as above
-        message_parse.make_response()
-        self.assertFalse(message_parse.is_dnssec_supported())
-        message_parse.set_dnssec_supported(True)
-        self.assertTrue(message_parse.is_dnssec_supported())
-        message_parse.set_dnssec_supported(False)
-        self.assertFalse(message_parse.is_dnssec_supported())
-    
-    def test_GetEDNS0UDPSize(self):
-        # Without EDNS0, the default max UDP size is used.
-        message_parse = Message(Message.PARSE)
-        factoryFromFile(message_parse, "message_fromWire1")
-        self.assertEqual(Message.DEFAULT_MAX_UDPSIZE, message_parse.get_udp_size())
-    
-        ## If the size specified in EDNS0 > default max, use it.
-        message_parse.clear(Message.PARSE)
-        factoryFromFile(message_parse, "message_fromWire2")
-        self.assertEqual(4096, message_parse.get_udp_size())
-    
-        ## If the size specified in EDNS0 < default max, keep using the default.
-        message_parse.clear(Message.PARSE)
-        factoryFromFile(message_parse, "message_fromWire8")
-        self.assertEqual(Message.DEFAULT_MAX_UDPSIZE, message_parse.get_udp_size())
-    
-    def test_SetEDNS0UDPSize(self):
-        # The default size if unspecified
-        message_render = Message(Message.RENDER)
-        message_parse = Message(Message.PARSE)
-        self.assertEqual(Message.DEFAULT_MAX_UDPSIZE, message_render.get_udp_size())
-        # A common buffer size with EDNS, should succeed
-        message_render.set_udp_size(4096)
-        self.assertEqual(4096, message_render.get_udp_size())
-        # Unusual large value, but accepted
-        message_render.set_udp_size(0xffff)
-        self.assertEqual(0xffff, message_render.get_udp_size())
-        # Too small is value is rejected
-        self.assertRaises(InvalidMessageUDPSize, message_render.set_udp_size, 511)
-    
-        # A message in the parse mode doesn't allow the set operation.
-        self.assertRaises(InvalidMessageOperation, message_parse.set_udp_size, 4096)
-        ## Once converted to the render mode, it works as above.
-        message_parse.make_response()
-        message_parse.set_udp_size(4096)
-        self.assertEqual(4096, message_parse.get_udp_size())
-        message_parse.set_udp_size(0xffff)
-        self.assertEqual(0xffff, message_parse.get_udp_size())
-        self.assertRaises(InvalidMessageUDPSize, message_parse.set_udp_size, 511)
-    
     def test_EDNS0ExtCode(self):
         # Extended Rcode = BADVERS
         message_parse = Message(Message.PARSE)
-        factoryFromFile(message_parse, "message_fromWire10")
+        factoryFromFile(message_parse, "message_fromWire10.wire")
         self.assertEqual(Rcode.BADVERS(), message_parse.get_rcode())
     
         # Maximum extended Rcode
         message_parse.clear(Message.PARSE)
-        factoryFromFile(message_parse, "message_fromWire11")
+        factoryFromFile(message_parse, "message_fromWire11.wire")
         self.assertEqual(0xfff, message_parse.get_rcode().get_code())
     
     def test_BadEDNS0(self):

Modified: experiments/327-sync/src/lib/dns/python/tests/messagerenderer_python_test.py
==============================================================================
--- experiments/327-sync/src/lib/dns/python/tests/messagerenderer_python_test.py (original)
+++ experiments/327-sync/src/lib/dns/python/tests/messagerenderer_python_test.py Tue Nov  9 10:38:17 2010
@@ -14,12 +14,12 @@
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 #
-# Tests for the messagerenderer part of the libdns_python module
+# Tests for the messagerenderer part of the pydnspp module
 #
 
 import unittest
 import os
-from libdns_python import *
+from pydnspp import *
 
 class MessageRendererTest(unittest.TestCase):
 
@@ -32,20 +32,21 @@
         message = Message(Message.RENDER)
         message.set_qid(123)
         message.set_opcode(Opcode.QUERY())
+        message.set_rcode(Rcode.NOERROR())
         message.add_question(Question(name, c, t))
 
         self.message1 = message
         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: experiments/327-sync/src/lib/dns/python/tests/name_python_test.py
==============================================================================
--- experiments/327-sync/src/lib/dns/python/tests/name_python_test.py (original)
+++ experiments/327-sync/src/lib/dns/python/tests/name_python_test.py Tue Nov  9 10:38:17 2010
@@ -14,12 +14,12 @@
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 #
-# Tests for the messagerenderer part of the libdns_python module
+# Tests for the messagerenderer part of the pydnspp module
 #
 
 import unittest
 import os
-from libdns_python import *
+from pydnspp import *
 
 class NameComparisonTest(unittest.TestCase):
     def setUp(self):

Modified: experiments/327-sync/src/lib/dns/python/tests/question_python_test.py
==============================================================================
--- experiments/327-sync/src/lib/dns/python/tests/question_python_test.py (original)
+++ experiments/327-sync/src/lib/dns/python/tests/question_python_test.py Tue Nov  9 10:38:17 2010
@@ -14,30 +14,18 @@
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 #
-# Tests for the rrtype part of the libdns_python module
+# Tests for the rrtype part of the pydnspp module
 #
 
 import unittest
 import os
-from libdns_python import *
+from pydnspp import *
+from testutil import *
 
 if "TESTDATA_PATH" in os.environ:
     testdata_path = os.environ["TESTDATA_PATH"]
 else:
     testdata_path = "../tests/testdata"
-
-def read_wire_data(filename):
-    data = bytes()
-    file = open(testdata_path + os.sep + filename, "r")
-    for line in file:
-        line = line.strip()
-        if line == "" or line.startswith("#"):
-            pass
-        else:
-            cur_data = bytes.fromhex(line)
-            data += cur_data
-
-    return data
 
 def question_from_wire(file, position = 0):
     data = read_wire_data(file)
@@ -102,7 +90,6 @@
         wiredata = read_wire_data("question_toWire2")
         self.assertEqual(renderer.get_data(), wiredata)
         self.assertRaises(TypeError, self.test_question1.to_wire, 1)
-    
 
 if __name__ == '__main__':
     unittest.main()

Modified: experiments/327-sync/src/lib/dns/python/tests/rdata_python_test.py
==============================================================================
--- experiments/327-sync/src/lib/dns/python/tests/rdata_python_test.py (original)
+++ experiments/327-sync/src/lib/dns/python/tests/rdata_python_test.py Tue Nov  9 10:38:17 2010
@@ -14,12 +14,12 @@
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 #
-# Tests for the rdata part of the libdns_python module
+# Tests for the rdata part of the pydnspp module
 #
 
 import unittest
 import os
-from libdns_python import *
+from pydnspp import *
 
 class RdataTest(unittest.TestCase):
     def setUp(self):

Modified: experiments/327-sync/src/lib/dns/python/tests/rrclass_python_test.py
==============================================================================
--- experiments/327-sync/src/lib/dns/python/tests/rrclass_python_test.py (original)
+++ experiments/327-sync/src/lib/dns/python/tests/rrclass_python_test.py Tue Nov  9 10:38:17 2010
@@ -14,12 +14,12 @@
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 #
-# Tests for the rrclass part of the libdns_python module
+# Tests for the rrclass part of the pydnspp module
 #
 
 import unittest
 import os
-from libdns_python import *
+from pydnspp import *
 
 class RRClassTest(unittest.TestCase):
     def setUp(self):

Modified: experiments/327-sync/src/lib/dns/python/tests/rrset_python_test.py
==============================================================================
--- experiments/327-sync/src/lib/dns/python/tests/rrset_python_test.py (original)
+++ experiments/327-sync/src/lib/dns/python/tests/rrset_python_test.py Tue Nov  9 10:38:17 2010
@@ -14,12 +14,12 @@
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 #
-# Tests for the rrtype part of the libdns_python module
+# Tests for the rrtype part of the pydnspp module
 #
 
 import unittest
 import os
-from libdns_python import *
+from pydnspp import *
 
 class TestModuleSpec(unittest.TestCase):
     

Modified: experiments/327-sync/src/lib/dns/python/tests/rrttl_python_test.py
==============================================================================
--- experiments/327-sync/src/lib/dns/python/tests/rrttl_python_test.py (original)
+++ experiments/327-sync/src/lib/dns/python/tests/rrttl_python_test.py Tue Nov  9 10:38:17 2010
@@ -14,12 +14,12 @@
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 #
-# Tests for the rrttl part of the libdns_python module
+# Tests for the rrttl part of the pydnspp module
 #
 
 import unittest
 import os
-from libdns_python import *
+from pydnspp import *
 
 class RRTTLTest(unittest.TestCase):
     def setUp(self):

Modified: experiments/327-sync/src/lib/dns/python/tests/rrtype_python_test.py
==============================================================================
--- experiments/327-sync/src/lib/dns/python/tests/rrtype_python_test.py (original)
+++ experiments/327-sync/src/lib/dns/python/tests/rrtype_python_test.py Tue Nov  9 10:38:17 2010
@@ -14,12 +14,12 @@
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 #
-# Tests for the rrtype part of the libdns_python module
+# Tests for the rrtype part of the pydnspp module
 #
 
 import unittest
 import os
-from libdns_python import *
+from pydnspp import *
 
 class TestModuleSpec(unittest.TestCase):
     

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

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

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

Modified: experiments/327-sync/src/lib/dns/rdata/generic/cname_5.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/rdata/generic/cname_5.cc (original)
+++ experiments/327-sync/src/lib/dns/rdata/generic/cname_5.cc Tue Nov  9 10:38:17 2010
@@ -49,34 +49,29 @@
 {}
 
 void
-CNAME::toWire(OutputBuffer& buffer) const
-{
+CNAME::toWire(OutputBuffer& buffer) const {
     cname_.toWire(buffer);
 }
 
 void
-CNAME::toWire(MessageRenderer& renderer) const
-{
+CNAME::toWire(MessageRenderer& renderer) const {
     renderer.writeName(cname_);
 }
 
 string
-CNAME::toText() const
-{
+CNAME::toText() const {
     return (cname_.toText());
 }
 
 int
-CNAME::compare(const Rdata& other) const
-{
+CNAME::compare(const Rdata& other) const {
     const CNAME& other_cname = dynamic_cast<const CNAME&>(other);
 
     return (compareNames(cname_, other_cname.cname_));
 }
 
 const Name&
-CNAME::getCname() const
-{
+CNAME::getCname() const {
     return (cname_);
 }
 

Modified: experiments/327-sync/src/lib/dns/rdata/generic/dname_39.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/rdata/generic/dname_39.cc (original)
+++ experiments/327-sync/src/lib/dns/rdata/generic/dname_39.cc Tue Nov  9 10:38:17 2010
@@ -49,34 +49,29 @@
 {}
 
 void
-DNAME::toWire(OutputBuffer& buffer) const
-{
+DNAME::toWire(OutputBuffer& buffer) const {
     dname_.toWire(buffer);
 }
 
 void
-DNAME::toWire(MessageRenderer& renderer) const
-{
+DNAME::toWire(MessageRenderer& renderer) const {
     renderer.writeName(dname_);
 }
 
 string
-DNAME::toText() const
-{
+DNAME::toText() const {
     return (dname_.toText());
 }
 
 int
-DNAME::compare(const Rdata& other) const
-{
+DNAME::compare(const Rdata& other) const {
     const DNAME& other_dname = dynamic_cast<const DNAME&>(other);
 
     return (compareNames(dname_, other_dname.dname_));
 }
 
 const Name&
-DNAME::getDname() const
-{
+DNAME::getDname() const {
     return (dname_);
 }
 

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

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

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

Modified: experiments/327-sync/src/lib/dns/rdata/generic/mx_15.h
==============================================================================
--- experiments/327-sync/src/lib/dns/rdata/generic/mx_15.h (original)
+++ experiments/327-sync/src/lib/dns/rdata/generic/mx_15.h Tue Nov  9 10:38:17 2010
@@ -35,7 +35,7 @@
     // BEGIN_COMMON_MEMBERS
     // END_COMMON_MEMBERS
 
-    explicit MX(uint16_t preference, const Name& mxname);
+    MX(uint16_t preference, const Name& mxname);
 
     ///
     /// Specialized methods

Modified: experiments/327-sync/src/lib/dns/rdata/generic/ns_2.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/rdata/generic/ns_2.cc (original)
+++ experiments/327-sync/src/lib/dns/rdata/generic/ns_2.cc Tue Nov  9 10:38:17 2010
@@ -45,34 +45,29 @@
 {}
 
 void
-NS::toWire(OutputBuffer& buffer) const
-{
+NS::toWire(OutputBuffer& buffer) const {
     nsname_.toWire(buffer);
 }
 
 void
-NS::toWire(MessageRenderer& renderer) const
-{
+NS::toWire(MessageRenderer& renderer) const {
     renderer.writeName(nsname_);
 }
 
 string
-NS::toText() const
-{
+NS::toText() const {
     return (nsname_.toText());
 }
 
 int
-NS::compare(const Rdata& other) const
-{
+NS::compare(const Rdata& other) const {
     const NS& other_ns = dynamic_cast<const NS&>(other);
 
     return (compareNames(nsname_, other_ns.nsname_));
 }
 
 const Name&
-NS::getNSName() const
-{
+NS::getNSName() const {
     return (nsname_);
 }
 

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

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

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

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

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

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

Modified: experiments/327-sync/src/lib/dns/rdata/generic/soa_6.h
==============================================================================
--- experiments/327-sync/src/lib/dns/rdata/generic/soa_6.h (original)
+++ experiments/327-sync/src/lib/dns/rdata/generic/soa_6.h Tue Nov  9 10:38:17 2010
@@ -33,9 +33,9 @@
     // BEGIN_COMMON_MEMBERS
     // END_COMMON_MEMBERS
 
-    explicit SOA(const Name& mname, const Name& rname, uint32_t serial,
-                 uint32_t refresh, uint32_t retry, uint32_t expire,
-                 uint32_t minimum);
+    SOA(const Name& mname, const Name& rname, uint32_t serial,
+        uint32_t refresh, uint32_t retry, uint32_t expire,
+        uint32_t minimum);
 private:
     /// Note: this is a prototype version; we may reconsider
     /// this representation later.

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

Modified: experiments/327-sync/src/lib/dns/rdata/template.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/rdata/template.cc (original)
+++ experiments/327-sync/src/lib/dns/rdata/template.cc Tue Nov  9 10:38:17 2010
@@ -34,36 +34,29 @@
 // If you added member functions specific to this derived class, you'll need
 // to implement them here, of course.
 
-MyType::MyType(const string& type_str)
-{
+MyType::MyType(const string& type_str) {
 }
 
-MyType::MyType(InputBuffer& buffer, size_t rdata_len)
-{
+MyType::MyType(InputBuffer& buffer, size_t rdata_len) {
 }
 
-MyType::MyType(const MyType& source)
-{
+MyType::MyType(const MyType& source) {
 }
 
 std::string
-MyType::toText() const
-{
+MyType::toText() const {
 }
 
 void
-MyType::toWire(OutputBuffer& buffer) const
-{
+MyType::toWire(OutputBuffer& buffer) const {
 }
 
 void
-MyType::toWire(MessageRenderer& renderer) const
-{
+MyType::toWire(MessageRenderer& renderer) const {
 }
 
 int
-MyType::compare(const Rdata& other) const
-{
+MyType::compare(const Rdata& other) const {
     // The compare method normally begins with this dynamic cast.
     const MyType& other_mytype = dynamic_cast<const MyType&>(other);
     // ...

Modified: experiments/327-sync/src/lib/dns/rrclass-placeholder.h
==============================================================================
--- experiments/327-sync/src/lib/dns/rrclass-placeholder.h (original)
+++ experiments/327-sync/src/lib/dns/rrclass-placeholder.h Tue Nov  9 10:38:17 2010
@@ -211,7 +211,7 @@
     /// \brief Same as \c equals().
     bool operator==(const RRClass& other) const { return (equals(other)); }
 
-    /// \brief Return true iff two RRClasses are equal.
+    /// \brief Return true iff two RRClasses are not equal.
     ///
     /// This method never throws an exception.
     ///
@@ -260,16 +260,14 @@
 // END_WELL_KNOWN_CLASS_DEFINITIONS
 
 inline const RRClass&
-RRClass::NONE()
-{
+RRClass::NONE() {
     static RRClass rrclass(RRCLASS_NONE);
 
     return (rrclass);
 }
 
 inline const RRClass&
-RRClass::ANY()
-{
+RRClass::ANY() {
     static RRClass rrclass(RRCLASS_ANY);
 
     return (rrclass);

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

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

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

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

Modified: experiments/327-sync/src/lib/dns/rrsetlist.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/rrsetlist.cc (original)
+++ experiments/327-sync/src/lib/dns/rrsetlist.cc Tue Nov  9 10:38:17 2010
@@ -41,8 +41,7 @@
 }
 
 void
-RRsetList::append(RRsetList& source)
-{
+RRsetList::append(RRsetList& source) {
     BOOST_FOREACH(RRsetPtr rrset, source) {
         addRRset(rrset);
     }

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

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

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

Modified: experiments/327-sync/src/lib/dns/tests/Makefile.am
==============================================================================
--- experiments/327-sync/src/lib/dns/tests/Makefile.am (original)
+++ experiments/327-sync/src/lib/dns/tests/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,6 +1,10 @@
+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_DIR=\"$(srcdir)/testdata\"
+AM_CPPFLAGS += -DTEST_DATA_SRCDIR=\"$(srcdir)/testdata\"
+AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/lib/dns/tests/testdata\"
 AM_CXXFLAGS = $(B10_CXXFLAGS)
 
 if USE_STATIC_LINK
@@ -14,10 +18,13 @@
 TESTS += run_unittests
 run_unittests_SOURCES = unittest_util.h unittest_util.cc
 run_unittests_SOURCES += buffer_unittest.cc name_unittest.cc
+run_unittests_SOURCES += edns_unittest.cc
 run_unittests_SOURCES += messagerenderer_unittest.cc
 run_unittests_SOURCES += rrclass_unittest.cc rrtype_unittest.cc
 run_unittests_SOURCES += rrttl_unittest.cc
 run_unittests_SOURCES += dnssectime_unittest.cc
+run_unittests_SOURCES += opcode_unittest.cc
+run_unittests_SOURCES += rcode_unittest.cc
 run_unittests_SOURCES += rdata_unittest.h rdata_unittest.cc
 run_unittests_SOURCES += rdata_in_a_unittest.cc rdata_in_aaaa_unittest.cc
 run_unittests_SOURCES += rdata_ns_unittest.cc rdata_soa_unittest.cc
@@ -49,99 +56,3 @@
 endif
 
 noinst_PROGRAMS = $(TESTS)
-
-# NOTE: keep this in sync with real file listing
-# so is included in tarball
-EXTRA_DIST = testdata/gen-wiredata.py.in
-EXTRA_DIST += testdata/message_fromWire1
-EXTRA_DIST += testdata/message_fromWire10
-EXTRA_DIST += testdata/message_fromWire10.spec
-EXTRA_DIST += testdata/message_fromWire11
-EXTRA_DIST += testdata/message_fromWire11.spec
-EXTRA_DIST += testdata/message_fromWire2
-EXTRA_DIST += testdata/message_fromWire3
-EXTRA_DIST += testdata/message_fromWire4
-EXTRA_DIST += testdata/message_fromWire5
-EXTRA_DIST += testdata/message_fromWire6
-EXTRA_DIST += testdata/message_fromWire7
-EXTRA_DIST += testdata/message_fromWire8
-EXTRA_DIST += testdata/message_fromWire9
-EXTRA_DIST += testdata/message_toWire1
-EXTRA_DIST += testdata/name_fromWire1
-EXTRA_DIST += testdata/name_fromWire10
-EXTRA_DIST += testdata/name_fromWire11
-EXTRA_DIST += testdata/name_fromWire12
-EXTRA_DIST += testdata/name_fromWire13
-EXTRA_DIST += testdata/name_fromWire14
-EXTRA_DIST += testdata/name_fromWire2
-EXTRA_DIST += testdata/name_fromWire3_1
-EXTRA_DIST += testdata/name_fromWire3_2
-EXTRA_DIST += testdata/name_fromWire4
-EXTRA_DIST += testdata/name_fromWire6
-EXTRA_DIST += testdata/name_fromWire7
-EXTRA_DIST += testdata/name_fromWire8
-EXTRA_DIST += testdata/name_fromWire9
-EXTRA_DIST += testdata/name_toWire1
-EXTRA_DIST += testdata/name_toWire2
-EXTRA_DIST += testdata/name_toWire3
-EXTRA_DIST += testdata/name_toWire4
-EXTRA_DIST += testdata/name_toWire5
-EXTRA_DIST += testdata/name_toWire5.spec
-EXTRA_DIST += testdata/name_toWire6
-EXTRA_DIST += testdata/name_toWire6.spec
-EXTRA_DIST += testdata/question_fromWire
-EXTRA_DIST += testdata/question_toWire1
-EXTRA_DIST += testdata/question_toWire2
-EXTRA_DIST += testdata/rdata_cname_fromWire
-EXTRA_DIST += testdata/rdata_dname_fromWire
-EXTRA_DIST += testdata/rdata_dnskey_fromWire
-EXTRA_DIST += testdata/rdata_ds_fromWire
-EXTRA_DIST += testdata/rdata_in_a_fromWire
-EXTRA_DIST += testdata/rdata_in_aaaa_fromWire
-EXTRA_DIST += testdata/rdata_mx_fromWire
-EXTRA_DIST += testdata/rdata_mx_toWire1
-EXTRA_DIST += testdata/rdata_ns_fromWire
-EXTRA_DIST += testdata/rdata_nsec3_fromWire1
-EXTRA_DIST += testdata/rdata_nsec3_fromWire2
-EXTRA_DIST += testdata/rdata_nsec3_fromWire3
-EXTRA_DIST += testdata/rdata_nsec3param_fromWire1
-EXTRA_DIST += testdata/rdata_nsec_fromWire1
-EXTRA_DIST += testdata/rdata_nsec_fromWire10
-EXTRA_DIST += testdata/rdata_nsec_fromWire10.spec
-EXTRA_DIST += testdata/rdata_nsec_fromWire2
-EXTRA_DIST += testdata/rdata_nsec_fromWire3
-EXTRA_DIST += testdata/rdata_nsec_fromWire4
-EXTRA_DIST += testdata/rdata_nsec_fromWire4.spec
-EXTRA_DIST += testdata/rdata_nsec_fromWire5
-EXTRA_DIST += testdata/rdata_nsec_fromWire5.spec
-EXTRA_DIST += testdata/rdata_nsec_fromWire6
-EXTRA_DIST += testdata/rdata_nsec_fromWire6.spec
-EXTRA_DIST += testdata/rdata_nsec_fromWire7
-EXTRA_DIST += testdata/rdata_nsec_fromWire7.spec
-EXTRA_DIST += testdata/rdata_nsec_fromWire8
-EXTRA_DIST += testdata/rdata_nsec_fromWire8.spec
-EXTRA_DIST += testdata/rdata_nsec_fromWire9
-EXTRA_DIST += testdata/rdata_nsec_fromWire9.spec
-EXTRA_DIST += testdata/rdata_opt_fromWire
-EXTRA_DIST += testdata/rdata_rrsig_fromWire1
-EXTRA_DIST += testdata/rdata_rrsig_fromWire2
-EXTRA_DIST += testdata/rdata_rrsig_fromWire2.spec
-EXTRA_DIST += testdata/rdata_soa_fromWire
-EXTRA_DIST += testdata/rdata_soa_toWireUncompressed
-EXTRA_DIST += testdata/rdata_soa_toWireUncompressed.spec
-EXTRA_DIST += testdata/rdata_txt_fromWire1
-EXTRA_DIST += testdata/rdata_txt_fromWire2
-EXTRA_DIST += testdata/rdata_txt_fromWire2.spec
-EXTRA_DIST += testdata/rdata_txt_fromWire3
-EXTRA_DIST += testdata/rdata_txt_fromWire3.spec
-EXTRA_DIST += testdata/rdata_txt_fromWire4
-EXTRA_DIST += testdata/rdata_txt_fromWire4.spec
-EXTRA_DIST += testdata/rdata_txt_fromWire5
-EXTRA_DIST += testdata/rdata_txt_fromWire5.spec
-EXTRA_DIST += testdata/rdata_unknown_fromWire
-EXTRA_DIST += testdata/rrcode16_fromWire1
-EXTRA_DIST += testdata/rrcode16_fromWire2
-EXTRA_DIST += testdata/rrcode32_fromWire1
-EXTRA_DIST += testdata/rrcode32_fromWire2
-EXTRA_DIST += testdata/rrset_toWire1
-EXTRA_DIST += testdata/rrset_toWire2

Modified: experiments/327-sync/src/lib/dns/tests/buffer_unittest.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/tests/buffer_unittest.cc (original)
+++ experiments/327-sync/src/lib/dns/tests/buffer_unittest.cc Tue Nov  9 10:38:17 2010
@@ -48,8 +48,7 @@
 
 const uint8_t BufferTest::testdata[5] = {1, 2, 3, 4, 5};
 
-TEST_F(BufferTest, inputBufferRead)
-{
+TEST_F(BufferTest, inputBufferRead) {
     EXPECT_EQ(5, ibuffer.getLength());
     EXPECT_EQ(1, ibuffer.readUint8());
     EXPECT_EQ(1, ibuffer.getPosition());
@@ -66,8 +65,7 @@
     EXPECT_EQ(0, memcmp(vdata, testdata, sizeof(testdata)));
 }
 
-TEST_F(BufferTest, inputBufferException)
-{
+TEST_F(BufferTest, inputBufferException) {
     EXPECT_THROW(ibuffer.setPosition(6), isc::dns::InvalidBufferPosition);
 
     ibuffer.setPosition(sizeof(testdata));
@@ -84,8 +82,7 @@
                  isc::dns::InvalidBufferPosition);
 }
 
-TEST_F(BufferTest, outputBufferExtend)
-{
+TEST_F(BufferTest, outputBufferExtend) {
     EXPECT_EQ(0, obuffer.getCapacity());
     EXPECT_EQ(0, obuffer.getLength());
     obuffer.writeUint8(10);
@@ -93,8 +90,7 @@
     EXPECT_EQ(1, obuffer.getLength());
 }
 
-TEST_F(BufferTest, outputBufferWrite)
-{
+TEST_F(BufferTest, outputBufferWrite) {
     const uint8_t* cp;
 
     obuffer.writeUint8(1);
@@ -126,8 +122,7 @@
     EXPECT_EQ(0, memcmp(cp + 7, testdata, sizeof(testdata)));
 }
 
-TEST_F(BufferTest, outputBufferWriteat)
-{
+TEST_F(BufferTest, outputBufferWriteat) {
     obuffer.writeUint32(data32);
     expected_size += sizeof(data32);
 
@@ -153,8 +148,7 @@
                  isc::dns::InvalidBufferPosition);
 }
 
-TEST_F(BufferTest, outputBufferSkip)
-{
+TEST_F(BufferTest, outputBufferSkip) {
     obuffer.skip(4);
     EXPECT_EQ(4, obuffer.getLength());
 
@@ -162,8 +156,7 @@
     EXPECT_EQ(6, obuffer.getLength());
 }
 
-TEST_F(BufferTest, outputBufferTrim)
-{
+TEST_F(BufferTest, outputBufferTrim) {
     obuffer.writeData(testdata, sizeof(testdata));
     EXPECT_EQ(5, obuffer.getLength());
 
@@ -176,8 +169,7 @@
     EXPECT_THROW(obuffer.trim(3), OutOfRange);
 }
 
-TEST_F(BufferTest, outputBufferReadat)
-{
+TEST_F(BufferTest, outputBufferReadat) {
     obuffer.writeData(testdata, sizeof(testdata));
     for (int i = 0; i < sizeof(testdata); i ++) {
         EXPECT_EQ(testdata[i], obuffer[i]);
@@ -185,8 +177,7 @@
     EXPECT_THROW(obuffer[sizeof(testdata)], isc::dns::InvalidBufferPosition);
 }
 
-TEST_F(BufferTest, outputBufferClear)
-{
+TEST_F(BufferTest, outputBufferClear) {
     obuffer.writeData(testdata, sizeof(testdata));
     obuffer.clear();
     EXPECT_EQ(0, obuffer.getLength());

Modified: experiments/327-sync/src/lib/dns/tests/message_unittest.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/tests/message_unittest.cc (original)
+++ experiments/327-sync/src/lib/dns/tests/message_unittest.cc Tue Nov  9 10:38:17 2010
@@ -17,10 +17,13 @@
 #include <exceptions/exceptions.h>
 
 #include <dns/buffer.h>
+#include <dns/edns.h>
 #include <dns/exceptions.h>
 #include <dns/message.h>
 #include <dns/messagerenderer.h>
 #include <dns/question.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
 #include <dns/rdataclass.h>
 #include <dns/rrclass.h>
 #include <dns/rrttl.h>
@@ -32,6 +35,7 @@
 
 using isc::UnitTestUtil;
 using namespace std;
+using namespace isc;
 using namespace isc::dns;
 using namespace isc::dns::rdata;
 
@@ -48,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) {
@@ -76,43 +101,192 @@
     message.fromWire(buffer);
 }
 
-TEST_F(MessageTest, RcodeConstruct) {
-    // normal cases
-    EXPECT_EQ(0, Rcode(0).getCode());
-    EXPECT_EQ(0xfff, Rcode(0xfff).getCode()); // possible max code
-
-    // should fail on attempt of construction with an out of range code
-    EXPECT_THROW(Rcode(0x1000), isc::OutOfRange);
-    EXPECT_THROW(Rcode(0xffff), isc::OutOfRange);
-}
-
-TEST_F(MessageTest, RcodeToText) {
-    EXPECT_EQ("NOERROR", Rcode::NOERROR().toText());
-    EXPECT_EQ("BADVERS", Rcode::BADVERS().toText());
-    EXPECT_EQ("17", Rcode(Rcode::BADVERS().getCode() + 1).toText());
-    EXPECT_EQ("4095", Rcode(Rcode(0xfff)).toText());
-}
-
+TEST_F(MessageTest, 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) {
+    EXPECT_FALSE(message_parse.getEDNS()); // by default EDNS isn't set
+
+    factoryFromFile(message_parse, "message_fromWire10.wire");
+    EXPECT_TRUE(message_parse.getEDNS());
+    EXPECT_EQ(0, message_parse.getEDNS()->getVersion());
+    EXPECT_EQ(4096, message_parse.getEDNS()->getUDPSize());
+    EXPECT_TRUE(message_parse.getEDNS()->getDNSSECAwareness());
+}
+
+TEST_F(MessageTest, setEDNS) {
+    // setEDNS() isn't allowed in the parse mode
+    EXPECT_THROW(message_parse.setEDNS(EDNSPtr(new EDNS())),
+                 InvalidMessageOperation);
+
+    EDNSPtr edns = EDNSPtr(new EDNS());
+    message_render.setEDNS(edns);
+    EXPECT_EQ(edns, message_render.getEDNS());
+}
+
+TEST_F(MessageTest, 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());
@@ -127,89 +301,14 @@
     EXPECT_TRUE(it->isLast());
 }
 
-TEST_F(MessageTest, GetEDNS0DOBit) {
-    // Without EDNS0, DNSSEC is considered to be unsupported.
-    factoryFromFile(message_parse, "message_fromWire1");
-    EXPECT_FALSE(message_parse.isDNSSECSupported());
-
-    // If DO bit is on, DNSSEC is considered to be supported.
-    message_parse.clear(Message::PARSE);
-    factoryFromFile(message_parse, "message_fromWire2");
-    EXPECT_TRUE(message_parse.isDNSSECSupported());
-
-    // If DO bit is off, DNSSEC is considered to be unsupported.
-    message_parse.clear(Message::PARSE);
-    factoryFromFile(message_parse, "message_fromWire3");
-    EXPECT_FALSE(message_parse.isDNSSECSupported());
-}
-
-TEST_F(MessageTest, SetEDNS0DOBit) {
-    // By default, it's false, and we can enable/disable it.
-    EXPECT_FALSE(message_render.isDNSSECSupported());
-    message_render.setDNSSECSupported(true);
-    EXPECT_TRUE(message_render.isDNSSECSupported());
-    message_render.setDNSSECSupported(false);
-    EXPECT_FALSE(message_render.isDNSSECSupported());
-
-    // A message in the parse mode doesn't allow this flag to be set.
-    EXPECT_THROW(message_parse.setDNSSECSupported(true),
-                 InvalidMessageOperation);
-    // Once converted to the render mode, it works as above
-    message_parse.makeResponse();
-    EXPECT_FALSE(message_parse.isDNSSECSupported());
-    message_parse.setDNSSECSupported(true);
-    EXPECT_TRUE(message_parse.isDNSSECSupported());
-    message_parse.setDNSSECSupported(false);
-    EXPECT_FALSE(message_parse.isDNSSECSupported());
-}
-
-TEST_F(MessageTest, GetEDNS0UDPSize) {
-    // Without EDNS0, the default max UDP size is used.
-    factoryFromFile(message_parse, "message_fromWire1");
-    EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message_parse.getUDPSize());
-
-    // If the size specified in EDNS0 > default max, use it.
-    message_parse.clear(Message::PARSE);
-    factoryFromFile(message_parse, "message_fromWire2");
-    EXPECT_EQ(4096, message_parse.getUDPSize());
-
-    // If the size specified in EDNS0 < default max, keep using the default.
-    message_parse.clear(Message::PARSE);
-    factoryFromFile(message_parse, "message_fromWire8");
-    EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message_parse.getUDPSize());
-}
-
-TEST_F(MessageTest, SetEDNS0UDPSize) {
-    // The default size if unspecified
-    EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message_render.getUDPSize());
-    // A common buffer size with EDNS, should succeed
-    message_render.setUDPSize(4096);
-    EXPECT_EQ(4096, message_render.getUDPSize());
-    // Unusual large value, but accepted
-    message_render.setUDPSize(0xffff);
-    EXPECT_EQ(0xffff, message_render.getUDPSize());
-    // Too small is value is rejected
-    EXPECT_THROW(message_render.setUDPSize(511), InvalidMessageUDPSize);
-
-    // A message in the parse mode doesn't allow the set operation.
-    EXPECT_THROW(message_parse.setUDPSize(4096), InvalidMessageOperation);
-    // Once converted to the render mode, it works as above.
-    message_parse.makeResponse();
-    message_parse.setUDPSize(4096);
-    EXPECT_EQ(4096, message_parse.getUDPSize());
-    message_parse.setUDPSize(0xffff);
-    EXPECT_EQ(0xffff, message_parse.getUDPSize());
-    EXPECT_THROW(message_parse.setUDPSize(511), InvalidMessageUDPSize);
-}
-
-TEST_F(MessageTest, EDNS0ExtCode) {
+TEST_F(MessageTest, EDNS0ExtRcode) {
     // Extended Rcode = BADVERS
-    factoryFromFile(message_parse, "message_fromWire10");
+    factoryFromFile(message_parse, "message_fromWire10.wire");
     EXPECT_EQ(Rcode::BADVERS(), message_parse.getRcode());
 
     // Maximum extended Rcode
     message_parse.clear(Message::PARSE);
-    factoryFromFile(message_parse, "message_fromWire11");
+    factoryFromFile(message_parse, "message_fromWire11.wire");
     EXPECT_EQ(0xfff, message_parse.getRcode().getCode());
 }
 
@@ -221,40 +320,23 @@
     message_parse.clear(Message::PARSE);
     EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire5"),
                  DNSMessageFORMERR);
-    // OPT RR of a non root name
-    message_parse.clear(Message::PARSE);
-    EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire6"),
-                 DNSMessageFORMERR);
-    // Compressed owner name of OPT RR points to a root name.
-    // Not necessarily bogus, but very unusual and mostly pathological.
-    // We accept it, but is it okay?
-    message_parse.clear(Message::PARSE);
-    EXPECT_NO_THROW(factoryFromFile(message_parse, "message_fromWire7"));
-    // Unsupported Version
-    message_parse.clear(Message::PARSE);
-    EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire9"),
-                 DNSMessageBADVERS);
 }
 
 TEST_F(MessageTest, toWire) {
     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;
@@ -262,4 +344,29 @@
     EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, obuffer.getData(),
                         obuffer.getLength(), &data[0], data.size());
 }
-}
+
+TEST_F(MessageTest, toWireInParseMode) {
+    // toWire() isn't allowed in the parse mode.
+    EXPECT_THROW(message_parse.toWire(renderer), InvalidMessageOperation);
+}
+
+TEST_F(MessageTest, toWireWithoutOpcode) {
+    message_render.setRcode(Rcode::NOERROR());
+    EXPECT_THROW(message_render.toWire(renderer), InvalidMessageOperation);
+}
+
+TEST_F(MessageTest, toWireWithoutRcode) {
+    message_render.setOpcode(Opcode::QUERY());
+    EXPECT_THROW(message_render.toWire(renderer), InvalidMessageOperation);
+}
+
+TEST_F(MessageTest, toTextWithoutOpcode) {
+    message_render.setRcode(Rcode::NOERROR());
+    EXPECT_THROW(message_render.toText(), InvalidMessageOperation);
+}
+
+TEST_F(MessageTest, toTextWithoutRcode) {
+    message_render.setOpcode(Opcode::QUERY());
+    EXPECT_THROW(message_render.toText(), InvalidMessageOperation);
+}
+}

Modified: experiments/327-sync/src/lib/dns/tests/messagerenderer_unittest.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/tests/messagerenderer_unittest.cc (original)
+++ experiments/327-sync/src/lib/dns/tests/messagerenderer_unittest.cc Tue Nov  9 10:38:17 2010
@@ -130,7 +130,7 @@
     // name compression in case sensitive manner.  See the data file
     // description for details.
     renderer.setCompressMode(MessageRenderer::CASE_SENSITIVE);
-    UnitTestUtil::readWireData("name_toWire5", data);
+    UnitTestUtil::readWireData("name_toWire5.wire", data);
     renderer.writeName(Name("a.example.com."));
     renderer.writeName(Name("b.eXample.com."));
     renderer.writeName(Name("c.eXample.com."));
@@ -140,7 +140,7 @@
 
 TEST_F(MessageRendererTest, writeNameMixedCaseCompress) {
     renderer.setCompressMode(MessageRenderer::CASE_SENSITIVE);
-    UnitTestUtil::readWireData("name_toWire6", data);
+    UnitTestUtil::readWireData("name_toWire6.wire", data);
     renderer.writeName(Name("a.example.com."));
     renderer.writeName(Name("b.eXample.com."));
 

Modified: experiments/327-sync/src/lib/dns/tests/name_unittest.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/tests/name_unittest.cc (original)
+++ experiments/327-sync/src/lib/dns/tests/name_unittest.cc Tue Nov  9 10:38:17 2010
@@ -84,8 +84,7 @@
 }
 
 Name
-NameTest::nameFactoryLowerCase()
-{
+NameTest::nameFactoryLowerCase() {
     string lowercase_namestr;
     lowercase_namestr.reserve(Name::MAX_WIRE);
 
@@ -124,8 +123,7 @@
                         buffer_expected.getData(), buffer_expected.getLength());
 }
 
-TEST_F(NameTest, nonlocalObject)
-{
+TEST_F(NameTest, nonlocalObject) {
     // A previous version of code relied on a non local static object for
     // name construction, so a non local static Name object defined outside
     // the name module might not be initialized correctly.  This test detects
@@ -133,8 +131,7 @@
     EXPECT_EQ("\\255.example.com.", downcased_global.toText());
 }
 
-TEST_F(NameTest, fromText)
-{
+TEST_F(NameTest, fromText) {
     vector<string> strnames;
     strnames.push_back("www.example.com");
     strnames.push_back("www.example.com."); // with a trailing dot
@@ -216,8 +213,7 @@
     EXPECT_EQ(Name::MAX_LABELS, maxlabels.getLabelCount());
 }
 
-TEST_F(NameTest, fromWire)
-{
+TEST_F(NameTest, fromWire) {
     //
     // test cases derived from BIND9 tests.
     //
@@ -271,8 +267,7 @@
     EXPECT_EQ(3, nameFactoryFromWire("name_fromWire1", 25).getLabelCount());
 }
 
-TEST_F(NameTest, copyConstruct)
-{
+TEST_F(NameTest, copyConstruct) {
     Name copy(example_name);
     EXPECT_EQ(copy, example_name);
 
@@ -283,8 +278,7 @@
     EXPECT_EQ(copy3, example_name);
 }
 
-TEST_F(NameTest, assignment)
-{
+TEST_F(NameTest, assignment) {
     Name copy(".");
     copy = example_name;
     EXPECT_EQ(copy, example_name);
@@ -301,8 +295,7 @@
     EXPECT_EQ(copy, example_name);
 }
 
-TEST_F(NameTest, toText)
-{
+TEST_F(NameTest, toText) {
     // tests derived from BIND9
     EXPECT_EQ("a.b.c.d", Name("a.b.c.d").toText(true));
     EXPECT_EQ("a.\\\\[[.c.d", Name("a.\\\\[\\[.c.d").toText(true));
@@ -349,31 +342,29 @@
               nameFactoryFromWire("name_fromWire14", 0).toText());
 }
 
-TEST_F(NameTest, toWireBuffer)
-{
+TEST_F(NameTest, toWireBuffer) {
     vector<unsigned char> data;
     OutputBuffer buffer(0);
 
     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());
 }
 
 //
 // We test various corner cases in Renderer tests, but add this test case
 // to fill the code coverage gap.
 //
-TEST_F(NameTest, toWireRenderer)
-{
+TEST_F(NameTest, toWireRenderer) {
     vector<unsigned char> data;
     OutputBuffer buffer(0);
     MessageRenderer renderer(buffer);
 
     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());
 }
 
 //
@@ -443,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: experiments/327-sync/src/lib/dns/tests/question_unittest.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/tests/question_unittest.cc (original)
+++ experiments/327-sync/src/lib/dns/tests/question_unittest.cc Tue Nov  9 10:38:17 2010
@@ -56,8 +56,7 @@
 };
 
 Question
-questionFromWire(const char* datafile, size_t position = 0)
-{
+questionFromWire(const char* datafile, size_t position = 0) {
     vector<unsigned char> data;
     UnitTestUtil::readWireData(datafile, data);
 
@@ -67,8 +66,7 @@
     return (Question(buffer));
 }
 
-TEST_F(QuestionTest, fromWire)
-{
+TEST_F(QuestionTest, fromWire) {
     Question q = questionFromWire("question_fromWire");
 
     EXPECT_EQ(example_name1, q.getName());
@@ -88,14 +86,12 @@
     EXPECT_THROW(questionFromWire("question_fromWire", 36), IncompleteRRClass);
 }
 
-TEST_F(QuestionTest, toText)
-{
+TEST_F(QuestionTest, toText) {
     EXPECT_EQ("foo.example.com. IN NS\n", test_question1.toText());
     EXPECT_EQ("bar.example.com. CH A\n", test_question2.toText());
 }
 
-TEST_F(QuestionTest, toWireBuffer)
-{
+TEST_F(QuestionTest, toWireBuffer) {
     test_question1.toWire(obuffer);
     test_question2.toWire(obuffer);
     UnitTestUtil::readWireData("question_toWire1", wiredata);
@@ -103,8 +99,7 @@
                         obuffer.getLength(), &wiredata[0], wiredata.size());
 }
 
-TEST_F(QuestionTest, toWireRenderer)
-{
+TEST_F(QuestionTest, toWireRenderer) {
     test_question1.toWire(renderer);
     test_question2.toWire(renderer);
     UnitTestUtil::readWireData("question_toWire2", wiredata);
@@ -113,15 +108,13 @@
 }
 
 // test operator<<.  We simply confirm it appends the result of toText().
-TEST_F(QuestionTest, LeftShiftOperator)
-{
+TEST_F(QuestionTest, LeftShiftOperator) {
     ostringstream oss;
     oss << test_question1;
     EXPECT_EQ(test_question1.toText(), oss.str());
 }
 
-TEST_F(QuestionTest, comparison)
-{
+TEST_F(QuestionTest, comparison) {
     const Name a("a"), b("b");
     const RRClass in(RRClass::IN()), ch(RRClass::CH());
     const RRType ns(RRType::NS()), aaaa(RRType::AAAA());

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

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

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

Modified: experiments/327-sync/src/lib/dns/tests/rdata_nsec_unittest.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/tests/rdata_nsec_unittest.cc (original)
+++ experiments/327-sync/src/lib/dns/tests/rdata_nsec_unittest.cc Tue Nov  9 10:38:17 2010
@@ -70,39 +70,39 @@
 
     // A malformed NSEC bitmap length field that could cause overflow.
     EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
-                                      "rdata_nsec_fromWire4"),
+                                      "rdata_nsec_fromWire4.wire"),
                  DNSMessageFORMERR);
 
     // The bitmap field is incomplete (only the first byte is included)
     EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
-                                      "rdata_nsec_fromWire5"),
+                                      "rdata_nsec_fromWire5.wire"),
                  DNSMessageFORMERR);
 
     // Bitmap length is 0, which is invalid.
     EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
-                                      "rdata_nsec_fromWire6"),
+                                      "rdata_nsec_fromWire6.wire"),
                  DNSMessageFORMERR);
 
     // A boundary case: longest possible bitmaps (32 maps).  This should be
     // accepted.
     EXPECT_NO_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
-                                         "rdata_nsec_fromWire7"));
+                                         "rdata_nsec_fromWire7.wire"));
 
     // Another boundary condition: 33 bitmaps, which should be rejected.
     EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
-                                      "rdata_nsec_fromWire8"),
+                                      "rdata_nsec_fromWire8.wire"),
                  DNSMessageFORMERR);
 
     // Disordered bitmap window blocks.
     EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
-                                      "rdata_nsec_fromWire9"),
+                                      "rdata_nsec_fromWire9.wire"),
                  DNSMessageFORMERR);
 
     // Bitmap ending with all-zero bytes.  Not necessarily harmful except
     // the additional overhead of parsing, but invalid according to the
     // spec anyway.
     EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
-                                      "rdata_nsec_fromWire10"),
+                                      "rdata_nsec_fromWire10.wire"),
                  DNSMessageFORMERR);
 }
 

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

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

Modified: experiments/327-sync/src/lib/dns/tests/rdata_rrsig_unittest.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/tests/rdata_rrsig_unittest.cc (original)
+++ experiments/327-sync/src/lib/dns/tests/rdata_rrsig_unittest.cc Tue Nov  9 10:38:17 2010
@@ -131,7 +131,7 @@
 
     // RDLEN is too short
     EXPECT_THROW(rdataFactoryFromFile(RRType::RRSIG(), RRClass::IN(),
-                                      "rdata_rrsig_fromWire2"),
+                                      "rdata_rrsig_fromWire2.wire"),
                  InvalidRdataLength);
 }
 }

Modified: experiments/327-sync/src/lib/dns/tests/rdata_soa_unittest.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/tests/rdata_soa_unittest.cc (original)
+++ experiments/327-sync/src/lib/dns/tests/rdata_soa_unittest.cc Tue Nov  9 10:38:17 2010
@@ -65,7 +65,7 @@
     obuffer.skip(2);
     rdata_soa.toWire(obuffer);
     vector<unsigned char> data;
-    UnitTestUtil::readWireData("rdata_soa_toWireUncompressed", data);
+    UnitTestUtil::readWireData("rdata_soa_toWireUncompressed.wire", data);
     EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                         static_cast<const uint8_t *>(obuffer.getData()) + 2,
                         obuffer.getLength() - 2, &data[2], data.size() - 2);

Modified: experiments/327-sync/src/lib/dns/tests/rdata_txt_unittest.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/tests/rdata_txt_unittest.cc (original)
+++ experiments/327-sync/src/lib/dns/tests/rdata_txt_unittest.cc Tue Nov  9 10:38:17 2010
@@ -109,12 +109,12 @@
     // Empty character string
     EXPECT_EQ(0, rdata_txt_empty.compare(
                   *rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
-                                        "rdata_txt_fromWire2")));
+                                        "rdata_txt_fromWire2.wire")));
 
     // Multiple character strings
     obuffer.clear();
     rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
-                         "rdata_txt_fromWire3")->toWire(obuffer);
+                         "rdata_txt_fromWire3.wire")->toWire(obuffer);
     // the result should be 'wiredata_txt' repeated twice
     vector<uint8_t> expected_data(wiredata_txt, wiredata_txt +
                                   sizeof(wiredata_txt));
@@ -145,12 +145,12 @@
 
     // RDATA is empty, which is invalid for TXT.
     EXPECT_THROW(rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
-                                      "rdata_txt_fromWire4"),
+                                      "rdata_txt_fromWire4.wire"),
                  DNSMessageFORMERR);
 
     // character-string length is too large, which could cause overrun.
     EXPECT_THROW(rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
-                                      "rdata_txt_fromWire5"),
+                                      "rdata_txt_fromWire5.wire"),
                  DNSMessageFORMERR);
 }
 

Modified: experiments/327-sync/src/lib/dns/tests/rdata_unittest.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/tests/rdata_unittest.cc (original)
+++ experiments/327-sync/src/lib/dns/tests/rdata_unittest.cc Tue Nov  9 10:38:17 2010
@@ -68,8 +68,7 @@
 };
 
 string
-Rdata_Unknown_Test::getLongestRdataTxt()
-{
+Rdata_Unknown_Test::getLongestRdataTxt() {
     ostringstream oss;
 
     oss << "\\# " << MAX_RDLENGTH << " ";
@@ -83,8 +82,7 @@
 }
 
 void
-Rdata_Unknown_Test::getLongestRdataWire(vector<uint8_t>& v)
-{
+Rdata_Unknown_Test::getLongestRdataWire(vector<uint8_t>& v) {
     unsigned char ch = 0;
     for (int i = 0; i < MAX_RDLENGTH; ++i, ++ch) {
         v.push_back(ch);
@@ -102,8 +100,7 @@
 // renumber it.
 const RRType unknown_rrtype = RRType(65000);
 
-TEST_F(Rdata_Unknown_Test, createFromText)
-{
+TEST_F(Rdata_Unknown_Test, createFromText) {
     // valid construction.  This also tests a normal case of "FromWire".
     EXPECT_EQ(0, generic::Generic("\\# 4 a1b2c30d").compare(
                   *rdataFactoryFromFile(unknown_rrtype, RRClass::IN(),
@@ -148,8 +145,7 @@
     EXPECT_THROW(generic::Generic("\\# 1ff"), InvalidRdataText);
 }
 
-TEST_F(Rdata_Unknown_Test, createFromWire)
-{
+TEST_F(Rdata_Unknown_Test, createFromWire) {
     // normal case (including 0-length data) is covered in createFromText.
 
     // buffer too short.  the error should be detected in buffer read
@@ -167,8 +163,7 @@
 
 // The following 3 sets of tests check the behavior of createRdata() variants
 // with the "unknown" RRtype.  The result should be RRclass independent.
-TEST_F(Rdata_Unknown_Test, createRdataFromString)
-{
+TEST_F(Rdata_Unknown_Test, createRdataFromString) {
     EXPECT_EQ(0, rdata_unknown.compare(
                   *createRdata(unknown_rrtype, RRClass::IN(),
                                rdata_unknowntxt)));
@@ -180,8 +175,7 @@
                                rdata_unknowntxt)));
 }
 
-TEST_F(Rdata_Unknown_Test, createRdataFromWire)
-{
+TEST_F(Rdata_Unknown_Test, createRdataFromWire) {
     InputBuffer ibuffer(wiredata_unknown, sizeof(wiredata_unknown));
     EXPECT_EQ(0, rdata_unknown.compare(
                   *createRdata(unknown_rrtype, RRClass::IN(),
@@ -198,8 +192,7 @@
                                ibuffer3, sizeof(wiredata_unknown))));
 }
 
-TEST_F(Rdata_Unknown_Test, createRdataByCopy)
-{
+TEST_F(Rdata_Unknown_Test, createRdataByCopy) {
     EXPECT_EQ(0, rdata_unknown.compare(
                   *createRdata(unknown_rrtype, RRClass::IN(), rdata_unknown)));
     EXPECT_EQ(0, rdata_unknown.compare(
@@ -209,8 +202,7 @@
                                rdata_unknown)));
 }
 
-TEST_F(Rdata_Unknown_Test, copyConstruct)
-{
+TEST_F(Rdata_Unknown_Test, copyConstruct) {
     generic::Generic copy(rdata_unknown);
     EXPECT_EQ(0, copy.compare(rdata_unknown));
 
@@ -221,8 +213,7 @@
     EXPECT_EQ(0, copy3.compare(rdata_unknown));
 }
 
-TEST_F(Rdata_Unknown_Test, assignment)
-{
+TEST_F(Rdata_Unknown_Test, assignment) {
     generic::Generic copy("\\# 1 10");
     copy = rdata_unknown;
     EXPECT_EQ(0, copy.compare(rdata_unknown));
@@ -239,31 +230,27 @@
     EXPECT_EQ(0, copy.compare(rdata_unknown));
 }
 
-TEST_F(Rdata_Unknown_Test, toText)
-{
+TEST_F(Rdata_Unknown_Test, toText) {
     EXPECT_EQ(rdata_unknowntxt, rdata_unknown.toText());
     EXPECT_EQ(getLongestRdataTxt(),
               generic::Generic(getLongestRdataTxt()).toText());
 }
 
-TEST_F(Rdata_Unknown_Test, toWireBuffer)
-{
+TEST_F(Rdata_Unknown_Test, toWireBuffer) {
     rdata_unknown.toWire(obuffer);
     EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                         obuffer.getData(), obuffer.getLength(),
                         wiredata_unknown, sizeof(wiredata_unknown));
 }
 
-TEST_F(Rdata_Unknown_Test, toWireRenderer)
-{
+TEST_F(Rdata_Unknown_Test, toWireRenderer) {
     rdata_unknown.toWire(renderer);
     EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                         obuffer.getData(), obuffer.getLength(),
                         wiredata_unknown, sizeof(wiredata_unknown));
 }
 
-TEST_F(Rdata_Unknown_Test, compare)
-{
+TEST_F(Rdata_Unknown_Test, compare) {
     // comparison as left-justified unsigned octet sequences:
     EXPECT_EQ(0, rdata_unknown.compare(rdata_unknown));
 
@@ -281,8 +268,7 @@
     EXPECT_LT(0, rdata_unknown.compare(rdata_unknown_short));
 }
 
-TEST_F(Rdata_Unknown_Test, LeftShiftOperator)
-{
+TEST_F(Rdata_Unknown_Test, LeftShiftOperator) {
     ostringstream oss;
     oss << rdata_unknown;
     EXPECT_EQ(rdata_unknown.toText(), oss.str());
@@ -291,14 +277,13 @@
 //
 // Tests for global utility functions
 //
-TEST_F(RdataTest, compareNames)
-{
+TEST_F(RdataTest, compareNames) {
     Name small("a.example");
     Name large("example");
 
     // 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: experiments/327-sync/src/lib/dns/tests/rrclass_unittest.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/tests/rrclass_unittest.cc (original)
+++ experiments/327-sync/src/lib/dns/tests/rrclass_unittest.cc Tue Nov  9 10:38:17 2010
@@ -51,8 +51,7 @@
                                           0x00, 0x80, 0x00, 0xff, 0xff };
 
 RRClass
-RRClassTest::rrclassFactoryFromWire(const char* datafile)
-{
+RRClassTest::rrclassFactoryFromWire(const char* datafile) {
     std::vector<unsigned char> data;
     UnitTestUtil::readWireData(datafile, data);
 
@@ -61,8 +60,7 @@
     return (RRClass(buffer));
 }
 
-TEST_F(RRClassTest, fromText)
-{
+TEST_F(RRClassTest, fromText) {
     EXPECT_EQ("IN", RRClass("IN").toText());
     EXPECT_EQ("CH", RRClass("CH").toText());
 
@@ -81,29 +79,25 @@
     EXPECT_THROW(RRClass("CLASS65000 "), InvalidRRClass);
 }
 
-TEST_F(RRClassTest, fromWire)
-{
+TEST_F(RRClassTest, fromWire) {
     EXPECT_EQ(0x1234,
               rrclassFactoryFromWire("rrcode16_fromWire1").getCode());
     EXPECT_THROW(rrclassFactoryFromWire("rrcode16_fromWire2"),
                  IncompleteRRClass);
 }
 
-TEST_F(RRClassTest, caseConstruct)
-{
+TEST_F(RRClassTest, caseConstruct) {
     EXPECT_EQ("IN", RRClass("in").toText());
     EXPECT_EQ("CH", RRClass("ch").toText());
     EXPECT_EQ("CLASS65535", RRClass("class65535").toText());
 }
 
-TEST_F(RRClassTest, toText)
-{
+TEST_F(RRClassTest, toText) {
     EXPECT_EQ("IN", RRClass(1).toText());
     EXPECT_EQ("CLASS65000", RRClass(65000).toText());
 }
 
-TEST_F(RRClassTest, toWireBuffer)
-{
+TEST_F(RRClassTest, toWireBuffer) {
     rrclass_1.toWire(obuffer);
     rrclass_0x80.toWire(obuffer);
     rrclass_0x800.toWire(obuffer);
@@ -115,8 +109,7 @@
                         wiredata, sizeof(wiredata));
 }
 
-TEST_F(RRClassTest, toWireRenderer)
-{
+TEST_F(RRClassTest, toWireRenderer) {
     rrclass_1.toWire(renderer);
     rrclass_0x80.toWire(renderer);
     rrclass_0x800.toWire(renderer);
@@ -128,14 +121,12 @@
                         wiredata, sizeof(wiredata));
 }
 
-TEST_F(RRClassTest, wellKnownClasss)
-{
+TEST_F(RRClassTest, wellKnownClasss) {
     EXPECT_EQ(1, RRClass::IN().getCode());
     EXPECT_EQ("IN", RRClass::IN().toText());
 }
 
-TEST_F(RRClassTest, compare)
-{
+TEST_F(RRClassTest, compare) {
     EXPECT_TRUE(RRClass(1) == RRClass("IN"));
     EXPECT_TRUE(RRClass(1).equals(RRClass("IN")));
     EXPECT_TRUE(RRClass(0).nequals(RRClass("IN")));
@@ -145,8 +136,7 @@
 }
 
 // test operator<<.  We simply confirm it appends the result of toText().
-TEST_F(RRClassTest, LeftShiftOperator)
-{
+TEST_F(RRClassTest, LeftShiftOperator) {
     ostringstream oss;
     oss << RRClass::IN();
     EXPECT_EQ(RRClass::IN().toText(), oss.str());

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

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

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

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

Modified: experiments/327-sync/src/lib/dns/tests/run_unittests.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/tests/run_unittests.cc (original)
+++ experiments/327-sync/src/lib/dns/tests/run_unittests.cc Tue Nov  9 10:38:17 2010
@@ -21,7 +21,8 @@
 int
 main(int argc, char* argv[]) {
     ::testing::InitGoogleTest(&argc, argv);
-    isc::UnitTestUtil::addDataPath(TEST_DATA_DIR);
+    isc::UnitTestUtil::addDataPath(TEST_DATA_SRCDIR);
+    isc::UnitTestUtil::addDataPath(TEST_DATA_BUILDDIR);
 
     return (RUN_ALL_TESTS());
 }

Modified: experiments/327-sync/src/lib/dns/tests/testdata/gen-wiredata.py.in
==============================================================================
--- experiments/327-sync/src/lib/dns/tests/testdata/gen-wiredata.py.in (original)
+++ experiments/327-sync/src/lib/dns/tests/testdata/gen-wiredata.py.in Tue Nov  9 10:38:17 2010
@@ -19,9 +19,9 @@
 from datetime import datetime
 from optparse import OptionParser
 
-re_hex = re.compile('0x[0-9a-fA-F]+')
-re_decimal = re.compile('\d+$')
-re_string = re.compile("\'(.*)\'$")
+re_hex = re.compile(r'0x[0-9a-fA-F]+')
+re_decimal = re.compile(r'\d+$')
+re_string = re.compile(r"\'(.*)\'$")
 
 dnssec_timefmt = '%Y%m%d%H%M%S'
 
@@ -365,9 +365,6 @@
     parser.add_option('-o', '--output', action='store', dest='output',
                       default=None, metavar='FILE',
                       help='output file name [default: prefix of input_file]')
-    parser.add_option('-m', '--mode', action='store', dest='mode',
-                      default='message', metavar='[message|custom]',
-                      help='specify dump mode [default: %default]')
     (options, args) = parser.parse_args()
 
     if len(args) == 0:
@@ -389,9 +386,10 @@
 
     print_header(output, configfile)
 
-    if options.mode == 'custom':
+    # First try the 'custom' mode; if it fails assume the standard mode.
+    try:
         sections = config.get('custom', 'sections').split(':')
-    else:
+    except configparser.NoSectionError:
         sections = ['header', 'question', 'edns']
 
     for s in sections:

Modified: experiments/327-sync/src/lib/dns/util/sha1.cc
==============================================================================
--- experiments/327-sync/src/lib/dns/util/sha1.cc (original)
+++ experiments/327-sync/src/lib/dns/util/sha1.cc Tue Nov  9 10:38:17 2010
@@ -312,8 +312,7 @@
  *   sha Error Code.
  *
  */
-static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte)
-{
+static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte) {
     int i;
     SHA1PadMessage(context, Pad_Byte);
     /* message may be sensitive, clear it out */
@@ -350,8 +349,7 @@
  *      Nothing.
  *
  */
-static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte)
-{
+static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte) {
     /*
      * Check to see if the current message block is too small to hold
      * the initial padding bits and length. If so, we will pad the

Modified: experiments/327-sync/src/lib/exceptions/exceptions.cc
==============================================================================
--- experiments/327-sync/src/lib/exceptions/exceptions.cc (original)
+++ experiments/327-sync/src/lib/exceptions/exceptions.cc Tue Nov  9 10:38:17 2010
@@ -23,8 +23,7 @@
 namespace isc {
 
 const char*
-Exception::what() const throw()
-{
+Exception::what() const throw() {
     const char* whatstr = "isc::Exception";
 
     // XXX: even though it's very unlikely that c_str() throws an exception,

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

Modified: experiments/327-sync/src/lib/exceptions/tests/run_unittests.cc
==============================================================================
--- experiments/327-sync/src/lib/exceptions/tests/run_unittests.cc (original)
+++ experiments/327-sync/src/lib/exceptions/tests/run_unittests.cc Tue Nov  9 10:38:17 2010
@@ -17,8 +17,7 @@
 #include <gtest/gtest.h>
 
 int
-main(int argc, char* argv[])
-{
+main(int argc, char* argv[]) {
     ::testing::InitGoogleTest(&argc, argv);
     return (RUN_ALL_TESTS());
 }

Modified: experiments/327-sync/src/lib/python/isc/Makefile.am
==============================================================================
--- experiments/327-sync/src/lib/python/isc/Makefile.am (original)
+++ experiments/327-sync/src/lib/python/isc/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,4 +1,4 @@
-SUBDIRS = datasrc cc config log notify # Util
+SUBDIRS = datasrc cc config log net notify util 
 
 python_PYTHON = __init__.py
 

Modified: experiments/327-sync/src/lib/python/isc/cc/Makefile.am
==============================================================================
--- experiments/327-sync/src/lib/python/isc/cc/Makefile.am (original)
+++ experiments/327-sync/src/lib/python/isc/cc/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 python_PYTHON =	__init__.py data.py session.py message.py
 

Modified: experiments/327-sync/src/lib/python/isc/cc/data.py
==============================================================================
--- experiments/327-sync/src/lib/python/isc/cc/data.py (original)
+++ experiments/327-sync/src/lib/python/isc/cc/data.py Tue Nov  9 10:38:17 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,17 +41,20 @@
        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 find(element, identifier):
     """Returns the subelement in the given data element, raises DataNotFoundError if not found"""

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

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

Modified: experiments/327-sync/src/lib/python/isc/config/Makefile.am
==============================================================================
--- experiments/327-sync/src/lib/python/isc/config/Makefile.am (original)
+++ experiments/327-sync/src/lib/python/isc/config/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 python_PYTHON = __init__.py ccsession.py cfgmgr.py config_data.py module_spec.py
 

Modified: experiments/327-sync/src/lib/python/isc/config/ccsession.py
==============================================================================
--- experiments/327-sync/src/lib/python/isc/config/ccsession.py (original)
+++ experiments/327-sync/src/lib/python/isc/config/ccsession.py Tue Nov  9 10:38:17 2010
@@ -1,4 +1,5 @@
 # Copyright (C) 2009  Internet Systems Consortium.
+# Copyright (C) 2010  CZ NIC
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -169,18 +170,37 @@
            time-critical, it is strongly recommended to only use
            check_command(), and not look at the socket at all."""
         return self._session._socket
-    
+
     def close(self):
         """Close the session to the command channel"""
         self._session.close()
 
-    def check_command(self):
-        """Check whether there is a command or configuration update
-           on the channel. Call the corresponding callback function if
-           there is."""
-        msg, env = self._session.group_recvmsg(False)
+    def check_command(self, nonblock=True):
+        """Check whether there is a command or configuration update on
+           the channel. This function does a read on the cc session, and
+           returns nothing.
+           It calls check_command_without_recvmsg()
+           to parse the received message.
+           
+           If nonblock is True, it just checks if there's a command
+           and does nothing if there isn't. If nonblock is False, it
+           waits until it arrives. It temporarily sets timeout to infinity,
+           because commands may not come in arbitrary long time."""
+        timeout_orig = self._session.get_timeout()
+        self._session.set_timeout(0)
+        try:
+            msg, env = self._session.group_recvmsg(nonblock)
+        finally:
+            self._session.set_timeout(timeout_orig)
+        self.check_command_without_recvmsg(msg, env)
+
+    def check_command_without_recvmsg(self, msg, env):
+        """Parse the given message to see if there is a command or a
+           configuration update. Calls the corresponding handler
+           functions if present. Responds on the channel if the
+           handler returns a message.""" 
         # should we default to an answer? success-by-default? unhandled error?
-        if msg and not 'result' in msg:
+        if msg is not None and not 'result' in msg:
             answer = None
             try:
                 module_name = env['group']
@@ -196,7 +216,8 @@
                             newc = self._remote_module_configs[module_name].get_local_config()
                             isc.cc.data.merge(newc, new_config)
                             self._remote_module_configs[module_name].set_local_config(newc)
-                            return
+                        # For other modules, we're not supposed to answer
+                        return
 
                     # ok, so apparently this update is for us.
                     errors = []
@@ -244,6 +265,8 @@
            also subscribes to the channel of the remote module name
            to receive the relevant updates. It is not possible to
            specify your own handler for this right now.
+           start() must have been called on this CCSession
+           prior to the call to this method.
            Returns the name of the module."""
         module_spec = isc.config.module_spec_from_file(spec_file_name)
         module_cfg = ConfigData(module_spec)
@@ -252,7 +275,13 @@
 
         # Get the current config for that module now
         seq = self._session.group_sendmsg(create_command(COMMAND_GET_CONFIG, { "module_name": module_name }), "ConfigManager")
-        answer, env = self._session.group_recvmsg(False, seq)
+
+        try:
+            answer, env = self._session.group_recvmsg(False, seq)
+        except isc.cc.SessionTimeout:
+            raise ModuleCCSessionError("No answer from ConfigManager when "
+                                       "asking about Remote module " +
+                                       module_name)
         if answer:
             rcode, value = parse_answer(answer)
             if rcode == 0:
@@ -283,25 +312,32 @@
         """Sends the data specification to the configuration manager"""
         msg = create_command(COMMAND_MODULE_SPEC, self.get_module_spec().get_full_spec())
         seq = self._session.group_sendmsg(msg, "ConfigManager")
-        answer, env = self._session.group_recvmsg(False, seq)
+        try:
+            answer, env = self._session.group_recvmsg(False, seq)
+        except isc.cc.SessionTimeout:
+            # TODO: log an error?
+            pass
         
     def __request_config(self):
         """Asks the configuration manager for the current configuration, and call the config handler if set.
            Raises a ModuleCCSessionError if there is no answer from the configuration manager"""
         seq = self._session.group_sendmsg(create_command(COMMAND_GET_CONFIG, { "module_name": self._module_name }), "ConfigManager")
-        answer, env = self._session.group_recvmsg(False, seq)
-        if answer:
-            rcode, value = parse_answer(answer)
-            if rcode == 0:
-                if value != None and self.get_module_spec().validate_config(False, value):
-                    self.set_local_config(value);
-                    if self._config_handler:
-                        self._config_handler(value)
+        try:
+            answer, env = self._session.group_recvmsg(False, seq)
+            if answer:
+                rcode, value = parse_answer(answer)
+                if rcode == 0:
+                    if value != None and self.get_module_spec().validate_config(False, value):
+                        self.set_local_config(value);
+                        if self._config_handler:
+                            self._config_handler(value)
+                else:
+                    # log error
+                    print("[" + self._module_name + "] Error requesting configuration: " + value)
             else:
-                # log error
-                print("[" + self._module_name + "] Error requesting configuration: " + value)
-        else:
-            raise ModuleCCSessionError("No answer from configuration manager")
+                raise ModuleCCSessionError("No answer from configuration manager")
+        except isc.cc.SessionTimeout:
+            raise ModuleCCSessionError("CC Session timeout waiting for configuration manager")
 
 
 class UIModuleCCSession(MultiConfigData):

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

Modified: experiments/327-sync/src/lib/python/isc/config/module_spec.py
==============================================================================
--- experiments/327-sync/src/lib/python/isc/config/module_spec.py (original)
+++ experiments/327-sync/src/lib/python/isc/config/module_spec.py Tue Nov  9 10:38:17 2010
@@ -316,7 +316,9 @@
     item_name = spec['item_name']
     item_optional = spec['item_optional']
 
-    if item_name in data:
+    if not data and item_optional:
+        return True
+    elif item_name in data:
         return _validate_item(spec, full, data[item_name], errors)
     elif full and not item_optional:
         if errors != None:

Modified: experiments/327-sync/src/lib/python/isc/config/tests/Makefile.am
==============================================================================
--- experiments/327-sync/src/lib/python/isc/config/tests/Makefile.am (original)
+++ experiments/327-sync/src/lib/python/isc/config/tests/Makefile.am Tue Nov  9 10:38:17 2010
@@ -10,7 +10,7 @@
 	for pytest in $(PYTESTS) ; do \
 	echo Running test: $$pytest ; \
 	env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python \
-	CONFIG_TESTDATA_PATH=$(abs_top_srcdir)/src/lib/config/testdata \
-	CONFIG_WR_TESTDATA_PATH=$(abs_top_builddir)/src/lib/config/testdata \
+	CONFIG_TESTDATA_PATH=$(abs_top_srcdir)/src/lib/config/tests/testdata \
+	CONFIG_WR_TESTDATA_PATH=$(abs_top_builddir)/src/lib/config/tests/testdata \
 	$(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
 	done

Modified: experiments/327-sync/src/lib/python/isc/config/tests/ccsession_test.py
==============================================================================
--- experiments/327-sync/src/lib/python/isc/config/tests/ccsession_test.py (original)
+++ experiments/327-sync/src/lib/python/isc/config/tests/ccsession_test.py Tue Nov  9 10:38:17 2010
@@ -23,7 +23,7 @@
 import os
 from isc.config.ccsession import *
 from isc.config.config_data import BIND10_CONFIG_DATA_VERSION
-from unittest_fakesession import FakeModuleCCSession
+from unittest_fakesession import FakeModuleCCSession, WouldBlockForever
 
 class TestHelperFunctions(unittest.TestCase):
     def test_parse_answer(self):
@@ -125,6 +125,8 @@
         self.assertTrue("Spec1" in fake_session.subscriptions)
 
         self.assertEqual(len(fake_session.message_queue), 0)
+        fake_session.group_sendmsg(None, 'Spec1')
+        fake_session.group_sendmsg(None, 'Spec1')
         self.assertRaises(ModuleCCSessionError, mccs.start)
         self.assertEqual(len(fake_session.message_queue), 2)
         self.assertEqual({'command': ['module_spec', {'module_name': 'Spec1'}]},
@@ -150,6 +152,8 @@
         fake_session = FakeModuleCCSession()
         mccs = self.create_session("spec2.spec", None, None, fake_session)
         self.assertEqual(len(fake_session.message_queue), 0)
+        fake_session.group_sendmsg(None, 'Spec2')
+        fake_session.group_sendmsg(None, 'Spec2')
         self.assertRaises(ModuleCCSessionError, mccs.start)
         self.assertEqual(len(fake_session.message_queue), 2)
         self.assertEqual({'command': ['module_spec', mccs.specification._module_spec]},
@@ -173,6 +177,8 @@
         mccs = self.create_session("spec2.spec", None, None, fake_session)
         mccs.set_config_handler(self.my_config_handler_ok)
         self.assertEqual(len(fake_session.message_queue), 0)
+        fake_session.group_sendmsg(None, 'Spec2')
+        fake_session.group_sendmsg(None, 'Spec2')
         self.assertRaises(ModuleCCSessionError, mccs.start)
         self.assertEqual(len(fake_session.message_queue), 2)
         self.assertEqual({'command': ['module_spec', mccs.specification._module_spec]},
@@ -196,6 +202,8 @@
         mccs = self.create_session("spec2.spec", None, None, fake_session)
         mccs.set_config_handler(self.my_config_handler_ok)
         self.assertEqual(len(fake_session.message_queue), 0)
+        fake_session.group_sendmsg(None, 'Spec2')
+        fake_session.group_sendmsg(None, 'Spec2')
         self.assertRaises(ModuleCCSessionError, mccs.start)
         self.assertEqual(len(fake_session.message_queue), 2)
         self.assertEqual({'command': ['module_spec', mccs.specification._module_spec]},
@@ -327,30 +335,173 @@
         self.assertEqual(len(fake_session.message_queue), 1)
         self.assertEqual({'result': [2, 'Spec2 has no command handler']},
                          fake_session.get_message('Spec2', None))
-        
-    def test_check_command7(self):
-        fake_session = FakeModuleCCSession()
-        mccs = self.create_session("spec2.spec", None, None, fake_session)
-        mccs.set_command_handler(self.my_command_handler_ok)
+
+    """Many check_command tests look too similar, this is common body."""
+    def common_check_command_check(self, cmd_handler,
+            cmd_check=lambda mccs, _: mccs.check_command()):
+        fake_session = FakeModuleCCSession()
+        mccs = self.create_session("spec2.spec", None, None, fake_session)
+        mccs.set_command_handler(cmd_handler)
         self.assertEqual(len(fake_session.message_queue), 0)
         cmd = isc.config.ccsession.create_command("print_message", "just a message")
         fake_session.group_sendmsg(cmd, 'Spec2')
         self.assertEqual(len(fake_session.message_queue), 1)
-        mccs.check_command()
+        cmd_check(mccs, fake_session)
+        return fake_session
+
+    def test_check_command7(self):
+        fake_session = self.common_check_command_check(
+            self.my_command_handler_ok)
         self.assertEqual(len(fake_session.message_queue), 1)
         self.assertEqual({'result': [0]},
                          fake_session.get_message('Spec2', None))
-        
+
     def test_check_command8(self):
-        fake_session = FakeModuleCCSession()
-        mccs = self.create_session("spec2.spec", None, None, fake_session)
-        mccs.set_command_handler(self.my_command_handler_no_answer)
+        fake_session = self.common_check_command_check(
+            self.my_command_handler_no_answer)
+        self.assertEqual(len(fake_session.message_queue), 0)
+
+    def test_check_command_block(self):
+        """See if the message gets there even in blocking mode."""
+        fake_session = self.common_check_command_check(
+            self.my_command_handler_ok,
+            lambda mccs, _: mccs.check_command(False))
+        self.assertEqual(len(fake_session.message_queue), 1)
+        self.assertEqual({'result': [0]},
+                         fake_session.get_message('Spec2', None))
+
+    def test_check_command_block_timeout(self):
+        """Check it works if session has timeout and it sets it back."""
+        def cmd_check(mccs, session):
+            session.set_timeout(1)
+            mccs.check_command(False)
+        fake_session = self.common_check_command_check(
+            self.my_command_handler_ok, cmd_check)
+        self.assertEqual(len(fake_session.message_queue), 1)
+        self.assertEqual({'result': [0]},
+                         fake_session.get_message('Spec2', None))
+        self.assertEqual(fake_session.get_timeout(), 1)
+
+    def test_check_command_blocks_forever(self):
+        """Check it would wait forever checking a command."""
+        fake_session = FakeModuleCCSession()
+        mccs = self.create_session("spec2.spec", None, None, fake_session)
+        mccs.set_command_handler(self.my_command_handler_ok)
+        self.assertRaises(WouldBlockForever, lambda: mccs.check_command(False))
+
+    def test_check_command_blocks_forever_timeout(self):
+        """Like above, but it should wait forever even with timeout here."""
+        fake_session = FakeModuleCCSession()
+        fake_session.set_timeout(1)
+        mccs = self.create_session("spec2.spec", None, None, fake_session)
+        mccs.set_command_handler(self.my_command_handler_ok)
+        self.assertRaises(WouldBlockForever, lambda: mccs.check_command(False))
+
+    def test_check_command_without_recvmsg1(self):
+        "copied from test_check_command2"
+        fake_session = FakeModuleCCSession()
+        mccs = self.create_session("spec1.spec", None, None, fake_session)
+        mccs.set_config_handler(self.my_config_handler_ok)
+        self.assertEqual(len(fake_session.message_queue), 0)
+        cmd = isc.config.ccsession.create_command(isc.config.ccsession.COMMAND_CONFIG_UPDATE, { 'Spec1': 'abcd' })
+        env = { 'group': 'Spec1', 'from':None };
+        mccs.check_command_without_recvmsg(cmd, env)
+        self.assertEqual(len(fake_session.message_queue), 1)
+        self.assertEqual({'result': [1, 'No config_data specification']},
+                         fake_session.get_message('Spec1', None))
+ 
+    def test_check_command_without_recvmsg2(self):
+        "copied from test_check_command3"
+        fake_session = FakeModuleCCSession()
+        mccs = self.create_session("spec2.spec", None, None, fake_session)
+        mccs.set_config_handler(self.my_config_handler_ok)
+        self.assertEqual(len(fake_session.message_queue), 0)
+        cmd = isc.config.ccsession.create_command(isc.config.ccsession.COMMAND_CONFIG_UPDATE, { 'Spec2': { 'item1': 2 }})
+        self.assertEqual(len(fake_session.message_queue), 0)
+        env = { 'group':'Spec2', 'from':None }
+        mccs.check_command_without_recvmsg(cmd, env)
+        self.assertEqual(len(fake_session.message_queue), 1)
+        self.assertEqual({'result': [0]},
+                          fake_session.get_message('Spec2', None))
+ 
+    def test_check_command_without_recvmsg3(self):
+        "copied from test_check_command7"
+        fake_session = FakeModuleCCSession()
+        mccs = self.create_session("spec2.spec", None, None, fake_session)
+        mccs.set_command_handler(self.my_command_handler_ok)
         self.assertEqual(len(fake_session.message_queue), 0)
         cmd = isc.config.ccsession.create_command("print_message", "just a message")
-        fake_session.group_sendmsg(cmd, 'Spec2')
-        self.assertEqual(len(fake_session.message_queue), 1)
-        mccs.check_command()
-        self.assertEqual(len(fake_session.message_queue), 0)
+        env = { 'group':'Spec2', 'from':None }
+        self.assertEqual(len(fake_session.message_queue), 0)
+        mccs.check_command_without_recvmsg(cmd, env)
+        self.assertEqual({'result': [0]},
+                         fake_session.get_message('Spec2', None))
+ 
+    def test_check_command_without_recvmsg_remote_module(self):
+        "copied from test_check_command3"
+        fake_session = FakeModuleCCSession()
+        mccs = self.create_session("spec1.spec", None, None, fake_session)
+        mccs.set_config_handler(self.my_config_handler_ok)
+        self.assertEqual(len(fake_session.message_queue), 0)
+
+        fake_session.group_sendmsg(None, 'Spec2')
+        rmodname = mccs.add_remote_config(self.spec_file("spec2.spec"))
+        print(fake_session.message_queue)
+        self.assertEqual({'command': ['get_config', {'module_name': 'Spec2'}]},
+                         fake_session.get_message('ConfigManager', None))
+        self.assertEqual(len(fake_session.message_queue), 0)
+
+        cmd = isc.config.ccsession.create_command(isc.config.ccsession.COMMAND_CONFIG_UPDATE, { 'Spec2': { 'item1': 2 }})
+        env = { 'group':'Spec2', 'from':None }
+        self.assertEqual(len(fake_session.message_queue), 0)
+        mccs.check_command_without_recvmsg(cmd, env)
+        self.assertEqual(len(fake_session.message_queue), 0)
+ 
+    def test_check_command_without_recvmsg_remote_module2(self):
+        "copied from test_check_command3"
+        fake_session = FakeModuleCCSession()
+        mccs = self.create_session("spec1.spec", None, None, fake_session)
+        mccs.set_config_handler(self.my_config_handler_ok)
+        self.assertEqual(len(fake_session.message_queue), 0)
+
+        fake_session.group_sendmsg(None, 'Spec2')
+        rmodname = mccs.add_remote_config(self.spec_file("spec2.spec"))
+        self.assertEqual({'command': ['get_config', {'module_name': 'Spec2'}]},
+                         fake_session.get_message('ConfigManager', None))
+        self.assertEqual(len(fake_session.message_queue), 0)
+
+        cmd = isc.config.ccsession.create_command(isc.config.ccsession.COMMAND_CONFIG_UPDATE, { 'Spec3': { 'item1': 2 }})
+        env = { 'group':'Spec3', 'from':None }
+        self.assertEqual(len(fake_session.message_queue), 0)
+        mccs.check_command_without_recvmsg(cmd, env)
+        self.assertEqual(len(fake_session.message_queue), 0)
+ 
+    def test_check_command_block_timeout(self):
+        """Check it works if session has timeout and it sets it back."""
+        def cmd_check(mccs, session):
+            session.set_timeout(1)
+            mccs.check_command(False)
+        fake_session = self.common_check_command_check(
+            self.my_command_handler_ok, cmd_check)
+        self.assertEqual(len(fake_session.message_queue), 1)
+        self.assertEqual({'result': [0]},
+                         fake_session.get_message('Spec2', None))
+        self.assertEqual(fake_session.get_timeout(), 1)
+
+    def test_check_command_blocks_forever(self):
+        """Check it would wait forever checking a command."""
+        fake_session = FakeModuleCCSession()
+        mccs = self.create_session("spec2.spec", None, None, fake_session)
+        mccs.set_command_handler(self.my_command_handler_ok)
+        self.assertRaises(WouldBlockForever, lambda: mccs.check_command(False))
+
+    def test_check_command_blocks_forever_timeout(self):
+        """Like above, but it should wait forever even with timeout here."""
+        fake_session = FakeModuleCCSession()
+        fake_session.set_timeout(1)
+        mccs = self.create_session("spec2.spec", None, None, fake_session)
+        mccs.set_command_handler(self.my_command_handler_ok)
+        self.assertRaises(WouldBlockForever, lambda: mccs.check_command(False))
 
     def test_remote_module(self):
         fake_session = FakeModuleCCSession()
@@ -360,6 +511,7 @@
         self.assertRaises(ModuleCCSessionError, mccs.get_remote_config_value, "Spec2", "item1")
 
         self.assertFalse("Spec2" in fake_session.subscriptions)
+        fake_session.group_sendmsg(None, 'Spec2')
         rmodname = mccs.add_remote_config(self.spec_file("spec2.spec"))
         self.assertTrue("Spec2" in fake_session.subscriptions)
         self.assertEqual("Spec2", rmodname)
@@ -373,6 +525,7 @@
         self.assertRaises(ModuleCCSessionError, mccs.get_remote_config_value, "Spec2", "item1")
 
         # test if unsubscription is alse sent when object is deleted
+        fake_session.group_sendmsg({'result' : [0]}, 'Spec2')
         rmodname = mccs.add_remote_config(self.spec_file("spec2.spec"))
         self.assertTrue("Spec2" in fake_session.subscriptions)
         mccs = None
@@ -383,6 +536,7 @@
         fake_session = FakeModuleCCSession()
         mccs = self.create_session("spec1.spec", None, None, fake_session)
         mccs.set_command_handler(self.my_command_handler_ok)
+        fake_session.group_sendmsg(None, 'Spec2')
         rmodname = mccs.add_remote_config(self.spec_file("spec2.spec"))
 
         # remove the 'get config' from the queue

Modified: experiments/327-sync/src/lib/python/isc/config/tests/cfgmgr_test.py
==============================================================================
--- experiments/327-sync/src/lib/python/isc/config/tests/cfgmgr_test.py (original)
+++ experiments/327-sync/src/lib/python/isc/config/tests/cfgmgr_test.py Tue Nov  9 10:38:17 2010
@@ -255,6 +255,7 @@
                          self.fake_session.get_message(self.name, None))
         self.assertEqual(len(self.fake_session.message_queue), 0)
 
+        self.fake_session.group_sendmsg(None, 'ConfigManager')
         self._handle_msg_helper({ "command": [ "set_config", [ ] ] },
                                 {'result': [1, 'Wrong number of arguments']} )
         self._handle_msg_helper({ "command": [ "set_config", [ self.name, { "test": 125 }] ] },

Modified: experiments/327-sync/src/lib/python/isc/config/tests/unittest_fakesession.py
==============================================================================
--- experiments/327-sync/src/lib/python/isc/config/tests/unittest_fakesession.py (original)
+++ experiments/327-sync/src/lib/python/isc/config/tests/unittest_fakesession.py Tue Nov  9 10:38:17 2010
@@ -15,6 +15,15 @@
 
 # $Id$
 
+import isc
+
+class WouldBlockForever(Exception):
+    """
+    This is thrown by the FakeModuleCCSession if it would need
+    to block forever for incoming message.
+    """
+    pass
+
 #
 # We can probably use a more general version of this
 #
@@ -24,6 +33,10 @@
         # each entry is of the form [ channel, instance, message ]
         self.message_queue = []
         self._socket = "ok we just need something not-None here atm"
+        # if self.timeout is set to anything other than 0, and
+        # the message_queue is empty when receive is called, throw
+        # a SessionTimeout
+        self._timeout = 0
 
     def group_subscribe(self, group_name, instance_name = None):
         if not group_name in self.subscriptions:
@@ -58,12 +71,21 @@
         if 'group' in env:
             self.message_queue.append([ env['group'], None, msg])
 
-    def group_recvmsg(self, blocking, seq = None):
+    def group_recvmsg(self, nonblock=True, seq = None):
         for qm in self.message_queue:
-            if qm[0] in self.subscriptions and (qm[1] == None or qm[1] in self.subscriptions[qm[0]]):
+            if qm[0] in self.subscriptions and (qm[1] == None or qm[1] in
+                self.subscriptions[qm[0]]):
                 self.message_queue.remove(qm)
                 return qm[2], {'group': qm[0], 'from': qm[1]}
-        return None, None
+        if self._timeout == 0:
+            if nonblock:
+                return None, None
+            else:
+                raise WouldBlockForever(
+                    "Blocking read without timeout and no message ready")
+        else:
+            raise isc.cc.SessionTimeout("Timeout set but no data to "
+                                 "return to group_recvmsg()")
 
     def get_message(self, channel, target = None):
         for qm in self.message_queue:
@@ -75,4 +97,9 @@
     def close(self):
         # need to pass along somehow that this function has been called,
         self._socket = "closed"
-        pass
+
+    def set_timeout(self, timeout):
+        self._timeout = timeout
+
+    def get_timeout(self):
+        return self._timeout

Modified: experiments/327-sync/src/lib/python/isc/datasrc/master.py
==============================================================================
--- experiments/327-sync/src/lib/python/isc/datasrc/master.py (original)
+++ experiments/327-sync/src/lib/python/isc/datasrc/master.py Tue Nov  9 10:38:17 2010
@@ -269,7 +269,7 @@
             if second[-1] == '.':
                 self.__origin = second
             elif not self.__origin:
-                raise MasterFileError("$ORIGIN is not absolute in record:%s" % s)
+                raise MasterFileError("$ORIGIN is not absolute in record: %s" % s)
             elif self.__origin != '.':
                 self.__origin = second + '.' + self.__origin
             else:

Modified: experiments/327-sync/src/lib/python/isc/dns/__init__.py
==============================================================================
--- experiments/327-sync/src/lib/python/isc/dns/__init__.py (original)
+++ experiments/327-sync/src/lib/python/isc/dns/__init__.py Tue Nov  9 10:38:17 2010
@@ -1,1 +1,1 @@
-from libdns_python_name import *
+from pydnspp import *

Modified: experiments/327-sync/src/lib/python/isc/log/Makefile.am
==============================================================================
--- experiments/327-sync/src/lib/python/isc/log/Makefile.am (original)
+++ experiments/327-sync/src/lib/python/isc/log/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 python_PYTHON = __init__.py log.py
 

Modified: experiments/327-sync/src/lib/python/isc/log/log.py
==============================================================================
--- experiments/327-sync/src/lib/python/isc/log/log.py (original)
+++ experiments/327-sync/src/lib/python/isc/log/log.py Tue Nov  9 10:38:17 2010
@@ -19,6 +19,7 @@
 To use, simply 'import isc.log.log' and log away!
 """
 import os
+import sys
 import syslog
 import logging
 import logging.handlers
@@ -31,47 +32,73 @@
           'error' : logging.ERROR,
           'critical' : logging.CRITICAL}
 
-
 FORMATTER = logging.Formatter("%(name)s: %(levelname)s: %(message)s")
 TIME_FORMATTER = logging.Formatter("%(asctime)s.%(msecs)03d %(name)s: %(levelname)s: %(message)s",
                                    "%d-%b-%Y %H:%M:%S")
 
+def log_err(err_type, err_msg):
+    sys.stderr.write(err_type + ": " + "%s.\n" % str(err_msg)[str(err_msg).find(']')+1:])
+
+
 class NSFileLogHandler(logging.handlers.RotatingFileHandler):
     """RotatingFileHandler: replace RotatingFileHandler with a custom handler"""
 
     def __init__(self, filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=0):
-        dir = os.path.split(filename)
-        if not (os.path.exists(dir[0])):
-            os.makedirs(dir[0])
-        super(NSFileLogHandler, self).__init__(filename, mode, maxBytes,
+        abs_file_name = self._get_abs_file_path(filename)
+        """Create log directory beforehand, because the underlying logging framework won't 
+        create non-exsiting log directory on writing logs.
+        """
+        if not (os.path.exists(os.path.dirname(abs_file_name))):
+            os.makedirs(os.path.dirname(abs_file_name))
+        super(NSFileLogHandler, self).__init__(abs_file_name, mode, maxBytes,
                                                 backupCount, encoding, delay)
+
+    def handleError(self, record):
+        """Overwrite handleError to provide more user-friendly error messages"""
+        if logging.raiseExceptions:
+            ei = sys.exc_info()
+            if (ei[1]):
+                sys.stderr.write("[b10-logging] : " + str(ei[1]))
+
+    def _get_abs_file_path(self, file_name):
+        """ Get absolute file path"""
+        # For a bare filename, log_dir will be set the current directory.
+        if not os.path.dirname(file_name):
+            abs_file_dir = os.getcwd()
+        else:
+            abs_file_dir = os.path.abspath(os.path.dirname(file_name))
+        abs_file_name = os.path.join(abs_file_dir, os.path.basename(file_name))
+        return abs_file_name
 
     def shouldRollover(self, record):
         """Rewrite RotatingFileHandler.shouldRollover. 
        
         If the log file is deleted at runtime, a new file will be created.
         """
-        dfn = self.baseFilename                 
+        dfn = self.baseFilename
         if (self.stream) and (not os.path.exists(dfn)): #Does log file exist?
-            self.stream.close()
-            dir = os.path.split(dfn)
-            if not (os.path.exists(dir[0])): #Does log subdirectory exist?
-                os.makedirs(dir[0])
+            self.stream = None
+            """ Log directory may be deleted while bind10 running or updated with a
+             non-existing directory. Need to create log directory beforehand, because
+             the underlying logging framework won't create non-exsiting log directory
+             on writing logs.
+             """
+            if not (os.path.exists(os.path.dirname(dfn))): #Does log subdirectory exist?
+                os.makedirs(os.path.dirname(dfn))
             self.stream = self._open()
         return super(NSFileLogHandler, self).shouldRollover(record)
     
     def update_config(self, file_name, backup_count, max_bytes):
         """Update RotatingFileHandler configuration.
-
-        If the file path does not exist, we will use the old log file.
+        Changes will be picked up in the next call to shouldRollover().
+
         input:
             log file name
             max backup count
             predetermined log file size
         """
-        dir = os.path.split(file_name)
-        if (os.path.exists(dir[0])):
-            self.baseFilename = file_name
+        abs_file_name = self._get_abs_file_path(file_name)
+        self.baseFilename = abs_file_name 
         self.maxBytes = max_bytes
         self.backupCount = backup_count
 
@@ -162,8 +189,9 @@
             try:
                 self._file_handler = NSFileLogHandler(filename = log_file,
                                           maxBytes = max_bytes, backupCount = backup_count)
-            except IOError:
+            except (IOError, OSError) as e:
                 self._file_handler = None
+                log_err("[b10-logging] Add file handler fail", str(e))
                 return
             self._file_handler.setFormatter(TIME_FORMATTER)
             self.addHandler(self._file_handler)
@@ -244,6 +272,9 @@
         logger.log_message('info', "We have a %s", "mysterious problem").
         """
         logLevel = LEVELS.get(level, logging.NOTSET)
-        self.log(logLevel, msg, *args, **kwargs)
-
-
+        try:
+            self.log(logLevel, msg, *args, **kwargs)
+        except (TypeError, KeyError) as e:
+            sys.stderr.write("[b10-logging] Log message fail %s\n" % (str(e)))
+
+

Modified: experiments/327-sync/src/lib/python/isc/log/tests/log_test.py
==============================================================================
--- experiments/327-sync/src/lib/python/isc/log/tests/log_test.py (original)
+++ experiments/327-sync/src/lib/python/isc/log/tests/log_test.py Tue Nov  9 10:38:17 2010
@@ -20,6 +20,7 @@
 from isc.log.log import *
 import unittest
 import os
+import sys
 import tempfile
 
 
@@ -46,21 +47,48 @@
         self.handler.shouldRollover(record)
         self.assertTrue(os.path.exists(self.FILE_LOG1.name))
 
+    def test_get_absolute_file_path(self):
+        abs_file_name = self.handler._get_abs_file_path(self.FILE_LOG1.name)
+        self.assertEqual(abs_file_name, self.FILE_LOG1.name)
+        # test bare filename
+        file_name1 = "bind10.py"
+        abs_file_name = self.handler._get_abs_file_path(file_name1)
+        self.assertEqual(abs_file_name, os.path.join(os.getcwd(), file_name1))
+        # test relative path 
+        file_name2 = "./bind10.py"
+        abs_file_name = self.handler._get_abs_file_path(file_name2)
+        self.assertEqual(abs_file_name, os.path.join(os.getcwd(), os.path.basename(file_name2)))
+         
     def test_update_config(self):
         self.handler.update_config(self.FILE_LOG2.name, 3, 512)
         self.assertEqual(self.handler.baseFilename, self.FILE_LOG2.name)
         self.assertEqual(self.handler.maxBytes, 512)
         self.assertEqual(self.handler.backupCount, 3)
 
-        dir = os.path.split(self.FILE_LOG3.name)                                        
-        path = dir[0] + "path_not_exists"
-        update_file = os.path.join(path, dir[1])
-
-        if not os.path.exists(path):
-            self.handler.update_config(update_file, 4, 1024)
-            self.assertEqual(self.handler.baseFilename, self.FILE_LOG2.name)
-            self.assertEqual(self.handler.maxBytes, 1024)
-            self.assertEqual(self.handler.backupCount, 4)
+        # check the existence of new log file.
+        # emit() will call shouldRollover() to update the log file
+        if(os.path.exists(self.FILE_LOG2.name)):
+            os.remove(self.FILE_LOG2.name)
+        record = logging.LogRecord(None, None, "", 0, "rotate file handler", (), None, None)
+        self.handler.emit(record)
+        self.assertTrue(os.path.exists(self.FILE_LOG2.name))
+
+    def test_handle_Error(self):
+        if(os.path.exists(self.FILE_LOG3.name)):
+            os.remove(self.FILE_LOG3.name)
+        # redirect error message to file
+        savederr = sys.stderr
+        errfd = open(self.FILE_LOG3.name, 'w+')
+        sys.stderr = errfd
+        record = logging.LogRecord(None, None, "", 0, "record message", (), None, None)
+        try:
+            raise ValueError("ValueError")
+        except ValueError:
+            self.handler.handleError(record)
+
+        self.assertEqual("[b10-logging] : ValueError", errfd.read())
+        sys.stderr = savederr
+        errfd.close()
 
     def tearDown(self):
         self.handler.flush()
@@ -78,50 +106,46 @@
         self.assertEqual(sysLevel, syslog.LOG_ERR)
 
     def test_emit(self):
-        record = logging.LogRecord(None, None, "", 0, "syslog handler", (), None, None)
+        syslog_message = "bind10 syslog testing"
+        record = logging.LogRecord(None, None, "", 0, syslog_message, (), None, None)
         self.handler.emit(record)
-
 
 class TestLogging(unittest.TestCase):
     
     def setUp(self):
-        self.FILE_STREAM_LOG1= tempfile.NamedTemporaryFile(mode='w',
+        self.FILE_STREAM_LOG1 = tempfile.NamedTemporaryFile(mode='w',
                                                       prefix="b10",
                                                       delete=True)
-        self.FILE_STREAM_LOG2= tempfile.NamedTemporaryFile(mode='w',
+        self.FILE_STREAM_LOG2 = tempfile.NamedTemporaryFile(mode='w',
                                                       prefix="b10",
                                                       delete=True)
-        self.FILE_STREAM_LOG3= tempfile.NamedTemporaryFile(mode='w',
+        self.FILE_STREAM_LOG3 = tempfile.NamedTemporaryFile(mode='w',
                                                       prefix="b10",
                                                       delete=True)
         self.file_stream_logger = NSLogger('File_Stream_Logger',
                                            self.FILE_STREAM_LOG1.name,
                                            'debug', 5, 1024, True)
         self.syslog_logger = NSLogger('SysLogger', '', 'info', 5, 1024, False)
+        self.stderr_bak = sys.stderr
+        sys.stderr = open(os.devnull, 'w')
     
     def test_logging_init(self):
         self.assertNotEqual(self.file_stream_logger._file_handler, None)
         self.assertNotEqual(self.file_stream_logger._stream_handler, None)
         self.assertEqual(self.file_stream_logger._syslog_handler, None)
 
-        ret = self.file_stream_logger._file_handler in self.file_stream_logger.handlers
-        self.assertTrue(ret)
-        ret = self.file_stream_logger._stream_handler in self.file_stream_logger.handlers
-        self.assertTrue(ret)
-        ret = self.file_stream_logger._syslog_handler in self.file_stream_logger.handlers
-        self.assertFalse(ret)
+        self.assertIn(self.file_stream_logger._file_handler, self.file_stream_logger.handlers)
+        self.assertIn(self.file_stream_logger._stream_handler, self.file_stream_logger.handlers)
+        self.assertNotIn(self.file_stream_logger._syslog_handler, self.file_stream_logger.handlers)
         logLevel = LEVELS.get('debug', logging.NOTSET)
         self.assertEqual(self.file_stream_logger.getEffectiveLevel(), logLevel)
 
         self.assertEqual(self.syslog_logger._file_handler, None)
         self.assertEqual(self.syslog_logger._stream_handler, None)
         self.assertNotEqual(self.syslog_logger._syslog_handler, None)
-        ret = self.syslog_logger._file_handler in self.syslog_logger.handlers
-        self.assertFalse(ret)
-        ret = self.syslog_logger._stream_handler in self.syslog_logger.handlers
-        self.assertFalse(ret)
-        ret = self.syslog_logger._syslog_handler in self.syslog_logger.handlers
-        self.assertTrue(ret)
+        self.assertNotIn(self.syslog_logger._file_handler, self.syslog_logger.handlers)
+        self.assertNotIn(self.syslog_logger._stream_handler, self.syslog_logger.handlers)
+        self.assertIn(self.syslog_logger._syslog_handler, self.syslog_logger.handlers)
 
         logLevel = LEVELS.get('info', logging.NOTSET)
         self.assertEqual(self.syslog_logger.getEffectiveLevel(), logLevel)
@@ -131,41 +155,52 @@
             self.syslog_logger.removeHandler(self.syslog_logger._file_handler)
         
         self.syslog_logger._add_rotate_handler('', 5, 1024)
-        ret = self.syslog_logger._file_handler in self.syslog_logger.handlers
-        self.assertFalse(ret)
+        self.assertNotIn(self.syslog_logger._file_handler, self.syslog_logger.handlers)
 
         self.syslog_logger._add_rotate_handler(self.FILE_STREAM_LOG1.name, 5, 1024)
-        ret = self.syslog_logger._file_handler in self.syslog_logger.handlers
-        self.assertTrue(ret)
+        self.assertIn(self.syslog_logger._file_handler, self.syslog_logger.handlers)
+
+        # test IOError exception
+        self.syslog_logger.removeHandler(self.syslog_logger._file_handler)
+        log_file = self.FILE_STREAM_LOG1.name + '/logfile'
+        self.syslog_logger._add_rotate_handler(log_file, 5, 1024)
+        self.assertNotIn(self.syslog_logger._file_handler, self.syslog_logger.handlers)
 
     def test_add_stream_handler(self):
         if(self.file_stream_logger._stream_handler in self.file_stream_logger.handlers):
             self.file_stream_logger.removeHandler(self.file_stream_logger._stream_handler)
 
         self.file_stream_logger._add_stream_handler()
-        ret = self.file_stream_logger._stream_handler in self.file_stream_logger.handlers
-        self.assertTrue(ret)
+        self.assertIn(self.file_stream_logger._stream_handler, self.file_stream_logger.handlers)
 
     def test_add_syslog_handler(self):
         if(self.syslog_logger._syslog_handler in self.syslog_logger.handlers):
             self.syslog_logger.removeHandler(self.syslog_logger._syslog_handler)
 
         self.syslog_logger._add_syslog_handler()
-        ret = self.syslog_logger._syslog_handler in self.syslog_logger.handlers
-        self.assertTrue(ret)
+        self.assertIn(self.syslog_logger._syslog_handler, self.syslog_logger.handlers)
 
     def test_update_rotate_handler(self):
         self.file_stream_logger._update_rotate_handler(self.FILE_STREAM_LOG2.name, 4, 1024)
-        ret = self.file_stream_logger._file_handler in self.file_stream_logger.handlers
-        self.assertTrue(ret)
+        self.assertIn(self.file_stream_logger._file_handler, self.file_stream_logger.handlers)
 
         self.file_stream_logger._update_rotate_handler('', 5, 1024)
-        ret = self.file_stream_logger._file_handler in self.file_stream_logger.handlers
-        self.assertFalse(ret)
+        self.assertNotIn(self.file_stream_logger._file_handler, self.file_stream_logger.handlers)
 
         self.file_stream_logger._update_rotate_handler(self.FILE_STREAM_LOG1.name, 4, 1024)
-        ret = self.file_stream_logger._file_handler in self.file_stream_logger.handlers
-        self.assertTrue(ret)
+        self.assertIn(self.file_stream_logger._file_handler, self.file_stream_logger.handlers)
+
+    def test_get_config(self):
+        config_data = {'log_file' : self.FILE_STREAM_LOG1.name,
+                       'log_severity' : 'critical',
+                       'log_versions' : 4,
+                       'log_max_bytes' : 1024}
+        self.file_stream_logger._get_config(config_data)
+        self.assertEqual(self.file_stream_logger._log_file, self.FILE_STREAM_LOG1.name)
+        self.assertEqual(self.file_stream_logger._severity, 'critical')
+        self.assertEqual(self.file_stream_logger._versions, 4)
+        self.assertEqual(self.file_stream_logger._max_bytes, 1024)
+
 
     def test_update_config(self):
         update_config = {'log_file' : self.FILE_STREAM_LOG1.name,
@@ -183,15 +218,20 @@
                          'log_max_bytes' : 1024}
         self.file_stream_logger.update_config(update_config)
         self.file_stream_logger.log_message('debug', 'debug message')
-        self.file_stream_logger.log_message('info', 'info message')
         self.file_stream_logger.log_message('warning', 'warning message')
         self.file_stream_logger.log_message('error', 'error message')
+        #test non-exist log level
+        self.assertRaises(None, self.file_stream_logger.log_message('not-exist', 'not exist message'))
+        #test log_message KeyError exception
+        self.assertRaises(None, self.file_stream_logger.log_message('critical', 'critical message', extra=['message', 'asctime']))
         self.assertTrue(os.path.exists(self.FILE_STREAM_LOG3.name))
     
     def tearDown(self):
         self.FILE_STREAM_LOG1.close()
         self.FILE_STREAM_LOG2.close()
         self.FILE_STREAM_LOG3.close()
+        sys.stderr.flush();
+        sys.stderr = self.stderr_bak
 
 if __name__ == '__main__':
     unittest.main()

Modified: experiments/327-sync/src/lib/python/isc/notify/Makefile.am
==============================================================================
--- experiments/327-sync/src/lib/python/isc/notify/Makefile.am (original)
+++ experiments/327-sync/src/lib/python/isc/notify/Makefile.am Tue Nov  9 10:38:17 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
 
 python_PYTHON = __init__.py notify_out.py
 

Modified: experiments/327-sync/src/lib/python/isc/notify/notify_out.py
==============================================================================
--- experiments/327-sync/src/lib/python/isc/notify/notify_out.py (original)
+++ experiments/327-sync/src/lib/python/isc/notify/notify_out.py Tue Nov  9 10:38:17 2010
@@ -19,10 +19,11 @@
 import socket
 import threading
 import time
+import errno
 from isc.datasrc import sqlite3_ds
 import isc
 try: 
-    from libdns_python import * 
+    from pydnspp import * 
 except ImportError as e: 
     # C++ loadable module may not be installed; 
     sys.stderr.write('[b10-xfrout] failed to import DNS or XFR module: %s\n' % str(e)) 
@@ -44,29 +45,11 @@
 _BAD_QR = 4
 _BAD_REPLY_PACKET = 5
 
+SOCK_DATA = b's'
 def addr_to_str(addr):
     return '%s#%s' % (addr[0], addr[1])
 
-def dispatcher(notifier):
-    '''The loop function for handling notify related events.
-    If one zone get the notify reply before timeout, call the
-    handle to process the reply. If one zone can't get the notify
-    before timeout, call the handler to resend notify or notify 
-    next slave.  
-    notifier: one object of class NotifyOut. '''
-    while True:
-        replied_zones, not_replied_zones = notifier._wait_for_notify_reply()
-        if len(replied_zones) == 0 and len(not_replied_zones) == 0:
-            time.sleep(_IDLE_SLEEP_TIME) #TODO set a better time for idle sleep
-            continue
-
-        for name_ in replied_zones:
-            notifier._zone_notify_handler(replied_zones[name_], _EVENT_READ)
-            
-        for name_ in not_replied_zones:
-            if not_replied_zones[name_].notify_timeout <= time.time():
-                notifier._zone_notify_handler(not_replied_zones[name_], _EVENT_TIMEOUT)
- 
+
 class ZoneNotifyInfo:
     '''This class keeps track of notify-out information for one zone.'''
 
@@ -115,14 +98,17 @@
 
 class NotifyOut:
     '''This class is used to handle notify logic for all zones(sending
-    notify message to its slaves).The only interface provided to 
-    the user is send_notify(). the object of this class should be 
-    used together with function dispatcher(). '''
+    notify message to its slaves). notify service can be started by 
+    calling  dispatcher(), and it can be stoped by calling shutdown()
+    in another thread. ''' 
     def __init__(self, datasrc_file, log=None, verbose=True):
         self._notify_infos = {} # key is (zone_name, zone_class)
         self._waiting_zones = []
         self._notifying_zones = []
         self._log = log
+        self._serving = False
+        self._read_sock, self._write_sock = socket.socketpair()
+        self._read_sock.setblocking(False)
         self.notify_num = 0  # the count of in progress notifies
         self._verbose = verbose
         self._lock = threading.Lock()
@@ -164,6 +150,70 @@
                 self._notify_infos[zone_id].prepare_notify_out()
                 self.notify_num += 1 
                 self._notifying_zones.append(zone_id)
+
+    def _dispatcher(self, started_event):
+        started_event.set() # Let the master know we are alive already
+        while self._serving:
+            replied_zones, not_replied_zones = self._wait_for_notify_reply()
+
+            for name_ in replied_zones:
+                self._zone_notify_handler(replied_zones[name_], _EVENT_READ)
+
+            for name_ in not_replied_zones:
+                if not_replied_zones[name_].notify_timeout <= time.time():
+                    self._zone_notify_handler(not_replied_zones[name_], _EVENT_TIMEOUT)
+
+    def dispatcher(self, daemon=False):
+        """Spawns a thread that will handle notify related events.
+
+        If one zone get the notify reply before timeout, call the
+        handle to process the reply. If one zone can't get the notify
+        before timeout, call the handler to resend notify or notify 
+        next slave.  
+
+        The thread can be stopped by calling shutdown().
+
+        Returns the thread object to anyone interested.
+        """
+
+        if self._serving:
+            raise RuntimeError(
+                'Dispatcher already running, tried to start twice')
+
+        # Prepare for launch
+        self._serving = True
+        started_event = threading.Event()
+
+        # Start
+        self._thread = threading.Thread(target=self._dispatcher,
+            args=[started_event])
+        if daemon:
+            self._thread.daemon = daemon
+        self._thread.start()
+
+        # Wait for it to get started
+        started_event.wait()
+
+        # Return it to anyone listening
+        return self._thread
+
+    def shutdown(self):
+        """Stop the dispatcher() thread. Blocks until the thread stopped."""
+
+        if not self._serving:
+            raise RuntimeError('Tried to stop while not running')
+
+        # Ask it to stop
+        self._serving = False
+        self._write_sock.send(SOCK_DATA) # make self._read_sock be readable.
+
+        # Wait for it
+        self._thread.join()
+
+        # Clean up
+        self._write_sock = None
+        self._read_sock = None
+        self._thread = None
 
     def _get_rdata_data(self, rr):
         return rr[7].strip()
@@ -200,49 +250,68 @@
         return addr_list
 
     def _prepare_select_info(self):
-        '''Prepare the information for select(), returned 
-        value is one tuple 
+        '''
+        Prepare the information for select(), returned
+        value is one tuple
         (block_timeout, valid_socks, notifying_zones)
         block_timeout: the timeout for select()
         valid_socks: sockets list for waiting ready reading.
-        notifying_zones: the zones which have been triggered 
-                        for notify. '''
+        notifying_zones: the zones which have been triggered
+                        for notify.
+        '''
         valid_socks = []
         notifying_zones = {}
-        min_timeout = None 
+        min_timeout = None
         for info in self._notify_infos:
             sock = self._notify_infos[info].get_socket()
             if sock:
                 valid_socks.append(sock)
                 notifying_zones[info] = self._notify_infos[info]
                 tmp_timeout = self._notify_infos[info].notify_timeout
-                if min_timeout:
+                if min_timeout is not None:
                     if tmp_timeout < min_timeout:
                         min_timeout = tmp_timeout
                 else:
                     min_timeout = tmp_timeout
-       
-        block_timeout = 0
-        if min_timeout:
+
+        block_timeout = _IDLE_SLEEP_TIME
+        if min_timeout is not None:
             block_timeout = min_timeout - time.time()
             if block_timeout < 0:
                 block_timeout = 0
-        
+
         return (block_timeout, valid_socks, notifying_zones)
 
     def _wait_for_notify_reply(self):
-        '''receive notify replies in specified time. returned value 
-        is one tuple:(replied_zones, not_replied_zones)
+        '''
+        Receive notify replies in specified time. returned value
+        is one tuple:(replied_zones, not_replied_zones). ({}, {}) is
+        returned if shutdown() was called.
+
         replied_zones: the zones which receive notify reply.
         not_replied_zones: the zones which haven't got notify reply.
+
         '''
-        (block_timeout, valid_socks, notifying_zones) = self._prepare_select_info()
+        (block_timeout, valid_socks, notifying_zones) = \
+            self._prepare_select_info()
+        # This is None only during some tests
+        if self._read_sock is not None:
+            valid_socks.append(self._read_sock)
         try:
             r_fds, w, e = select.select(valid_socks, [], [], block_timeout)
         except select.error as err:
             if err.args[0] != EINTR:
-                return [], []
-        
+                return {}, {}
+
+        if self._read_sock in r_fds: # user has called shutdown()
+            try:
+                # Noone should write anything else than shutdown
+                assert self._read_sock.recv(len(SOCK_DATA)) == SOCK_DATA
+                return {}, {}
+            except socket.error as e: # Workaround around rare linux bug
+                if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK:
+                    raise
+
         not_replied_zones = {}
         replied_zones = {}
         for info in notifying_zones:
@@ -333,13 +402,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):
@@ -351,7 +420,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: experiments/327-sync/src/lib/python/isc/notify/tests/notify_out_test.py
==============================================================================
--- experiments/327-sync/src/lib/python/isc/notify/tests/notify_out_test.py (original)
+++ experiments/327-sync/src/lib/python/isc/notify/tests/notify_out_test.py Tue Nov  9 10:38:17 2010
@@ -20,7 +20,7 @@
 import time
 import socket
 from isc.datasrc import sqlite3_ds
-from isc.notify import notify_out
+from isc.notify import notify_out, SOCK_DATA
 
 class TestZoneNotifyInfo(unittest.TestCase):
     def setUp(self):
@@ -53,8 +53,6 @@
 
 class TestNotifyOut(unittest.TestCase):
     def setUp(self):
-        self.old_stdout = sys.stdout
-        sys.stdout = open(os.devnull, 'w')
         self._db_file = tempfile.NamedTemporaryFile(delete=False)
         sqlite3_ds.load(self._db_file.name, 'cn.', self._cn_data_reader)
         sqlite3_ds.load(self._db_file.name, 'com.', self._com_data_reader)
@@ -70,7 +68,6 @@
         info.notify_slaves.append(('1.1.1.1', 5353))
 
     def tearDown(self):
-        sys.stdout = self.old_stdout
         self._db_file.close()
         os.unlink(self._db_file.name)
 
@@ -123,6 +120,20 @@
         self.assertTrue(('com.', 'IN') in timeout_zones.keys())
         self.assertLess(time.time(), self._notify._notify_infos[('com.', 'IN')].notify_timeout)
     
+    def test_wait_for_notify_reply_2(self):
+        # Test the returned value when the read_side socket is readable.
+        self._notify.send_notify('cn.')
+        self._notify.send_notify('com.')
+
+        # Now make one socket be readable
+        self._notify._notify_infos[('cn.', 'IN')].notify_timeout = time.time() + 10
+        self._notify._notify_infos[('com.', 'IN')].notify_timeout = time.time() + 10
+        self._notify._read_sock, self._notify._write_sock = socket.socketpair()
+        self._notify._write_sock.send(SOCK_DATA)
+        replied_zones, timeout_zones = self._notify._wait_for_notify_reply()
+        self.assertEqual(0, len(replied_zones))
+        self.assertEqual(0, len(timeout_zones))
+
     def test_notify_next_target(self):
         self._notify.send_notify('cn.')
         self._notify.send_notify('com.')
@@ -258,7 +269,7 @@
         
     def test_prepare_select_info(self):
         timeout, valid_fds, notifying_zones = self._notify._prepare_select_info()
-        self.assertEqual(0, timeout)
+        self.assertEqual(notify_out._IDLE_SLEEP_TIME, timeout)
         self.assertListEqual([], valid_fds)
 
         self._notify._notify_infos[('cn.', 'IN')]._sock = 1
@@ -279,6 +290,12 @@
         self.assertEqual(timeout, 0)
         self.assertListEqual([2, 1], valid_fds)
 
+    def test_shutdown(self):
+        thread = self._notify.dispatcher()
+        self.assertTrue(thread.is_alive())
+        self._notify.shutdown()
+        self.assertFalse(thread.is_alive())
+
 if __name__== "__main__":
     unittest.main()
 

Modified: experiments/327-sync/src/lib/xfr/Makefile.am
==============================================================================
--- experiments/327-sync/src/lib/xfr/Makefile.am (original)
+++ experiments/327-sync/src/lib/xfr/Makefile.am Tue Nov  9 10:38:17 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: experiments/327-sync/src/lib/xfr/fd_share.cc
==============================================================================
--- experiments/327-sync/src/lib/xfr/fd_share.cc (original)
+++ experiments/327-sync/src/lib/xfr/fd_share.cc Tue Nov  9 10:38:17 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: experiments/327-sync/src/lib/xfr/fd_share.h
==============================================================================
--- experiments/327-sync/src/lib/xfr/fd_share.h (original)
+++ experiments/327-sync/src/lib/xfr/fd_share.h Tue Nov  9 10:38:17 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: experiments/327-sync/src/lib/xfr/fdshare_python.cc
==============================================================================
--- experiments/327-sync/src/lib/xfr/fdshare_python.cc (original)
+++ experiments/327-sync/src/lib/xfr/fdshare_python.cc Tue Nov  9 10:38:17 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* self UNUSED_PARAM, 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* self UNUSED_PARAM, 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: experiments/327-sync/src/lib/xfr/python_xfr.cc
==============================================================================
--- experiments/327-sync/src/lib/xfr/python_xfr.cc (original)
+++ experiments/327-sync/src/lib/xfr/python_xfr.cc Tue Nov  9 10:38:17 2010
@@ -28,8 +28,7 @@
 using namespace isc::xfr;
 using namespace boost::python;
 
-BOOST_PYTHON_MODULE(bind10_xfr)
-{
+BOOST_PYTHON_MODULE(bind10_xfr) {
     def("recv_fd", &recv_fd);
     def("send_fd", &send_fd);
 }

Modified: experiments/327-sync/src/lib/xfr/xfrout_client.cc
==============================================================================
--- experiments/327-sync/src/lib/xfr/xfrout_client.cc (original)
+++ experiments/327-sync/src/lib/xfr/xfrout_client.cc Tue Nov  9 10:38:17 2010
@@ -47,8 +47,7 @@
     impl_(new XfroutClientImpl(file))
 {}
 
-XfroutClient::~XfroutClient()
-{
+XfroutClient::~XfroutClient() {
     delete impl_;
 }
 
@@ -70,7 +69,7 @@
     }
 }
 
-int 
+int
 XfroutClient::sendXfroutRequestInfo(const int tcp_sock,
                                     const void* const msg_data,
                                     const uint16_t msg_len)
@@ -94,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