[svn] commit: r3501 - in /branches/trac327: ./ 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/recurse/ src/bin/recurse/tests/ src/bin/recurse/tests/testdata/ 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/asiolink/ src/lib/asiolink/internal/ src/lib/asiolink/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
Wed Nov 10 10:44:43 UTC 2010
Author: vorner
Date: Wed Nov 10 10:44:42 2010
New Revision: 3501
Log:
Sync with trunk
Added:
branches/trac327/src/bin/auth/benchmarks/
- copied from r3500, trunk/src/bin/auth/benchmarks/
branches/trac327/src/bin/auth/tests/testdata/Makefile.am
- copied unchanged from r3500, trunk/src/bin/auth/tests/testdata/Makefile.am
branches/trac327/src/bin/recurse/tests/testdata/iqueryresponse_fromWire.spec
- copied unchanged from r3500, branches/trac327/src/bin/auth/tests/testdata/iqueryresponse_fromWire.spec
branches/trac327/src/bin/recurse/tests/testdata/multiquestion_fromWire.spec
- copied unchanged from r3500, branches/trac327/src/bin/auth/tests/testdata/multiquestion_fromWire.spec
branches/trac327/src/bin/recurse/tests/testdata/queryBadEDNS_fromWire.spec
- copied unchanged from r3500, branches/trac327/src/bin/auth/tests/testdata/queryBadEDNS_fromWire.spec
branches/trac327/src/bin/recurse/tests/testdata/shortanswer_fromWire.spec
- copied unchanged from r3500, branches/trac327/src/bin/auth/tests/testdata/shortanswer_fromWire.spec
branches/trac327/src/bin/recurse/tests/testdata/simplequery_fromWire.spec
- copied unchanged from r3500, branches/trac327/src/bin/auth/tests/testdata/simplequery_fromWire.spec
branches/trac327/src/bin/recurse/tests/testdata/simpleresponse_fromWire.spec
- copied unchanged from r3500, branches/trac327/src/bin/auth/tests/testdata/simpleresponse_fromWire.spec
branches/trac327/src/bin/stats/Makefile.am
- copied unchanged from r3500, trunk/src/bin/stats/Makefile.am
branches/trac327/src/bin/stats/b10-stats.8
- copied unchanged from r3500, trunk/src/bin/stats/b10-stats.8
branches/trac327/src/bin/stats/b10-stats.xml
- copied unchanged from r3500, trunk/src/bin/stats/b10-stats.xml
branches/trac327/src/bin/stats/run_b10-stats.sh.in
- copied unchanged from r3500, trunk/src/bin/stats/run_b10-stats.sh.in
branches/trac327/src/bin/stats/run_b10-stats_stub.sh.in
- copied unchanged from r3500, trunk/src/bin/stats/run_b10-stats_stub.sh.in
branches/trac327/src/bin/stats/stats.py.in
- copied unchanged from r3500, trunk/src/bin/stats/stats.py.in
branches/trac327/src/bin/stats/stats.spec.pre.in
- copied unchanged from r3500, trunk/src/bin/stats/stats.spec.pre.in
branches/trac327/src/bin/stats/stats_stub.py.in
- copied unchanged from r3500, trunk/src/bin/stats/stats_stub.py.in
branches/trac327/src/bin/stats/tests/
- copied from r3500, trunk/src/bin/stats/tests/
branches/trac327/src/bin/tests/
- copied from r3500, trunk/src/bin/tests/
branches/trac327/src/bin/xfrin/xfrin.spec
- copied unchanged from r3500, trunk/src/bin/xfrin/xfrin.spec
branches/trac327/src/bin/zonemgr/b10-zonemgr.8
- copied unchanged from r3500, trunk/src/bin/zonemgr/b10-zonemgr.8
branches/trac327/src/bin/zonemgr/b10-zonemgr.xml
- copied unchanged from r3500, trunk/src/bin/zonemgr/b10-zonemgr.xml
branches/trac327/src/lib/asiolink/iosocket.cc
branches/trac327/src/lib/config/tests/testdata/
- copied from r3500, trunk/src/lib/config/tests/testdata/
branches/trac327/src/lib/dns/edns.cc
- copied unchanged from r3500, trunk/src/lib/dns/edns.cc
branches/trac327/src/lib/dns/edns.h
- copied unchanged from r3500, trunk/src/lib/dns/edns.h
branches/trac327/src/lib/dns/opcode.cc
- copied unchanged from r3500, trunk/src/lib/dns/opcode.cc
branches/trac327/src/lib/dns/opcode.h
- copied unchanged from r3500, trunk/src/lib/dns/opcode.h
branches/trac327/src/lib/dns/python/edns_python.cc
- copied unchanged from r3500, trunk/src/lib/dns/python/edns_python.cc
branches/trac327/src/lib/dns/python/opcode_python.cc
- copied unchanged from r3500, trunk/src/lib/dns/python/opcode_python.cc
branches/trac327/src/lib/dns/python/pydnspp.cc
- copied unchanged from r3500, trunk/src/lib/dns/python/pydnspp.cc
branches/trac327/src/lib/dns/python/pydnspp_common.cc
- copied unchanged from r3500, trunk/src/lib/dns/python/pydnspp_common.cc
branches/trac327/src/lib/dns/python/pydnspp_common.h
- copied unchanged from r3500, trunk/src/lib/dns/python/pydnspp_common.h
branches/trac327/src/lib/dns/python/rcode_python.cc
- copied unchanged from r3500, trunk/src/lib/dns/python/rcode_python.cc
branches/trac327/src/lib/dns/python/tests/edns_python_test.py
- copied unchanged from r3500, trunk/src/lib/dns/python/tests/edns_python_test.py
branches/trac327/src/lib/dns/python/tests/opcode_python_test.py
- copied unchanged from r3500, trunk/src/lib/dns/python/tests/opcode_python_test.py
branches/trac327/src/lib/dns/python/tests/rcode_python_test.py
- copied unchanged from r3500, trunk/src/lib/dns/python/tests/rcode_python_test.py
branches/trac327/src/lib/dns/python/tests/testutil.py
- copied unchanged from r3500, trunk/src/lib/dns/python/tests/testutil.py
branches/trac327/src/lib/dns/rcode.cc
- copied unchanged from r3500, trunk/src/lib/dns/rcode.cc
branches/trac327/src/lib/dns/rcode.h
- copied unchanged from r3500, trunk/src/lib/dns/rcode.h
branches/trac327/src/lib/dns/tests/edns_unittest.cc
- copied unchanged from r3500, trunk/src/lib/dns/tests/edns_unittest.cc
branches/trac327/src/lib/dns/tests/opcode_unittest.cc
- copied unchanged from r3500, trunk/src/lib/dns/tests/opcode_unittest.cc
branches/trac327/src/lib/dns/tests/rcode_unittest.cc
- copied unchanged from r3500, trunk/src/lib/dns/tests/rcode_unittest.cc
branches/trac327/src/lib/dns/tests/testdata/Makefile.am
- copied unchanged from r3500, trunk/src/lib/dns/tests/testdata/Makefile.am
branches/trac327/src/lib/dns/tests/testdata/edns_toWire1.spec
- copied unchanged from r3500, trunk/src/lib/dns/tests/testdata/edns_toWire1.spec
branches/trac327/src/lib/dns/tests/testdata/edns_toWire2.spec
- copied unchanged from r3500, trunk/src/lib/dns/tests/testdata/edns_toWire2.spec
branches/trac327/src/lib/dns/tests/testdata/edns_toWire3.spec
- copied unchanged from r3500, trunk/src/lib/dns/tests/testdata/edns_toWire3.spec
branches/trac327/src/lib/dns/tests/testdata/edns_toWire4.spec
- copied unchanged from r3500, trunk/src/lib/dns/tests/testdata/edns_toWire4.spec
branches/trac327/src/lib/python/isc/net/
- copied from r3500, trunk/src/lib/python/isc/net/
branches/trac327/src/lib/python/isc/util/
- copied from r3500, trunk/src/lib/python/isc/util/
Removed:
branches/trac327/src/bin/auth/tests/testdata/badExampleQuery_fromWire
branches/trac327/src/bin/auth/tests/testdata/examplequery_fromWire
branches/trac327/src/bin/auth/tests/testdata/iqueryresponse_fromWire
branches/trac327/src/bin/auth/tests/testdata/multiquestion_fromWire
branches/trac327/src/bin/auth/tests/testdata/queryBadEDNS_fromWire
branches/trac327/src/bin/auth/tests/testdata/shortanswer_fromWire
branches/trac327/src/bin/auth/tests/testdata/simplequery_fromWire
branches/trac327/src/bin/auth/tests/testdata/simpleresponse_fromWire
branches/trac327/src/bin/recurse/tests/testdata/iqueryresponse_fromWire
branches/trac327/src/bin/recurse/tests/testdata/multiquestion_fromWire
branches/trac327/src/bin/recurse/tests/testdata/queryBadEDNS_fromWire
branches/trac327/src/bin/recurse/tests/testdata/shortanswer_fromWire
branches/trac327/src/bin/recurse/tests/testdata/simplequery_fromWire
branches/trac327/src/bin/recurse/tests/testdata/simpleresponse_fromWire
branches/trac327/src/bin/stats/statsd.py
branches/trac327/src/bin/stats/statsd.txt
branches/trac327/src/bin/stats/test/
branches/trac327/src/bin/stats/test_total.py
branches/trac327/src/bin/xfrin/xfrin.spec.pre.in
branches/trac327/src/lib/config/testdata/
branches/trac327/src/lib/dns/message_test.py
branches/trac327/src/lib/dns/python/libdns_python.cc
branches/trac327/src/lib/dns/python/libdns_python_common.cc
branches/trac327/src/lib/dns/python/libdns_python_common.h
branches/trac327/src/lib/dns/python/tests/test.py
branches/trac327/src/lib/dns/tests/testdata/message_fromWire10
branches/trac327/src/lib/dns/tests/testdata/message_fromWire11
branches/trac327/src/lib/dns/tests/testdata/name_toWire5
branches/trac327/src/lib/dns/tests/testdata/name_toWire6
branches/trac327/src/lib/dns/tests/testdata/rdata_nsec_fromWire10
branches/trac327/src/lib/dns/tests/testdata/rdata_nsec_fromWire4
branches/trac327/src/lib/dns/tests/testdata/rdata_nsec_fromWire5
branches/trac327/src/lib/dns/tests/testdata/rdata_nsec_fromWire6
branches/trac327/src/lib/dns/tests/testdata/rdata_nsec_fromWire7
branches/trac327/src/lib/dns/tests/testdata/rdata_nsec_fromWire8
branches/trac327/src/lib/dns/tests/testdata/rdata_nsec_fromWire9
branches/trac327/src/lib/dns/tests/testdata/rdata_rrsig_fromWire2
branches/trac327/src/lib/dns/tests/testdata/rdata_soa_toWireUncompressed
branches/trac327/src/lib/dns/tests/testdata/rdata_txt_fromWire2
branches/trac327/src/lib/dns/tests/testdata/rdata_txt_fromWire3
branches/trac327/src/lib/dns/tests/testdata/rdata_txt_fromWire4
branches/trac327/src/lib/dns/tests/testdata/rdata_txt_fromWire5
branches/trac327/src/lib/python/isc/Util/
Modified:
branches/trac327/ (props changed)
branches/trac327/ChangeLog
branches/trac327/README
branches/trac327/configure.ac
branches/trac327/doc/guide/bind10-guide.html
branches/trac327/doc/guide/bind10-guide.xml
branches/trac327/src/bin/Makefile.am
branches/trac327/src/bin/auth/Makefile.am
branches/trac327/src/bin/auth/auth_srv.cc
branches/trac327/src/bin/auth/auth_srv.h
branches/trac327/src/bin/auth/b10-auth.8
branches/trac327/src/bin/auth/b10-auth.xml
branches/trac327/src/bin/auth/benchmarks/Makefile.am
branches/trac327/src/bin/auth/benchmarks/query_bench.cc
branches/trac327/src/bin/auth/tests/Makefile.am
branches/trac327/src/bin/auth/tests/auth_srv_unittest.cc
branches/trac327/src/bin/auth/tests/mockups.h
branches/trac327/src/bin/auth/tests/run_unittests.cc
branches/trac327/src/bin/bind10/Makefile.am
branches/trac327/src/bin/bind10/bind10.8
branches/trac327/src/bin/bind10/bind10.py.in (contents, props changed)
branches/trac327/src/bin/bind10/bind10.xml
branches/trac327/src/bin/bind10/run_bind10.sh.in
branches/trac327/src/bin/bind10/tests/args_test.py
branches/trac327/src/bin/bind10/tests/bind10_test.py
branches/trac327/src/bin/bindctl/Makefile.am
branches/trac327/src/bin/bindctl/bindctl-source.py.in
branches/trac327/src/bin/cfgmgr/Makefile.am
branches/trac327/src/bin/cfgmgr/b10-cfgmgr.py.in
branches/trac327/src/bin/cmdctl/Makefile.am
branches/trac327/src/bin/cmdctl/cmdctl.py.in (contents, props changed)
branches/trac327/src/bin/host/Makefile.am
branches/trac327/src/bin/host/host.cc
branches/trac327/src/bin/loadzone/Makefile.am
branches/trac327/src/bin/loadzone/b10-loadzone.py.in
branches/trac327/src/bin/loadzone/tests/error/error.known
branches/trac327/src/bin/msgq/Makefile.am
branches/trac327/src/bin/msgq/msgq.py.in
branches/trac327/src/bin/msgq/tests/Makefile.am
branches/trac327/src/bin/msgq/tests/msgq_test.py
branches/trac327/src/bin/recurse/recursor.cc
branches/trac327/src/bin/recurse/tests/Makefile.am
branches/trac327/src/bin/recurse/tests/recursor_unittest.cc
branches/trac327/src/bin/usermgr/b10-cmdctl-usermgr.py.in
branches/trac327/src/bin/xfrin/Makefile.am
branches/trac327/src/bin/xfrin/TODO
branches/trac327/src/bin/xfrin/b10-xfrin.8
branches/trac327/src/bin/xfrin/b10-xfrin.xml
branches/trac327/src/bin/xfrin/tests/xfrin_test.py
branches/trac327/src/bin/xfrin/xfrin.py.in
branches/trac327/src/bin/xfrout/Makefile.am
branches/trac327/src/bin/xfrout/TODO
branches/trac327/src/bin/xfrout/b10-xfrout.8
branches/trac327/src/bin/xfrout/b10-xfrout.xml
branches/trac327/src/bin/xfrout/tests/xfrout_test.py
branches/trac327/src/bin/xfrout/xfrout.py.in
branches/trac327/src/bin/zonemgr/Makefile.am
branches/trac327/src/bin/zonemgr/TODO
branches/trac327/src/bin/zonemgr/tests/Makefile.am
branches/trac327/src/bin/zonemgr/tests/zonemgr_test.py
branches/trac327/src/bin/zonemgr/zonemgr.py.in
branches/trac327/src/bin/zonemgr/zonemgr.spec.pre.in
branches/trac327/src/lib/asiolink/Makefile.am
branches/trac327/src/lib/asiolink/asiolink.h
branches/trac327/src/lib/asiolink/internal/tcpdns.h
branches/trac327/src/lib/asiolink/internal/udpdns.h
branches/trac327/src/lib/asiolink/tests/asiolink_unittest.cc
branches/trac327/src/lib/asiolink/udpdns.cc
branches/trac327/src/lib/bench/Makefile.am
branches/trac327/src/lib/bench/benchmark_util.cc
branches/trac327/src/lib/bench/example/search_bench.cc
branches/trac327/src/lib/bench/tests/Makefile.am
branches/trac327/src/lib/bench/tests/loadquery_unittest.cc
branches/trac327/src/lib/cc/Makefile.am
branches/trac327/src/lib/cc/data.cc
branches/trac327/src/lib/cc/tests/Makefile.am
branches/trac327/src/lib/cc/tests/data_unittests.cc
branches/trac327/src/lib/cc/tests/run_unittests.cc
branches/trac327/src/lib/cc/tests/session_unittests.cc
branches/trac327/src/lib/config/Makefile.am
branches/trac327/src/lib/config/ccsession.cc
branches/trac327/src/lib/config/ccsession.h
branches/trac327/src/lib/config/config_data.h
branches/trac327/src/lib/config/module_spec.cc
branches/trac327/src/lib/config/module_spec.h
branches/trac327/src/lib/config/tests/Makefile.am
branches/trac327/src/lib/config/tests/ccsession_unittests.cc
branches/trac327/src/lib/config/tests/data_def_unittests_config.h.in
branches/trac327/src/lib/config/tests/fake_session.cc
branches/trac327/src/lib/config/tests/fake_session.h
branches/trac327/src/lib/config/tests/module_spec_unittests.cc
branches/trac327/src/lib/config/tests/run_unittests.cc
branches/trac327/src/lib/datasrc/Makefile.am
branches/trac327/src/lib/datasrc/data_source.cc
branches/trac327/src/lib/datasrc/query.cc
branches/trac327/src/lib/datasrc/query.h
branches/trac327/src/lib/datasrc/static_datasrc.cc
branches/trac327/src/lib/datasrc/tests/Makefile.am
branches/trac327/src/lib/datasrc/tests/datasrc_unittest.cc
branches/trac327/src/lib/datasrc/tests/query_unittest.cc
branches/trac327/src/lib/datasrc/tests/run_unittests.cc
branches/trac327/src/lib/datasrc/tests/test_datasrc.cc
branches/trac327/src/lib/dns/Makefile.am
branches/trac327/src/lib/dns/exceptions.cc
branches/trac327/src/lib/dns/gen-rdatacode.py.in
branches/trac327/src/lib/dns/message.cc
branches/trac327/src/lib/dns/message.h
branches/trac327/src/lib/dns/name.h
branches/trac327/src/lib/dns/python/Makefile.am
branches/trac327/src/lib/dns/python/README
branches/trac327/src/lib/dns/python/message_python.cc
branches/trac327/src/lib/dns/python/messagerenderer_python.cc
branches/trac327/src/lib/dns/python/name_python.cc
branches/trac327/src/lib/dns/python/question_python.cc
branches/trac327/src/lib/dns/python/rdata_python.cc
branches/trac327/src/lib/dns/python/rrclass_python.cc
branches/trac327/src/lib/dns/python/rrset_python.cc
branches/trac327/src/lib/dns/python/rrttl_python.cc
branches/trac327/src/lib/dns/python/rrtype_python.cc
branches/trac327/src/lib/dns/python/tests/Makefile.am
branches/trac327/src/lib/dns/python/tests/message_python_test.py
branches/trac327/src/lib/dns/python/tests/messagerenderer_python_test.py
branches/trac327/src/lib/dns/python/tests/name_python_test.py
branches/trac327/src/lib/dns/python/tests/question_python_test.py
branches/trac327/src/lib/dns/python/tests/rdata_python_test.py
branches/trac327/src/lib/dns/python/tests/rrclass_python_test.py
branches/trac327/src/lib/dns/python/tests/rrset_python_test.py
branches/trac327/src/lib/dns/python/tests/rrttl_python_test.py
branches/trac327/src/lib/dns/python/tests/rrtype_python_test.py
branches/trac327/src/lib/dns/question.cc
branches/trac327/src/lib/dns/rdata.cc
branches/trac327/src/lib/dns/rdata/ch_3/a_1.cc
branches/trac327/src/lib/dns/rdata/generic/cname_5.cc
branches/trac327/src/lib/dns/rdata/generic/dname_39.cc
branches/trac327/src/lib/dns/rdata/generic/dnskey_48.cc
branches/trac327/src/lib/dns/rdata/generic/ds_43.cc
branches/trac327/src/lib/dns/rdata/generic/mx_15.cc
branches/trac327/src/lib/dns/rdata/generic/mx_15.h
branches/trac327/src/lib/dns/rdata/generic/ns_2.cc
branches/trac327/src/lib/dns/rdata/generic/nsec3_50.cc
branches/trac327/src/lib/dns/rdata/generic/nsec3param_51.cc
branches/trac327/src/lib/dns/rdata/generic/opt_41.cc
branches/trac327/src/lib/dns/rdata/generic/ptr_12.cc
branches/trac327/src/lib/dns/rdata/generic/rrsig_46.cc
branches/trac327/src/lib/dns/rdata/generic/soa_6.cc
branches/trac327/src/lib/dns/rdata/generic/soa_6.h
branches/trac327/src/lib/dns/rdata/hs_4/a_1.cc
branches/trac327/src/lib/dns/rdata/template.cc
branches/trac327/src/lib/dns/rrclass-placeholder.h
branches/trac327/src/lib/dns/rrclass.cc
branches/trac327/src/lib/dns/rrparamregistry-placeholder.cc
branches/trac327/src/lib/dns/rrset.cc
branches/trac327/src/lib/dns/rrset.h
branches/trac327/src/lib/dns/rrsetlist.cc
branches/trac327/src/lib/dns/rrttl.cc
branches/trac327/src/lib/dns/rrtype-placeholder.h
branches/trac327/src/lib/dns/rrtype.cc
branches/trac327/src/lib/dns/tests/Makefile.am
branches/trac327/src/lib/dns/tests/buffer_unittest.cc
branches/trac327/src/lib/dns/tests/message_unittest.cc
branches/trac327/src/lib/dns/tests/messagerenderer_unittest.cc
branches/trac327/src/lib/dns/tests/name_unittest.cc
branches/trac327/src/lib/dns/tests/question_unittest.cc
branches/trac327/src/lib/dns/tests/rdata_cname_unittest.cc
branches/trac327/src/lib/dns/tests/rdata_dname_unittest.cc
branches/trac327/src/lib/dns/tests/rdata_ns_unittest.cc
branches/trac327/src/lib/dns/tests/rdata_nsec_unittest.cc
branches/trac327/src/lib/dns/tests/rdata_opt_unittest.cc
branches/trac327/src/lib/dns/tests/rdata_ptr_unittest.cc
branches/trac327/src/lib/dns/tests/rdata_rrsig_unittest.cc
branches/trac327/src/lib/dns/tests/rdata_soa_unittest.cc
branches/trac327/src/lib/dns/tests/rdata_txt_unittest.cc
branches/trac327/src/lib/dns/tests/rdata_unittest.cc
branches/trac327/src/lib/dns/tests/rrclass_unittest.cc
branches/trac327/src/lib/dns/tests/rrparamregistry_unittest.cc
branches/trac327/src/lib/dns/tests/rrset_unittest.cc
branches/trac327/src/lib/dns/tests/rrttl_unittest.cc
branches/trac327/src/lib/dns/tests/rrtype_unittest.cc
branches/trac327/src/lib/dns/tests/run_unittests.cc
branches/trac327/src/lib/dns/tests/testdata/gen-wiredata.py.in
branches/trac327/src/lib/dns/tests/unittest_util.cc
branches/trac327/src/lib/dns/util/sha1.cc
branches/trac327/src/lib/exceptions/exceptions.cc
branches/trac327/src/lib/exceptions/exceptions.h
branches/trac327/src/lib/exceptions/tests/run_unittests.cc
branches/trac327/src/lib/python/isc/Makefile.am
branches/trac327/src/lib/python/isc/cc/Makefile.am
branches/trac327/src/lib/python/isc/cc/data.py
branches/trac327/src/lib/python/isc/cc/session.py
branches/trac327/src/lib/python/isc/cc/tests/session_test.py
branches/trac327/src/lib/python/isc/config/Makefile.am
branches/trac327/src/lib/python/isc/config/ccsession.py
branches/trac327/src/lib/python/isc/config/cfgmgr.py
branches/trac327/src/lib/python/isc/config/module_spec.py
branches/trac327/src/lib/python/isc/config/tests/Makefile.am
branches/trac327/src/lib/python/isc/config/tests/ccsession_test.py
branches/trac327/src/lib/python/isc/config/tests/cfgmgr_test.py
branches/trac327/src/lib/python/isc/config/tests/unittest_fakesession.py
branches/trac327/src/lib/python/isc/datasrc/master.py
branches/trac327/src/lib/python/isc/dns/__init__.py
branches/trac327/src/lib/python/isc/log/Makefile.am
branches/trac327/src/lib/python/isc/log/log.py
branches/trac327/src/lib/python/isc/log/tests/log_test.py
branches/trac327/src/lib/python/isc/notify/Makefile.am
branches/trac327/src/lib/python/isc/notify/notify_out.py
branches/trac327/src/lib/python/isc/notify/tests/notify_out_test.py
branches/trac327/src/lib/xfr/Makefile.am
branches/trac327/src/lib/xfr/fd_share.cc
branches/trac327/src/lib/xfr/fd_share.h
branches/trac327/src/lib/xfr/fdshare_python.cc
branches/trac327/src/lib/xfr/python_xfr.cc
branches/trac327/src/lib/xfr/xfrout_client.cc
Modified: branches/trac327/ChangeLog
==============================================================================
--- branches/trac327/ChangeLog (original)
+++ branches/trac327/ChangeLog Wed Nov 10 10:44:42 2010
@@ -3,9 +3,149 @@
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)
+
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 +174,8 @@
zone axfr/ixfr finishing, the server will notify its slaves.
(Trac #289, svn r2737)
- 86. [func] jerry
- bin/zonemgr: Added zone manager module. The zone manager is one
+ 86. [func] jerry
+ bin/zonemgr: Added zone manager module. The zone manager is one
of the co-operating processes of BIND10, which keeps track of
timers and other information necessary for BIND10 to act as a
slave. (Trac #215, svn r2737)
Modified: branches/trac327/README
==============================================================================
--- branches/trac327/README (original)
+++ branches/trac327/README Wed Nov 10 10:44:42 2010
@@ -17,7 +17,8 @@
bus, b10-auth authoritative DNS server (with SQLite3 backend),
b10-cmdctl remote control daemon, b10-cfgmgr configuration manager,
b10-xfrin AXFR inbound service, b10-xfrout outgoing AXFR service,
-and a new libdns++ library for C++ with a python wrapper.
+b10-zonemgr secondary manager, and a new libdns++ library for C++
+with a python wrapper.
Documentation is included and also available via the BIND 10
website at http://bind10.isc.org/
Modified: branches/trac327/configure.ac
==============================================================================
--- branches/trac327/configure.ac (original)
+++ branches/trac327/configure.ac Wed Nov 10 10:44:42 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
@@ -179,7 +206,6 @@
# gcc specific settings:
if test "X$GXX" = "Xyes"; then
B10_CXXFLAGS="-Wall -Wextra -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare"
-UNUSED_PARAM_ATTRIBUTE='__attribute__((unused))'
# Certain versions of gcc (g++) have a bug that incorrectly warns about
# the use of anonymous name spaces even if they're closed in a single
@@ -198,7 +224,6 @@
fi dnl GXX = yes
AM_CONDITIONAL(GCC_WERROR_OK, test $werror_ok = 1)
-AC_DEFINE_UNQUOTED(UNUSED_PARAM, $UNUSED_PARAM_ATTRIBUTE, Define to compiler keyword indicating a function argument is intentionally unused)
# produce PIC unless we disable shared libraries. need this for python bindings.
if test $enable_shared != "no" -a "X$GXX" = "Xyes"; then
@@ -236,7 +261,6 @@
[ --with-gtest=PATH specify a path to gtest header files (PATH/include) and library (PATH/lib)],
gtest_path="$withval", gtest_path="no")
-
USE_LCOV="no"
if test "$lcov" != "no"; then
# force gtest if not set
@@ -270,14 +294,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 +394,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 +435,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 +465,26 @@
src/bin/msgq/tests/Makefile
src/bin/auth/Makefile
src/bin/auth/tests/Makefile
+ src/bin/auth/tests/testdata/Makefile
+ src/bin/auth/benchmarks/Makefile
src/bin/recurse/Makefile
src/bin/recurse/tests/Makefile
+ src/bin/recurse/tests/testdata/Makefile
src/bin/xfrin/Makefile
src/bin/xfrin/tests/Makefile
src/bin/xfrout/Makefile
src/bin/xfrout/tests/Makefile
src/bin/zonemgr/Makefile
src/bin/zonemgr/tests/Makefile
+ src/bin/stats/Makefile
+ src/bin/stats/tests/Makefile
+ src/bin/stats/tests/isc/Makefile
+ src/bin/stats/tests/isc/cc/Makefile
+ src/bin/stats/tests/isc/config/Makefile
+ src/bin/stats/tests/isc/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 +495,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 +504,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 +530,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 +539,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
@@ -501,6 +564,7 @@
src/bin/auth/spec_config.h.pre
src/bin/recurse/recurse.spec.pre
src/bin/recurse/spec_config.h.pre
+ src/bin/tests/process_rename_test.py
src/lib/config/tests/data_def_unittests_config.h
src/lib/python/isc/config/tests/config_test
src/lib/python/isc/cc/tests/cc_test
@@ -516,6 +580,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 +613,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 +644,3 @@
Now you can type "make" to build BIND 10
EOF
-
Modified: branches/trac327/doc/guide/bind10-guide.html
==============================================================================
--- branches/trac327/doc/guide/bind10-guide.html (original)
+++ branches/trac327/doc/guide/bind10-guide.html Wed Nov 10 10:44:42 2010
@@ -1,8 +1,8 @@
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>BIND 10 Guide</title><link rel="stylesheet" href="bind10-guide.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.75.2"><meta name="description" content="This is the reference guide for BIND 10. The most up-to-date version of this document, along with other documents for BIND 10, can be found at ."></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" title="BIND 10 Guide"><div class="titlepage"><div><div><h1 class="title"><a name="id1168230342594"></a>BIND 10 Guide</h1></div><div><h2 class="subtitle">Administrator Reference for BIND 10</h2></div><div><p class="copyright">Copyright © 2010 Internet Systems Consortium, Inc.</p></div><div><div class="abstract" title="Abstract"><p class="title"><b>Abstract</b></p><p>This is the reference guide for BIND 10.</p><p>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>BIND 10 Guide</title><link rel="stylesheet" href="bind10-guide.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.75.2"><meta name="description" content="This is the reference guide for BIND 10. The most up-to-date version of this document, along with other documents for BIND 10, can be found at ."></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" title="BIND 10 Guide"><div class="titlepage"><div><div><h1 class="title"><a name="id1168230298903"></a>BIND 10 Guide</h1></div><div><h2 class="subtitle">Administrator Reference for BIND 10</h2></div><div><p class="copyright">Copyright © 2010 Internet Systems Consortium, Inc.</p></div><div><div class="abstract" title="Abstract"><p class="title"><b>Abstract</b></p><p>This is the reference guide for BIND 10.</p><p>
The most up-to-date version of this document, along with other documents
for BIND 10, can be found at
<a class="ulink" href="http://bind10.isc.org/docs" target="_top">http://bind10.isc.org/docs</a>.
- </p></div></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="chapter"><a href="#intro">1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230342718">Supported Platforms</a></span></dt><dt><span class="section"><a href="#id1168230342746">Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">Managing BIND 10</a></span></dt></dl></dd><dt><span class="chapter"><a href="#installation">2. Installation</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230328220">Building Requirements</a></span></dt><dt><span class="section"><a href="#quickstart">Quick start</a></span></dt><dt><span class="section"><a href="#install">Installation from source</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230328406">Download Tar File</a></span></dt><dt><s
pan class="section"><a href="#id1168230328426">Retrieve from Subversion</a></span></dt><dt><span class="section"><a href="#id1168230328486">Configure before the build</a></span></dt><dt><span class="section"><a href="#id1168230328584">Build</a></span></dt><dt><span class="section"><a href="#id1168230328599">Install</a></span></dt><dt><span class="section"><a href="#id1168230328622">Install Hierarchy</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#bind10">3. Starting BIND10 with <span class="command"><strong>bind10</strong></span></a></span></dt><dd><dl><dt><span class="section"><a href="#start">Starting BIND 10</a></span></dt></dl></dd><dt><span class="chapter"><a href="#msgq">4. Command channel</a></span></dt><dt><span class="chapter"><a href="#cfgmgr">5. Configuration manager</a></span></dt><dt><span class="chapter"><a href="#cmdctl">6. Remote control daemon</a></span></dt><dd><dl><dt><span class="section"><a href="#cmdctl.spec">Configuration specifi
cation for b10-cmdctl</a></span></dt></dl></dd><dt><span class="chapter"><a href="#bindctl">7. Control and configure user interface</a></span></dt><dt><span class="chapter"><a href="#authserver">8. Authoritative Server</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230329190">Server Configurations</a></span></dt><dt><span class="section"><a href="#id1168230329255">Data Source Backends</a></span></dt><dt><span class="section"><a href="#id1168230329285">Loading Master Zones Files</a></span></dt></dl></dd><dt><span class="chapter"><a href="#xfrin">9. Incoming Zone Transfers</a></span></dt><dt><span class="chapter"><a href="#xfrout">10. Outbound Zone Transfers</a></span></dt></dl></div><div class="chapter" title="Chapter 1. Introduction"><div class="titlepage"><div><div><h2 class="title"><a name="intro"></a>Chapter 1. Introduction</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168230342718">S
upported Platforms</a></span></dt><dt><span class="section"><a href="#id1168230342746">Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">Managing BIND 10</a></span></dt></dl></div><p>
+ </p></div></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="chapter"><a href="#intro">1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230299028">Supported Platforms</a></span></dt><dt><span class="section"><a href="#id1168230299056">Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">Managing BIND 10</a></span></dt></dl></dd><dt><span class="chapter"><a href="#installation">2. Installation</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230284542">Building Requirements</a></span></dt><dt><span class="section"><a href="#quickstart">Quick start</a></span></dt><dt><span class="section"><a href="#install">Installation from source</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230284728">Download Tar File</a></span></dt><dt><s
pan class="section"><a href="#id1168230284748">Retrieve from Subversion</a></span></dt><dt><span class="section"><a href="#id1168230284809">Configure before the build</a></span></dt><dt><span class="section"><a href="#id1168230284906">Build</a></span></dt><dt><span class="section"><a href="#id1168230284921">Install</a></span></dt><dt><span class="section"><a href="#id1168230284946">Install Hierarchy</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#bind10">3. Starting BIND10 with <span class="command"><strong>bind10</strong></span></a></span></dt><dd><dl><dt><span class="section"><a href="#start">Starting BIND 10</a></span></dt></dl></dd><dt><span class="chapter"><a href="#msgq">4. Command channel</a></span></dt><dt><span class="chapter"><a href="#cfgmgr">5. Configuration manager</a></span></dt><dt><span class="chapter"><a href="#cmdctl">6. Remote control daemon</a></span></dt><dd><dl><dt><span class="section"><a href="#cmdctl.spec">Configuration specifi
cation for b10-cmdctl</a></span></dt></dl></dd><dt><span class="chapter"><a href="#bindctl">7. Control and configure user interface</a></span></dt><dt><span class="chapter"><a href="#authserver">8. Authoritative Server</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230285515">Server Configurations</a></span></dt><dt><span class="section"><a href="#id1168230285580">Data Source Backends</a></span></dt><dt><span class="section"><a href="#id1168230285610">Loading Master Zones Files</a></span></dt></dl></dd><dt><span class="chapter"><a href="#xfrin">9. Incoming Zone Transfers</a></span></dt><dt><span class="chapter"><a href="#xfrout">10. Outbound Zone Transfers</a></span></dt><dt><span class="chapter"><a href="#zonemgr">11. Secondary Manager</a></span></dt></dl></div><div class="chapter" title="Chapter 1. Introduction"><div class="titlepage"><div><div><h2 class="title"><a name="intro"></a>Chapter 1. Introduction</h2></div></div></div><div class="toc"><p><b>T
able of Contents</b></p><dl><dt><span class="section"><a href="#id1168230299028">Supported Platforms</a></span></dt><dt><span class="section"><a href="#id1168230299056">Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">Managing BIND 10</a></span></dt></dl></div><p>
BIND is the popular implementation of a DNS server, developer
interfaces, and DNS tools.
BIND 10 is a rewrite of BIND 9. BIND 10 is written in C++ and Python
@@ -11,10 +11,10 @@
This guide covers the experimental prototype version of
BIND 10.
</p></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
- BIND 10, at this time, does not provide an recursive
+ BIND 10, at this time, does not provide a recursive
DNS server. It does provide a EDNS0- and DNSSEC-capable
authoritative DNS server.
- </p></div><div class="section" title="Supported Platforms"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230342718"></a>Supported Platforms</h2></div></div></div><p>
+ </p></div><div class="section" title="Supported Platforms"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230299028"></a>Supported Platforms</h2></div></div></div><p>
BIND 10 builds have been tested on Debian GNU/Linux 5,
Ubuntu 9.10, NetBSD 5, Solaris 10, FreeBSD 7, and CentOS
Linux 5.3.
@@ -24,16 +24,16 @@
It is planned for BIND 10 to build, install and run on
Windows and standard Unix-type platforms.
- </p></div><div class="section" title="Required Software"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230342746"></a>Required Software</h2></div></div></div><p>
+ </p></div><div class="section" title="Required Software"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230299056"></a>Required Software</h2></div></div></div><p>
BIND 10 requires Python 3.1. Later versions may work, but Python
3.1 is the minimum version which will work.
</p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
For this development prototype release, the only supported
data source backend is SQLite3. The authoritative server
requires SQLite 3.3.9 or newer.
- The <span class="command"><strong>b10-xfrin</strong></span> and <span class="command"><strong>b10-xfrout</strong></span>
- modules require the libpython3 library and the Python
- _sqlite3.so module.
+ The <span class="command"><strong>b10-xfrin</strong></span>, <span class="command"><strong>b10-xfrout</strong></span>,
+ and <span class="command"><strong>b10-zonemgr</strong></span> modules require the
+ libpython3 library and the Python _sqlite3.so module.
</p></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
Some operating systems do not provide these dependencies
in their default installation nor standard packages
@@ -83,6 +83,11 @@
This process is used to handle transfer requests to
send a local zone to a remote secondary server,
when acting as a master server.
+ </li><li class="listitem">
+ <span class="command"><strong>b10-zonemgr</strong></span> —
+ Secondary manager.
+ This process keeps track of timers and other
+ necessary information for BIND 10 to act as a slave server.
</li></ul></div><p>
</p><p>
These are ran automatically by <span class="command"><strong>bind10</strong></span>
@@ -116,7 +121,7 @@
and, of course, DNS. These include detailed developer
documentation and code examples.
- </p></div><div class="chapter" title="Chapter 2. Installation"><div class="titlepage"><div><div><h2 class="title"><a name="installation"></a>Chapter 2. Installation</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168230328220">Building Requirements</a></span></dt><dt><span class="section"><a href="#quickstart">Quick start</a></span></dt><dt><span class="section"><a href="#install">Installation from source</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230328406">Download Tar File</a></span></dt><dt><span class="section"><a href="#id1168230328426">Retrieve from Subversion</a></span></dt><dt><span class="section"><a href="#id1168230328486">Configure before the build</a></span></dt><dt><span class="section"><a href="#id1168230328584">Build</a></span></dt><dt><span class="section"><a href="#id1168230328599">Install</a></span></dt><dt><span class="section"><a href="#id1168230328622">Install
Hierarchy</a></span></dt></dl></dd></dl></div><div class="section" title="Building Requirements"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230328220"></a>Building Requirements</h2></div></div></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ </p></div><div class="chapter" title="Chapter 2. Installation"><div class="titlepage"><div><div><h2 class="title"><a name="installation"></a>Chapter 2. Installation</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168230284542">Building Requirements</a></span></dt><dt><span class="section"><a href="#quickstart">Quick start</a></span></dt><dt><span class="section"><a href="#install">Installation from source</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230284728">Download Tar File</a></span></dt><dt><span class="section"><a href="#id1168230284748">Retrieve from Subversion</a></span></dt><dt><span class="section"><a href="#id1168230284809">Configure before the build</a></span></dt><dt><span class="section"><a href="#id1168230284906">Build</a></span></dt><dt><span class="section"><a href="#id1168230284921">Install</a></span></dt><dt><span class="section"><a href="#id1168230284946">Install
Hierarchy</a></span></dt></dl></dd></dl></div><div class="section" title="Building Requirements"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230284542"></a>Building Requirements</h2></div></div></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
Some operating systems have split their distribution packages into
a run-time and a development package. You will need to install
the development package versions, which include header files and
@@ -176,14 +181,14 @@
the Subversion code revision control system or as a downloadable
tar file. It may also be available in pre-compiled ready-to-use
packages from operating system vendors.
- </p><div class="section" title="Download Tar File"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230328406"></a>Download Tar File</h3></div></div></div><p>
+ </p><div class="section" title="Download Tar File"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230284728"></a>Download Tar File</h3></div></div></div><p>
Downloading a release tar file is the recommended method to
obtain the source code.
</p><p>
The BIND 10 releases are available as tar file downloads from
<a class="ulink" href="ftp://ftp.isc.org/isc/bind10/" target="_top">ftp://ftp.isc.org/isc/bind10/</a>.
Periodic development snapshots may also be available.
- </p></div><div class="section" title="Retrieve from Subversion"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230328426"></a>Retrieve from Subversion</h3></div></div></div><p>
+ </p></div><div class="section" title="Retrieve from Subversion"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230284748"></a>Retrieve from Subversion</h3></div></div></div><p>
Downloading this "bleeding edge" code is recommended only for
developers or advanced users. Using development code in a production
environment is not recommended.
@@ -215,7 +220,7 @@
<span class="command"><strong>autoheader</strong></span>,
<span class="command"><strong>automake</strong></span>,
and related commands.
- </p></div><div class="section" title="Configure before the build"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230328486"></a>Configure before the build</h3></div></div></div><p>
+ </p></div><div class="section" title="Configure before the build"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230284809"></a>Configure before the build</h3></div></div></div><p>
BIND 10 uses the GNU Build System to discover build environment
details.
To generate the makefiles using the defaults, simply run:
@@ -246,16 +251,16 @@
</p><p>
If the configure fails, it may be due to missing or old
dependencies.
- </p></div><div class="section" title="Build"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230328584"></a>Build</h3></div></div></div><p>
+ </p></div><div class="section" title="Build"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230284906"></a>Build</h3></div></div></div><p>
After the configure step is complete, to build the executables
from the C++ code and prepare the Python scripts, run:
</p><pre class="screen">$ <strong class="userinput"><code>make</code></strong></pre><p>
- </p></div><div class="section" title="Install"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230328599"></a>Install</h3></div></div></div><p>
+ </p></div><div class="section" title="Install"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230284921"></a>Install</h3></div></div></div><p>
To install the BIND 10 executables, support files,
and documentation, run:
</p><pre class="screen">$ <strong class="userinput"><code>make install</code></strong></pre><p>
- </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>The install step may require superuser privileges.</p></div></div><div class="section" title="Install Hierarchy"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230328622"></a>Install Hierarchy</h3></div></div></div><p>
+ </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>The install step may require superuser privileges.</p></div></div><div class="section" title="Install Hierarchy"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230284946"></a>Install Hierarchy</h3></div></div></div><p>
The following is the layout of the complete BIND 10 installation:
</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<code class="filename">bin/</code> —
@@ -307,8 +312,9 @@
The <span class="command"><strong>bind10</strong></span> master process will also start up
<span class="command"><strong>b10-cmdctl</strong></span> for admins to communicate with the
system, <span class="command"><strong>b10-auth</strong></span> for Authoritative DNS service,
- <span class="command"><strong>b10-xfrin</strong></span> for inbound DNS zone transfers.
- and <span class="command"><strong>b10-xfrout</strong></span> for outbound DNS zone transfers.
+ <span class="command"><strong>b10-xfrin</strong></span> for inbound DNS zone transfers,
+ <span class="command"><strong>b10-xfrout</strong></span> for outbound DNS zone transfers,
+ and <span class="command"><strong>b10-zonemgr</strong></span> for secondary service.
</p><div class="section" title="Starting BIND 10"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="start"></a>Starting BIND 10</h2></div></div></div><p>
To start the BIND 10 service, simply run <span class="command"><strong>bind10</strong></span>.
Run it with the <code class="option">--verbose</code> switch to
@@ -467,7 +473,7 @@
the details and relays (over a <span class="command"><strong>b10-msgq</strong></span> command
channel) the configuration on to the specified module.
</p><p>
- </p></div><div class="chapter" title="Chapter 8. Authoritative Server"><div class="titlepage"><div><div><h2 class="title"><a name="authserver"></a>Chapter 8. Authoritative Server</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168230329190">Server Configurations</a></span></dt><dt><span class="section"><a href="#id1168230329255">Data Source Backends</a></span></dt><dt><span class="section"><a href="#id1168230329285">Loading Master Zones Files</a></span></dt></dl></div><p>
+ </p></div><div class="chapter" title="Chapter 8. Authoritative Server"><div class="titlepage"><div><div><h2 class="title"><a name="authserver"></a>Chapter 8. Authoritative Server</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168230285515">Server Configurations</a></span></dt><dt><span class="section"><a href="#id1168230285580">Data Source Backends</a></span></dt><dt><span class="section"><a href="#id1168230285610">Loading Master Zones Files</a></span></dt></dl></div><p>
The <span class="command"><strong>b10-auth</strong></span> is the authoritative DNS server.
It supports EDNS0 and DNSSEC. It supports IPv6.
Normally it is started by the <span class="command"><strong>bind10</strong></span> master
@@ -475,7 +481,7 @@
</p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
This development prototype release listens on all interfaces
and the non-standard port 5300.
- </p></div><div class="section" title="Server Configurations"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230329190"></a>Server Configurations</h2></div></div></div><p>
+ </p></div><div class="section" title="Server Configurations"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230285515"></a>Server Configurations</h2></div></div></div><p>
<span class="command"><strong>b10-auth</strong></span> is configured via the
<span class="command"><strong>b10-cfgmgr</strong></span> configuration manager.
The module name is <span class="quote">“<span class="quote">Auth</span>”</span>.
@@ -495,7 +501,7 @@
</p><div class="variablelist"><dl><dt><span class="term">shutdown</span></dt><dd>Stop the authoritative DNS server.
</dd></dl></div><p>
- </p></div><div class="section" title="Data Source Backends"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230329255"></a>Data Source Backends</h2></div></div></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ </p></div><div class="section" title="Data Source Backends"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230285580"></a>Data Source Backends</h2></div></div></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
For the development prototype release, <span class="command"><strong>b10-auth</strong></span>
only supports the SQLite3 data source backend.
Upcoming versions will be able to use multiple different
@@ -508,7 +514,7 @@
The default is <code class="filename">/usr/local/var/</code>.)
This data file location may be changed by defining the
<span class="quote">“<span class="quote">database_file</span>”</span> configuration.
- </p></div><div class="section" title="Loading Master Zones Files"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230329285"></a>Loading Master Zones Files</h2></div></div></div><p>
+ </p></div><div class="section" title="Loading Master Zones Files"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230285610"></a>Loading Master Zones Files</h2></div></div></div><p>
RFC 1035 style DNS master zone files may imported
into a BIND 10 data source by using the
<span class="command"><strong>b10-loadzone</strong></span> utility.
@@ -544,12 +550,12 @@
transfer. When received, it is stored in the BIND 10
data store, and its records can be served by
<span class="command"><strong>b10-auth</strong></span>.
- This allows the BIND 10 server to provide
- <span class="quote">“<span class="quote">secondary</span>”</span> service.
+ In combination with <span class="command"><strong>b10-zonemgr</strong></span> (for
+ automated SOA checks), this allows the BIND 10 server to
+ provide <span class="quote">“<span class="quote">secondary</span>”</span> service.
</p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
The current development release of BIND 10 only supports
AXFR. (IXFR is not supported.)
- It also does not yet support automated SOA checks.
</p></div><p>
To manually trigger a zone transfer to retrieve a remote zone,
you may use the <span class="command"><strong>bindctl</strong></span> utility.
@@ -564,9 +570,24 @@
sends the zone.
This is used to provide master DNS service to share zones
to secondary name servers.
+ The <span class="command"><strong>b10-xfrout</strong></span> is also used to send
+ NOTIFY messages to slaves.
</p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
The current development release of BIND 10 only supports
AXFR. (IXFR is not supported.)
- It also does not yet support NOTIFY.
Access control is not yet provided.
+ </p></div></div><div class="chapter" title="Chapter 11. Secondary Manager"><div class="titlepage"><div><div><h2 class="title"><a name="zonemgr"></a>Chapter 11. Secondary Manager</h2></div></div></div><p>
+ The <span class="command"><strong>b10-zonemgr</strong></span> process is started by
+ <span class="command"><strong>bind10</strong></span>.
+ It keeps track of SOA refresh, retry, and expire timers
+ and other details for BIND 10 to perform as a slave.
+ When the <span class="command"><strong>b10-auth</strong></span> authoritative DNS server
+ receives a NOTIFY message, <span class="command"><strong>b10-zonemgr</strong></span>
+ may tell <span class="command"><strong>b10-xfrin</strong></span> to do a refresh
+ to start an inbound zone transfer.
+ The secondary manager resets its counters when a new zone is
+ transferred in.
+ </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ Access control (such as allowing notifies) is not yet provided.
+ The primary/secondary service is not yet complete.
</p></div></div></div></body></html>
Modified: branches/trac327/doc/guide/bind10-guide.xml
==============================================================================
--- branches/trac327/doc/guide/bind10-guide.xml (original)
+++ branches/trac327/doc/guide/bind10-guide.xml Wed Nov 10 10:44:42 2010
@@ -42,7 +42,7 @@
<note>
<para>
- BIND 10, at this time, does not provide an recursive
+ BIND 10, at this time, does not provide a recursive
DNS server. It does provide a EDNS0- and DNSSEC-capable
authoritative DNS server.
</para>
@@ -74,9 +74,9 @@
For this development prototype release, the only supported
data source backend is SQLite3. The authoritative server
requires SQLite 3.3.9 or newer.
- The <command>b10-xfrin</command> and <command>b10-xfrout</command>
- modules require the libpython3 library and the Python
- _sqlite3.so module.
+ The <command>b10-xfrin</command>, <command>b10-xfrout</command>,
+ and <command>b10-zonemgr</command> modules require the
+ libpython3 library and the Python _sqlite3.so module.
</para></note>
<!-- TODO: this will change ... -->
@@ -165,6 +165,15 @@
</simpara>
</listitem>
+ <listitem>
+ <simpara>
+ <command>b10-zonemgr</command> —
+ Secondary manager.
+ This process keeps track of timers and other
+ necessary information for BIND 10 to act as a slave server.
+ </simpara>
+ </listitem>
+
</itemizedlist>
</para>
@@ -650,8 +659,9 @@
The <command>bind10</command> master process will also start up
<command>b10-cmdctl</command> for admins to communicate with the
system, <command>b10-auth</command> for Authoritative DNS service,
- <command>b10-xfrin</command> for inbound DNS zone transfers.
- and <command>b10-xfrout</command> for outbound DNS zone transfers.
+ <command>b10-xfrin</command> for inbound DNS zone transfers,
+ <command>b10-xfrout</command> for outbound DNS zone transfers,
+ and <command>b10-zonemgr</command> for secondary service.
</para>
<section id="start">
@@ -1173,14 +1183,14 @@
transfer. When received, it is stored in the BIND 10
data store, and its records can be served by
<command>b10-auth</command>.
- This allows the BIND 10 server to provide
- <quote>secondary</quote> service.
+ In combination with <command>b10-zonemgr</command> (for
+ automated SOA checks), this allows the BIND 10 server to
+ provide <quote>secondary</quote> service.
</para>
<note><simpara>
The current development release of BIND 10 only supports
AXFR. (IXFR is not supported.)
- It also does not yet support automated SOA checks.
</simpara></note>
<para>
@@ -1204,12 +1214,13 @@
sends the zone.
This is used to provide master DNS service to share zones
to secondary name servers.
+ The <command>b10-xfrout</command> is also used to send
+ NOTIFY messages to slaves.
</para>
<note><simpara>
The current development release of BIND 10 only supports
AXFR. (IXFR is not supported.)
- It also does not yet support NOTIFY.
Access control is not yet provided.
</simpara></note>
@@ -1226,6 +1237,31 @@
</chapter>
+ <chapter id="zonemgr">
+ <title>Secondary Manager</title>
+
+ <para>
+ The <command>b10-zonemgr</command> process is started by
+ <command>bind10</command>.
+ It keeps track of SOA refresh, retry, and expire timers
+ and other details for BIND 10 to perform as a slave.
+ When the <command>b10-auth</command> authoritative DNS server
+ receives a NOTIFY message, <command>b10-zonemgr</command>
+ may tell <command>b10-xfrin</command> to do a refresh
+ to start an inbound zone transfer.
+ The secondary manager resets its counters when a new zone is
+ transferred in.
+ </para>
+
+ <note><simpara>
+ Access control (such as allowing notifies) is not yet provided.
+ The primary/secondary service is not yet complete.
+ </simpara></note>
+
+<!-- TODO: lots to describe for zonemgr -->
+
+ </chapter>
+
<!-- TODO: how to help: run unit tests, join lists, review trac tickets -->
<!-- <index> <title>Index</title> </index> -->
Modified: branches/trac327/src/bin/Makefile.am
==============================================================================
--- branches/trac327/src/bin/Makefile.am (original)
+++ branches/trac327/src/bin/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,1 +1,4 @@
-SUBDIRS = bind10 bindctl cfgmgr loadzone msgq host cmdctl auth recurse xfrin xfrout usermgr zonemgr
+SUBDIRS = bind10 bindctl cfgmgr loadzone msgq host cmdctl auth recurse xfrin \
+ xfrout usermgr zonemgr stats tests
+
+check-recursive: all-recursive
Modified: branches/trac327/src/bin/auth/Makefile.am
==============================================================================
--- branches/trac327/src/bin/auth/Makefile.am (original)
+++ branches/trac327/src/bin/auth/Makefile.am Wed Nov 10 10:44:42 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)
Modified: branches/trac327/src/bin/auth/auth_srv.cc
==============================================================================
--- branches/trac327/src/bin/auth/auth_srv.cc (original)
+++ branches/trac327/src/bin/auth/auth_srv.cc Wed Nov 10 10:44:42 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>
@@ -76,7 +79,7 @@
OutputBufferPtr buffer);
bool processAxfrQuery(const IOMessage& io_message, MessagePtr message,
OutputBufferPtr buffer);
- bool processNotify(const IOMessage& io_message, MessagePtr message,
+ bool processNotify(const IOMessage& io_message, MessagePtr message,
OutputBufferPtr buffer);
/// Currently non-configurable, but will be.
@@ -87,6 +90,8 @@
bool verbose_mode_;
AbstractSession* xfrin_session_;
+ /// Hot spot cache
+ isc::datasrc::HotCache cache_;
private:
std::string db_file_;
@@ -98,9 +103,6 @@
bool xfrout_connected_;
AbstractXfroutClient& xfrout_client_;
-
- /// Hot spot cache
- isc::datasrc::HotCache cache_;
};
AuthSrvImpl::AuthSrvImpl(const bool use_cache,
@@ -155,13 +157,15 @@
{
MessageRenderer renderer(*buffer);
if (io_message.getSocket().getProtocol() == IPPROTO_UDP) {
- renderer.setLengthLimit(message->getUDPSize());
+ ConstEDNSPtr edns(message->getEDNS());
+ renderer.setLengthLimit(edns ? edns->getUDPSize() :
+ Message::DEFAULT_MAX_UDPSIZE);
} else {
renderer.setLengthLimit(65535);
}
message->toWire(renderer);
if (server_->getVerbose()) {
- cerr << "[b10-recurse] sending a response (" << renderer.getLength()
+ cerr << "[b10-auth] sending a response (" << renderer.getLength()
<< " bytes):\n" << message->toText() << endl;
}
}
@@ -176,7 +180,7 @@
class ConfigChecker : public SimpleCallback {
public:
ConfigChecker(AuthSrv* srv) : server_(srv) {}
- virtual void operator()(const IOMessage& io_message UNUSED_PARAM) const {
+ virtual void operator()(const IOMessage&) const {
if (server_->getConfigSession()->hasQueuedMsgs()) {
server_->getConfigSession()->checkCommand();
}
@@ -217,8 +221,8 @@
// XXX: with the current implementation, it's not easy to set EDNS0
// depending on whether the query had it. So we'll simply omit it.
const qid_t qid = message->getQid();
- const bool rd = message->getHeaderFlag(MessageFlag::RD());
- const bool cd = message->getHeaderFlag(MessageFlag::CD());
+ const bool rd = message->getHeaderFlag(Message::HEADERFLAG_RD);
+ const bool cd = message->getHeaderFlag(Message::HEADERFLAG_CD);
const Opcode& opcode = message->getOpcode();
vector<QuestionPtr> questions;
@@ -231,13 +235,12 @@
message->clear(Message::RENDER);
message->setQid(qid);
message->setOpcode(opcode);
- message->setHeaderFlag(MessageFlag::QR());
- message->setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
+ message->setHeaderFlag(Message::HEADERFLAG_QR);
if (rd) {
- message->setHeaderFlag(MessageFlag::RD());
+ message->setHeaderFlag(Message::HEADERFLAG_RD);
}
if (cd) {
- message->setHeaderFlag(MessageFlag::CD());
+ message->setHeaderFlag(Message::HEADERFLAG_CD);
}
for_each(questions.begin(), questions.end(), QuestionInserter(message));
message->setRcode(rcode);
@@ -260,6 +263,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 +302,7 @@
message->parseHeader(request_buffer);
// Ignore all responses.
- if (message->getHeaderFlag(MessageFlag::QR())) {
+ if (message->getHeaderFlag(Message::HEADERFLAG_QR)) {
if (impl_->verbose_mode_) {
cerr << "[b10-auth] received unexpected response, ignoring"
<< endl;
@@ -342,7 +355,7 @@
}
makeErrorMessage(message, buffer, Rcode::NOTIMP(),
impl_->verbose_mode_);
- } else if (message->getRRCount(Section::QUESTION()) != 1) {
+ } else if (message->getRRCount(Message::SECTION_QUESTION) != 1) {
makeErrorMessage(message, buffer, Rcode::FORMERR(),
impl_->verbose_mode_);
} else {
@@ -365,14 +378,21 @@
AuthSrvImpl::processNormalQuery(const IOMessage& io_message, MessagePtr message,
OutputBufferPtr buffer)
{
- const bool dnssec_ok = message->isDNSSECSupported();
- const uint16_t remote_bufsize = message->getUDPSize();
+ ConstEDNSPtr remote_edns = message->getEDNS();
+ const bool dnssec_ok = remote_edns && remote_edns->getDNSSECAwareness();
+ const uint16_t remote_bufsize = remote_edns ? remote_edns->getUDPSize() :
+ Message::DEFAULT_MAX_UDPSIZE;
message->makeResponse();
- message->setHeaderFlag(MessageFlag::AA());
+ message->setHeaderFlag(Message::HEADERFLAG_AA);
message->setRcode(Rcode::NOERROR());
- message->setDNSSECSupported(dnssec_ok);
- message->setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
+
+ if (remote_edns) {
+ EDNSPtr local_edns = EDNSPtr(new EDNS());
+ local_edns->setDNSSECAwareness(dnssec_ok);
+ local_edns->setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
+ message->setEDNS(local_edns);
+ }
try {
Query query(*message, cache_, dnssec_ok);
@@ -415,8 +435,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 +452,7 @@
xfrout_client_.disconnect();
xfrout_connected_ = false;
}
-
+
if (verbose_mode_) {
cerr << "[b10-auth] Error in handling XFR request: " << err.what()
<< endl;
@@ -438,9 +460,6 @@
makeErrorMessage(message, buffer, Rcode::SERVFAIL(), verbose_mode_);
return (true);
}
-
- xfrout_client_.disconnect();
- xfrout_connected_ = false;
return (false);
}
@@ -451,10 +470,10 @@
{
// The incoming notify must contain exactly one question for SOA of the
// zone name.
- if (message->getRRCount(Section::QUESTION()) != 1) {
+ if (message->getRRCount(Message::SECTION_QUESTION) != 1) {
if (verbose_mode_) {
cerr << "[b10-auth] invalid number of questions in notify: "
- << message->getRRCount(Section::QUESTION()) << endl;
+ << message->getRRCount(Message::SECTION_QUESTION) << endl;
}
makeErrorMessage(message, buffer, Rcode::FORMERR(), verbose_mode_);
return (true);
@@ -487,7 +506,7 @@
}
return (false);
}
-
+
const string remote_ip_address =
io_message.getRemoteEndpoint().getAddress().toText();
static const string command_template_start =
@@ -498,7 +517,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 +531,7 @@
if (rcode != 0) {
if (verbose_mode_) {
cerr << "[b10-auth] failed to notify Zonemgr: "
- << parsed_answer->str() << endl;
+ << parsed_answer->str() << endl;
}
return (false);
}
@@ -524,7 +543,7 @@
}
message->makeResponse();
- message->setHeaderFlag(MessageFlag::AA());
+ message->setHeaderFlag(Message::HEADERFLAG_AA);
message->setRcode(Rcode::NOERROR());
MessageRenderer renderer(*buffer);
Modified: branches/trac327/src/bin/auth/auth_srv.h
==============================================================================
--- branches/trac327/src/bin/auth/auth_srv.h (original)
+++ branches/trac327/src/bin/auth/auth_srv.h Wed Nov 10 10:44:42 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,17 +96,80 @@
/// \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;
- /// \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.
void setConfigSession(isc::config::ModuleCCSession* config_session);
- isc::config::ModuleCCSession* getConfigSession() const;
-
- /// \brief Handle commands from the config session
- isc::data::ConstElementPtr updateConfig(isc::data::ConstElementPtr config);
/// \brief Assign an ASIO IO Service queue to this Recursor object
void setIOService(asiolink::IOService& ios) { io_service_ = &ios; }
@@ -101,6 +186,28 @@
/// \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.
+ ///
+ /// 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 +220,7 @@
/// Ownership isn't transferred: the caller is responsible for keeping
/// this object to be valid while the server object is working and for
/// disconnecting the session and destroying the object when the server
+ /// is shutdown.
///
void setXfrinSession(isc::cc::AbstractSession* xfrin_session);
private:
Modified: branches/trac327/src/bin/auth/b10-auth.8
==============================================================================
--- branches/trac327/src/bin/auth/b10-auth.8 (original)
+++ branches/trac327/src/bin/auth/b10-auth.8 Wed Nov 10 10:44:42 2010
@@ -137,6 +137,7 @@
\fBb10-cmdctl\fR(8),
\fBb10-loadzone\fR(8),
\fBb10-msgq\fR(8),
+\fBb10-zonemgr\fR(8),
\fBbind10\fR(8),
BIND 10 Guide\&.
.SH "HISTORY"
Modified: branches/trac327/src/bin/auth/b10-auth.xml
==============================================================================
--- branches/trac327/src/bin/auth/b10-auth.xml (original)
+++ branches/trac327/src/bin/auth/b10-auth.xml Wed Nov 10 10:44:42 2010
@@ -201,6 +201,9 @@
<refentrytitle>b10-msgq</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
+ <refentrytitle>b10-zonemgr</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
<refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citetitle>BIND 10 Guide</citetitle>.
Modified: branches/trac327/src/bin/auth/benchmarks/Makefile.am
==============================================================================
--- branches/trac327/src/bin/auth/benchmarks/Makefile.am (original)
+++ branches/trac327/src/bin/auth/benchmarks/Makefile.am Wed Nov 10 10:44:42 2010
@@ -17,5 +17,5 @@
query_bench_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
query_bench_LDADD += $(top_builddir)/src/lib/cc/libcc.la
query_bench_LDADD += $(top_builddir)/src/lib/xfr/libxfr.la
-query_bench_LDADD += $(top_builddir)/src/bin/auth/libasio_link.a
+query_bench_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
query_bench_LDADD += $(SQLITE_LIBS)
Modified: branches/trac327/src/bin/auth/benchmarks/query_bench.cc
==============================================================================
--- branches/trac327/src/bin/auth/benchmarks/query_bench.cc (original)
+++ branches/trac327/src/bin/auth/benchmarks/query_bench.cc Wed Nov 10 10:44:42 2010
@@ -26,7 +26,6 @@
#include <dns/buffer.h>
#include <dns/message.h>
-#include <dns/messagerenderer.h>
#include <dns/name.h>
#include <dns/question.h>
#include <dns/rrclass.h>
@@ -34,7 +33,7 @@
#include <xfr/xfrout_client.h>
#include <auth/auth_srv.h>
-#include <auth/asio_link.h>
+#include <asiolink/asiolink.h>
using namespace std;
using namespace isc;
@@ -42,11 +41,21 @@
using namespace isc::dns;
using namespace isc::xfr;
using namespace isc::bench;
-using namespace asio_link;
+using namespace asiolink;
namespace {
// Commonly used constant:
XfroutClient xfrout_client("dummy_path"); // path doesn't matter
+
+// Just something to pass as the server to resume
+class DummyServer : public DNSServer {
+ public:
+ virtual void operator()(asio::error_code, size_t) { }
+ virtual void resume(const bool) { }
+ virtual DNSServer* clone() {
+ return new DummyServer(*this);
+ }
+};
class QueryBenchMark {
private:
@@ -56,12 +65,12 @@
typedef boost::shared_ptr<const IOEndpoint> IOEndpointPtr;
public:
QueryBenchMark(const int cache_slots, const char* const datasrc_file,
- const BenchQueries& queries, Message& query_message,
- MessageRenderer& renderer) :
+ const BenchQueries& queries, MessagePtr query_message,
+ OutputBufferPtr buffer) :
server_(new AuthSrv(cache_slots >= 0 ? true : false, xfrout_client)),
queries_(queries),
query_message_(query_message),
- renderer_(renderer),
+ buffer_(buffer),
dummy_socket(IOSocket::getDummyUDPSocket()),
dummy_endpoint(IOEndpointPtr(IOEndpoint::create(IPPROTO_UDP,
IOAddress("192.0.2.1"),
@@ -76,12 +85,13 @@
unsigned int run() {
BenchQueries::const_iterator query;
const BenchQueries::const_iterator query_end = queries_.end();
+ DummyServer server;
for (query = queries_.begin(); query != query_end; ++query) {
IOMessage io_message(&(*query)[0], (*query).size(), dummy_socket,
*dummy_endpoint);
- query_message_.clear(Message::PARSE);
- renderer_.clear();
- server_->processMessage(io_message, query_message_, renderer_);
+ query_message_->clear(Message::PARSE);
+ server_->processMessage(io_message, query_message_, buffer_,
+ &server);
}
return (queries_.size());
@@ -89,11 +99,12 @@
private:
AuthSrvPtr server_;
const BenchQueries& queries_;
- Message& query_message_;
- MessageRenderer& renderer_;
+ MessagePtr query_message_;
+ OutputBufferPtr buffer_;
IOSocket& dummy_socket;
IOEndpointPtr dummy_endpoint;
};
+
}
namespace isc {
@@ -143,9 +154,8 @@
BenchQueries queries;
loadQueryData(query_data_file, queries, RRClass::IN());
- OutputBuffer buffer(4096);
- MessageRenderer renderer(buffer);
- Message message(Message::PARSE);
+ OutputBufferPtr buffer(new OutputBuffer(4096));
+ MessagePtr message(new Message(Message::PARSE));
cout << "Parameters:" << endl;
cout << " Iterations: " << iteration << endl;
@@ -157,24 +167,24 @@
<< endl;
BenchMark<QueryBenchMark>(iteration,
QueryBenchMark(0, datasrc_file, queries, message,
- renderer));
+ buffer));
cout << "Benchmark enabling Hot Spot Cache with 10*#queries slots "
<< endl;
BenchMark<QueryBenchMark>(iteration,
QueryBenchMark(10 * queries.size(), datasrc_file,
- queries, message, renderer));
+ queries, message, buffer));
cout << "Benchmark enabling Hot Spot Cache with #queries/2 slots "
<< endl;
BenchMark<QueryBenchMark>(iteration,
QueryBenchMark(queries.size() / 2, datasrc_file,
- queries, message, renderer));
+ queries, message, buffer));
cout << "Benchmark disabling Hot Spot Cache" << endl;
BenchMark<QueryBenchMark>(iteration,
QueryBenchMark(-1, datasrc_file, queries,
- message, renderer));
+ message, buffer));
return (0);
}
Modified: branches/trac327/src/bin/auth/tests/Makefile.am
==============================================================================
--- branches/trac327/src/bin/auth/tests/Makefile.am (original)
+++ branches/trac327/src/bin/auth/tests/Makefile.am Wed Nov 10 10:44:42 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: branches/trac327/src/bin/auth/tests/auth_srv_unittest.cc
==============================================================================
--- branches/trac327/src/bin/auth/tests/auth_srv_unittest.cc (original)
+++ branches/trac327/src/bin/auth/tests/auth_srv_unittest.cc Wed Nov 10 10:44:42 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>
@@ -52,18 +54,6 @@
const char* const BADCONFIG_TESTDB =
"{ \"database_file\": \"" TEST_DATA_DIR "/nodir/notexist\"}";
const char* const DEFAULT_REMOTE_ADDRESS = "192.0.2.1";
-
-class DummySocket : public IOSocket {
-private:
- DummySocket(const DummySocket& source);
- DummySocket& operator=(const DummySocket& source);
-public:
- DummySocket(const int protocol) : protocol_(protocol) {}
- virtual int getNative() const { return (-1); }
- virtual int getProtocol() const { return (protocol_); }
-private:
- const int protocol_;
-};
class AuthSrvTest : public ::testing::Test {
protected:
@@ -102,9 +92,8 @@
vector<uint8_t> data;
void createDataFromFile(const char* const datafile, int protocol);
- void createRequestPacket(Message& message, int protocol);
+ void createRequestPacket(Message& message, const int protocol);
};
-
// These are flags to indicate whether the corresponding flag bit of the
// DNS header is to be set in the test cases. (Note that the flag values
@@ -129,7 +118,8 @@
endpoint = IOEndpoint::create(protocol,
IOAddress(DEFAULT_REMOTE_ADDRESS), 5300);
UnitTestUtil::readWireData(datafile, data);
- io_sock = new DummySocket(protocol);
+ io_sock = (protocol == IPPROTO_UDP) ? &IOSocket::getDummyUDPSocket() :
+ &IOSocket::getDummyTCPSocket();
io_message = new IOMessage(&data[0], data.size(), *io_sock, *endpoint);
}
@@ -140,11 +130,11 @@
message.toWire(request_renderer);
delete io_message;
- delete io_sock;
endpoint = IOEndpoint::create(protocol,
IOAddress(DEFAULT_REMOTE_ADDRESS), 5300);
- io_sock = new DummySocket(protocol);
+ io_sock = (protocol == IPPROTO_UDP) ? &IOSocket::getDummyUDPSocket() :
+ &IOSocket::getDummyTCPSocket();
io_message = new IOMessage(request_renderer.getData(),
request_renderer.getLength(),
*io_sock, *endpoint);
@@ -160,18 +150,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,7 +180,7 @@
i == Opcode::NOTIFY().getCode()) {
continue;
}
- createDataFromFile("simplequery_fromWire");
+ createDataFromFile("simplequery_fromWire.wire");
data[2] = ((i << 3) & 0xff);
parse_message->clear(Message::PARSE);
@@ -206,7 +203,7 @@
// Multiple questions. Should result in FORMERR.
TEST_F(AuthSrvTest, multiQuestion) {
- createDataFromFile("multiquestion_fromWire");
+ createDataFromFile("multiquestion_fromWire.wire");
server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
@@ -236,7 +233,7 @@
// or malformed or could otherwise cause a protocol error.
TEST_F(AuthSrvTest, response) {
// A valid (although unusual) response
- createDataFromFile("simpleresponse_fromWire");
+ createDataFromFile("simpleresponse_fromWire.wire");
server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
EXPECT_FALSE(dnsserv.hasAnswer());
@@ -247,7 +244,7 @@
EXPECT_FALSE(dnsserv.hasAnswer());
// A response to iquery. must be dropped rather than returning NOTIMP.
- createDataFromFile("iqueryresponse_fromWire");
+ createDataFromFile("iqueryresponse_fromWire.wire");
server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
EXPECT_FALSE(dnsserv.hasAnswer());
}
@@ -265,7 +262,7 @@
// Query with a broken answer section
TEST_F(AuthSrvTest, shortAnswer) {
- createDataFromFile("shortanswer_fromWire");
+ createDataFromFile("shortanswer_fromWire.wire");
server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
EXPECT_TRUE(dnsserv.hasAnswer());
@@ -284,17 +281,25 @@
// Query with unsupported version of EDNS.
TEST_F(AuthSrvTest, ednsBadVers) {
- 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");
+ 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, but
+ // it will be added automatically at the render time.
// Note that the DNSSEC DO bit is cleared even if this bit in the query
// is set. This is a limitation of the current implementation.
headerCheck(*parse_message, default_qid, Rcode::BADVERS(), opcode.getCode(),
QR_FLAG, 1, 0, 0, 1);
- EXPECT_EQ(4096, parse_message->getUDPSize());
- EXPECT_FALSE(parse_message->isDNSSECSupported());
+ EXPECT_FALSE(parse_message->getEDNS()); // EDNS isn't added at this point
+
+ InputBuffer ib(response_obuffer->getData(), response_obuffer->getLength());
+ Message parsed(Message::PARSE);
+ parsed.fromWire(ib);
+ EXPECT_EQ(Rcode::BADVERS(), parsed.getRcode());
+ ConstEDNSPtr edns(parsed.getEDNS());
+ ASSERT_TRUE(edns);
+ EXPECT_FALSE(edns->getDNSSECAwareness());
}
TEST_F(AuthSrvTest, AXFROverUDP) {
@@ -318,7 +323,7 @@
// so we shouldn't have to respond.
server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
EXPECT_FALSE(dnsserv.hasAnswer());
- EXPECT_FALSE(xfrout.isConnected());
+ EXPECT_TRUE(xfrout.isConnected());
}
TEST_F(AuthSrvTest, AXFRConnectFail) {
@@ -331,8 +336,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 +346,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,7 +383,7 @@
TEST_F(AuthSrvTest, notify) {
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_TRUE(dnsserv.hasAnswer());
@@ -412,7 +415,7 @@
// 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());
+ request_message.setHeaderFlag(Message::HEADERFLAG_AA);
createRequestPacket(request_message, IPPROTO_UDP);
server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
EXPECT_TRUE(dnsserv.hasAnswer());
@@ -427,7 +430,8 @@
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);
createRequestPacket(request_message, IPPROTO_UDP);
@@ -443,7 +447,7 @@
// 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);
createRequestPacket(request_message, IPPROTO_UDP);
server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
EXPECT_TRUE(dnsserv.hasAnswer());
@@ -454,7 +458,7 @@
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);
createRequestPacket(request_message, IPPROTO_UDP);
server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
EXPECT_TRUE(dnsserv.hasAnswer());
@@ -476,7 +480,7 @@
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());
createRequestPacket(request_message, IPPROTO_UDP);
server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
@@ -490,7 +494,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 +508,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 +520,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 +531,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 +543,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,7 +570,7 @@
// query for existent data in the installed data source. The resulting
// response should have the AA flag on, and have an RR in each answer
// and authority section.
- createDataFromFile("examplequery_fromWire");
+ createDataFromFile("examplequery_fromWire.wire");
server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
@@ -580,7 +584,7 @@
// tool and the data source itself naively accept it). This will result
// in a SERVFAIL response, and the answer and authority sections should
// be empty.
- createDataFromFile("badExampleQuery_fromWire");
+ createDataFromFile("badExampleQuery_fromWire.wire");
server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
@@ -595,10 +599,20 @@
updateConfig(&server, BADCONFIG_TESTDB, false);
// The original data source should still exist.
- createDataFromFile("examplequery_fromWire");
+ createDataFromFile("examplequery_fromWire.wire");
server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
QR_FLAG | AA_FLAG, 1, 1, 1, 0);
}
-}
+
+TEST_F(AuthSrvTest, cacheSlots) {
+ // simple check for the get/set operations
+ server.setCacheSlots(10); // 10 = arbitrary choice
+ EXPECT_EQ(10, server.getCacheSlots());
+
+ // 0 is a valid size
+ server.setCacheSlots(0);
+ EXPECT_EQ(00, server.getCacheSlots());
+}
+}
Modified: branches/trac327/src/bin/auth/tests/mockups.h
==============================================================================
--- branches/trac327/src/bin/auth/tests/mockups.h (original)
+++ branches/trac327/src/bin/auth/tests/mockups.h Wed Nov 10 10:44:42 2010
@@ -28,17 +28,16 @@
public:
MockSession() :
// by default we return a simple "success" message.
- msg_(Element::fromJSON("{\"result\": [0, \"SUCCESS\"]}")),
+ msg_(isc::data::Element::fromJSON("{\"result\": [0, \"SUCCESS\"]}")),
send_ok_(true), receive_ok_(true)
{}
- virtual void establish(const char* socket_file UNUSED_PARAM) {}
+ virtual void establish(const char*) {}
virtual void disconnect() {}
virtual int group_sendmsg(isc::data::ConstElementPtr msg, std::string group,
- std::string instance UNUSED_PARAM,
- std::string to UNUSED_PARAM)
+ std::string, std::string)
{
if (!send_ok_) {
isc_throw(isc::cc::SessionError,
@@ -50,10 +49,8 @@
return (0);
}
- virtual bool group_recvmsg(isc::data::ConstElementPtr& env UNUSED_PARAM,
- isc::data::ConstElementPtr& msg UNUSED_PARAM,
- bool nonblock UNUSED_PARAM,
- int seq UNUSED_PARAM)
+ virtual bool group_recvmsg(isc::data::ConstElementPtr&,
+ isc::data::ConstElementPtr& msg, bool, int)
{
if (!receive_ok_) {
isc_throw(isc::cc::SessionError,
@@ -64,15 +61,12 @@
return (true);
}
- virtual void subscribe(std::string group UNUSED_PARAM,
- std::string instance UNUSED_PARAM) {}
- virtual void unsubscribe(std::string group UNUSED_PARAM,
- std::string instance UNUSED_PARAM) {}
+ virtual void subscribe(std::string, std::string) {}
+ virtual void unsubscribe(std::string, std::string) {}
- virtual void startRead(boost::function<void()> callback UNUSED_PARAM) {}
+ virtual void startRead(boost::function<void()>) {}
- virtual int reply(isc::data::ConstElementPtr envelope UNUSED_PARAM,
- isc::data::ConstElementPtr newmsg UNUSED_PARAM) {
+ virtual int reply(isc::data::ConstElementPtr, isc::data::ConstElementPtr) {
return (-1);
}
@@ -80,7 +74,7 @@
return (false);
}
- virtual void setTimeout(size_t timeout UNUSED_PARAM) {};
+ virtual void setTimeout(size_t) {};
virtual size_t getTimeout() const { return 0; };
// The following methods extent AbstractSession to allow testing:
@@ -103,9 +97,7 @@
class MockServer : public asiolink::DNSServer {
public:
MockServer() : done_(false) {}
- void operator()(asio::error_code ec UNUSED_PARAM,
- size_t length UNUSED_PARAM)
- {}
+ void operator()(asio::error_code, size_t) {}
virtual void resume(const bool done) { done_ = done; }
virtual bool hasAnswer() { return (done_); }
virtual int value() { return (0); }
@@ -137,10 +129,7 @@
is_connected_ = false;
}
- virtual int sendXfroutRequestInfo(int tcp_sock UNUSED_PARAM,
- const void* msg_data UNUSED_PARAM,
- uint16_t msg_len UNUSED_PARAM)
- {
+ virtual int sendXfroutRequestInfo(int, const void*, uint16_t) {
if (!send_ok_) {
isc_throw(isc::xfr::XfroutError,
"xfrout connection send is disabled for test");
Modified: branches/trac327/src/bin/auth/tests/run_unittests.cc
==============================================================================
--- branches/trac327/src/bin/auth/tests/run_unittests.cc (original)
+++ branches/trac327/src/bin/auth/tests/run_unittests.cc Wed Nov 10 10:44:42 2010
@@ -19,10 +19,10 @@
#include <dns/tests/unittest_util.h>
int
-main(int argc, char* argv[])
-{
+main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
isc::UnitTestUtil::addDataPath(TEST_DATA_DIR);
+ isc::UnitTestUtil::addDataPath(TEST_DATA_BUILDDIR);
return (RUN_ALL_TESTS());
}
Modified: branches/trac327/src/bin/bind10/Makefile.am
==============================================================================
--- branches/trac327/src/bin/bind10/Makefile.am (original)
+++ branches/trac327/src/bin/bind10/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
sbin_SCRIPTS = bind10
CLEANFILES = bind10 bind10.pyc
Modified: branches/trac327/src/bin/bind10/bind10.8
==============================================================================
--- branches/trac327/src/bin/bind10/bind10.8 (original)
+++ branches/trac327/src/bin/bind10/bind10.8 Wed Nov 10 10:44:42 2010
@@ -1,13 +1,22 @@
'\" t
.\" Title: bind10
.\" Author: [see the "AUTHORS" section]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\" Generator: DocBook XSL Stylesheets v1.76.0 <http://docbook.sf.net/>
.\" Date: July 29, 2010
.\" Manual: BIND10
.\" Source: BIND10
.\" Language: English
.\"
.TH "BIND10" "8" "July 29, 2010" "BIND10" "BIND10"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -22,7 +31,7 @@
bind10 \- BIND 10 boss process
.SH "SYNOPSIS"
.HP \w'\fBbind10\fR\ 'u
-\fBbind10\fR [\fB\-a\ \fR\fB\fIaddress\fR\fR] [\fB\-m\ \fR\fB\fIfile\fR\fR] [\fB\-n\fR] [\fB\-p\ \fR\fB\fInumber\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-\-address\ \fR\fB\fIaddress\fR\fR] [\fB\-\-msgq\-socket\-file\ \fR\fB\fIfile\fR\fR] [\fB\-\-no\-cache\fR] [\fB\-\-port\ \fR\fB\fInumber\fR\fR] [\fB\-\-user\ \fR\fB\fIuser\fR\fR] [\fB\-\-verbose\fR]
+\fBbind10\fR [\fB\-a\ \fR\fB\fIaddress\fR\fR] [\fB\-m\ \fR\fB\fIfile\fR\fR] [\fB\-n\fR] [\fB\-p\ \fR\fB\fInumber\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-\-address\ \fR\fB\fIaddress\fR\fR] [\fB\-\-msgq\-socket\-file\ \fR\fB\fIfile\fR\fR] [\fB\-\-no\-cache\fR] [\fB\-\-port\ \fR\fB\fInumber\fR\fR] [\fB\-\-user\ \fR\fB\fIuser\fR\fR] [\fB\-\-pretty\-name\ \fR\fB\fIname\fR\fR] [\fB\-\-verbose\fR]
.SH "DESCRIPTION"
.PP
The
@@ -86,6 +95,15 @@
must be initially ran as the root user to use this option\&. The default is to run as the current user\&.
.RE
.PP
+\fB\-\-pretty\-name \fR\fB\fIname\fR\fR
+.RS 4
+The name this process should have in tools like
+\fBps\fR
+or
+\fBtop\fR\&. This is handy if you have multiple versions/installations of
+\fBbind10\fR\&.
+.RE
+.PP
\fB\-v\fR, \fB\-\-verbose\fR
.RS 4
Display more about what is going on for
@@ -101,6 +119,8 @@
\fBb10-cmdctl\fR(8),
\fBb10-msgq\fR(8),
\fBb10-xfrin\fR(8),
+\fBb10-xfrout\fR(8),
+\fBb10-zonemgr\fR(8),
BIND 10 Guide\&.
.SH "HISTORY"
.PP
Modified: branches/trac327/src/bin/bind10/bind10.py.in
==============================================================================
--- branches/trac327/src/bin/bind10/bind10.py.in (original)
+++ branches/trac327/src/bin/bind10/bind10.py.in Wed Nov 10 10:44:42 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,42 +182,17 @@
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."""
- def __init__(self, msgq_socket_file=None, dns_port=5300, address='',
+ def __init__(self, msgq_socket_file=None, dns_port=5300, address=None,
forward=None, nocache=False, verbose=False, setuid=None,
username=None):
"""Initialize the Boss of BIND. This is a singleton (only one
@@ -218,11 +208,11 @@
self.address = None
self.nocache = nocache
if address:
- self.address = IPAddr(address)
+ self.address = address
self.forward = None
self.recursive = False
if forward:
- self.forward = IPAddr(forward)
+ self.forward = forward
self.recursive = True
self.nocache = False
self.cc_session = None
@@ -443,6 +433,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 +473,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,13 +487,15 @@
def stop_all_processes(self):
"""Stop all processes."""
cmd = { "command": ['shutdown']}
- self.cc_session.group_sendmsg(cmd, 'Boss', 'Cmdctl')
- self.cc_session.group_sendmsg(cmd, "Boss", "ConfigManager")
- self.cc_session.group_sendmsg(cmd, "Boss", "Auth")
- self.cc_session.group_sendmsg(cmd, "Boss", "Recurse")
- 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, "Recurse", "Recurse")
+ self.cc_session.group_sendmsg(cmd, "Xfrout", "Xfrout")
+ self.cc_session.group_sendmsg(cmd, "Xfrin", "Xfrin")
+ self.cc_session.group_sendmsg(cmd, "Zonemgr", "Zonemgr")
+ self.cc_session.group_sendmsg(cmd, "Stats", "Stats")
def stop_process(self, process):
"""Stop the given process, friendly-like."""
@@ -498,7 +512,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 +621,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,29 +643,31 @@
def check_port(option, opt_str, value, parser):
"""Function to insure that the port we are passed is actually
a valid port number. Used by OptionParser() on startup."""
- if not re.match('^(6553[0-5]|655[0-2]\d|65[0-4]\d\d|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3}|0)$', value):
- raise OptionValueError("%s requires a port number (0-65535)" % opt_str)
- if (opt_str == '-m' or opt_str == '--msgq-port'):
- parser.values.msgq_port = value
- elif (opt_str == '-p' or opt_str == '--port'):
- parser.values.dns_port = value
- else:
- raise OptionValueError("Unknown option " + opt_str)
-
+ try:
+ if opt_str in ['-p', '--port']:
+ parser.values.auth_port = isc.net.parse.port_parse(value)
+ else:
+ raise OptionValueError("Unknown option " + opt_str)
+ except ValueError as e:
+ raise OptionValueError(str(e))
+
def check_addr(option, opt_str, value, parser):
"""Function to insure that the address we are passed is actually
a valid address. Used by OptionParser() on startup."""
try:
- IPAddr(value)
- except:
+ if opt_str in ['-a', '--address']:
+ parser.values.address = isc.net.parse.addr_parse(value)
+ if opt_str in ['-f', '--forward']:
+ parser.values.forward = isc.net.parse.addr_parse(value)
+ else:
+ raise OptionValueError("Unknown option " + opt_str)
+ except ValueError:
raise OptionValueError("%s requires a valid IPv4 or IPv6 address" % opt_str)
- if (opt_str == '-a' or opt_str == '--address'):
- parser.values.address = value
- elif (opt_str == '-f' or opt_str == '--forward'):
- parser.values.forward = value
- else:
- raise OptionValueError("Unknown option " + opt_str)
-
+
+def process_rename(option, opt_str, value, parser):
+ """Function that renames the process if it is requested by a option."""
+ isc.util.process.rename(value)
+
def main():
global options
global boss_of_bind
@@ -657,7 +675,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)")
@@ -669,13 +687,16 @@
help="UNIX domain socket file the b10-msgq daemon will use")
parser.add_option("-n", "--no-cache", action="store_true", dest="nocache",
default=False, help="disable hot-spot cache in authoritative DNS server")
- parser.add_option("-p", "--port", dest="dns_port", type="string",
- action="callback", callback=check_port, default="5300",
+ parser.add_option("-p", "--port", dest="dns_port", type="int",
+ action="callback", callback=check_port, default=5300,
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,11 +733,7 @@
# Announce startup.
if options.verbose:
- sys.stdout.write("BIND 10 %s\n" % __version__)
-
- # TODO: set process name, perhaps by:
- # http://code.google.com/p/procname/
- # http://github.com/lericson/procname/
+ sys.stdout.write("%s\n" % VERSION)
# Create wakeup pipe for signal handlers
wakeup_pipe = os.pipe()
@@ -729,8 +746,11 @@
signal.signal(signal.SIGINT, fatal_signal)
signal.signal(signal.SIGTERM, fatal_signal)
+ # Block SIGPIPE, as we don't want it to end this process
+ signal.signal(signal.SIGPIPE, signal.SIG_IGN)
+
# Go bob!
- boss_of_bind = BoB(options.msgq_socket_file, int(options.dns_port),
+ boss_of_bind = BoB(options.msgq_socket_file, options.dns_port,
options.address, options.forward, options.nocache,
options.verbose, setuid, username)
startup_result = boss_of_bind.startup()
@@ -738,6 +758,17 @@
sys.stderr.write("[bind10] Error on startup: %s\n" % startup_result)
sys.exit(1)
sys.stdout.write("[bind10] BIND 10 started\n")
+
+ # send "bind10.boot_time" to b10-stats
+ time.sleep(1) # wait a second
+ if options.verbose:
+ sys.stdout.write("[bind10] send \"bind10.boot_time\" to b10-stats\n")
+ cmd = isc.config.ccsession.create_command('set',
+ { "stats_data": {
+ 'bind10.boot_time': time.strftime('%Y-%m-%dT%H:%M:%SZ', _BASETIME)
+ }
+ })
+ boss_of_bind.cc_session.group_sendmsg(cmd, 'Stats')
# In our main loop, we check for dead processes or messages
# on the c-channel.
@@ -767,7 +798,12 @@
for fd in rlist + xlist:
if fd == ccs_fd:
- boss_of_bind.ccs.check_command()
+ try:
+ boss_of_bind.ccs.check_command()
+ except isc.cc.session.ProtocolError:
+ if options.verbose:
+ sys.stderr.write("[bind10] msgq channel disappeared.\n")
+ break
elif fd == wakeup_fd:
os.read(wakeup_fd, 32)
Modified: branches/trac327/src/bin/bind10/bind10.xml
==============================================================================
--- branches/trac327/src/bin/bind10/bind10.xml (original)
+++ branches/trac327/src/bin/bind10/bind10.xml Wed Nov 10 10:44:42 2010
@@ -56,6 +56,7 @@
<arg><option>--no-cache</option></arg>
<arg><option>--port <replaceable>number</replaceable></option></arg>
<arg><option>--user <replaceable>user</replaceable></option></arg>
+ <arg><option>--pretty-name <replaceable>name</replaceable></option></arg>
<arg><option>--verbose</option></arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -149,6 +150,17 @@
</varlistentry>
<varlistentry>
+ <term><option>--pretty-name <replaceable>name</replaceable></option></term>
+
+ <listitem>
+ <para>The name this process should have in tools like
+ <command>ps</command> or <command>top</command>. This
+ is handy if you have multiple versions/installations
+ of <command>bind10</command>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>-v</option>, <option>--verbose</option></term>
<listitem>
<para>Display more about what is going on for
@@ -188,6 +200,12 @@
</citerefentry>,
<citerefentry>
<refentrytitle>b10-xfrin</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>b10-xfrout</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>b10-zonemgr</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citetitle>BIND 10 Guide</citetitle>.
</para>
Modified: branches/trac327/src/bin/bind10/run_bind10.sh.in
==============================================================================
--- branches/trac327/src/bin/bind10/run_bind10.sh.in (original)
+++ branches/trac327/src/bin/bind10/run_bind10.sh.in Wed Nov 10 10:44:42 2010
@@ -20,7 +20,7 @@
BIND10_PATH=@abs_top_builddir@/src/bin/bind10
-PATH=@abs_top_builddir@/src/bin/msgq:@abs_top_builddir@/src/bin/auth:@abs_top_builddir@/src/bin/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/recurse:@abs_top_builddir@/src/bin/cfgmgr:@abs_top_builddir@/src/bin/cmdctl:@abs_top_builddir@/src/bin/stats:@abs_top_builddir@/src/bin/xfrin:@abs_top_builddir@/src/bin/xfrout:@abs_top_builddir@/src/bin/zonemgr:$PATH
export PATH
PYTHONPATH=@abs_top_builddir@/src/lib/python:@abs_top_builddir@/src/lib/dns/python/.libs:@abs_top_builddir@/src/lib/xfr/.libs
Modified: branches/trac327/src/bin/bind10/tests/args_test.py
==============================================================================
--- branches/trac327/src/bin/bind10/tests/args_test.py (original)
+++ branches/trac327/src/bin/bind10/tests/args_test.py Wed Nov 10 10:44:42 2010
@@ -130,5 +130,28 @@
x = bob.wait()
self.assertTrue(bob.wait() == 0)
+ def testPrettyName(self):
+ """Try the --pretty-name option."""
+ CMD_PRETTY_NAME = b'bob-name-test'
+ bob = subprocess.Popen(args=(BIND10_EXE, '--pretty-name',
+ CMD_PRETTY_NAME), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ started_ok = self._waitForString(bob, '[bind10] BIND 10 started')
+ self.assertTrue(started_ok)
+ ps = subprocess.Popen(args=("ps", "axo", "pid,comm"),
+ stdout=subprocess.PIPE)
+ s = ps.stdout.readline()
+ command = None
+ while True:
+ s = ps.stdout.readline()
+ if s == '': break
+ (pid,comm) = s.split(None, 1)
+ if int(pid) == bob.pid:
+ command = comm
+ break
+ self.assertEqual(command, CMD_PRETTY_NAME + b'\n')
+ time.sleep(0.1)
+ bob.terminate()
+ bob.wait()
+
if __name__ == '__main__':
unittest.main()
Modified: branches/trac327/src/bin/bind10/tests/bind10_test.py
==============================================================================
--- branches/trac327/src/bin/bind10/tests/bind10_test.py (original)
+++ branches/trac327/src/bin/bind10/tests/bind10_test.py Wed Nov 10 10:44:42 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: branches/trac327/src/bin/bindctl/Makefile.am
==============================================================================
--- branches/trac327/src/bin/bindctl/Makefile.am (original)
+++ branches/trac327/src/bin/bindctl/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
bin_SCRIPTS = bindctl
man_MANS = bindctl.1
Modified: branches/trac327/src/bin/bindctl/bindctl-source.py.in
==============================================================================
--- branches/trac327/src/bin/bindctl/bindctl-source.py.in (original)
+++ branches/trac327/src/bin/bindctl/bindctl-source.py.in Wed Nov 10 10:44:42 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: branches/trac327/src/bin/cfgmgr/Makefile.am
==============================================================================
--- branches/trac327/src/bin/cfgmgr/Makefile.am (original)
+++ branches/trac327/src/bin/cfgmgr/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
pkglibexecdir = $(libexecdir)/@PACKAGE@
Modified: branches/trac327/src/bin/cfgmgr/b10-cfgmgr.py.in
==============================================================================
--- branches/trac327/src/bin/cfgmgr/b10-cfgmgr.py.in (original)
+++ branches/trac327/src/bin/cfgmgr/b10-cfgmgr.py.in Wed Nov 10 10:44:42 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: branches/trac327/src/bin/cmdctl/Makefile.am
==============================================================================
--- branches/trac327/src/bin/cmdctl/Makefile.am (original)
+++ branches/trac327/src/bin/cmdctl/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
pkglibexecdir = $(libexecdir)/@PACKAGE@
@@ -15,7 +15,7 @@
b10_cmdctl_DATA = $(CMDCTL_CONFIGURATIONS)
b10_cmdctl_DATA += cmdctl.spec
-
+
EXTRA_DIST = $(CMDCTL_CONFIGURATIONS)
CLEANFILES= b10-cmdctl cmdctl.pyc cmdctl.spec
Modified: branches/trac327/src/bin/cmdctl/cmdctl.py.in
==============================================================================
--- branches/trac327/src/bin/cmdctl/cmdctl.py.in (original)
+++ branches/trac327/src/bin/cmdctl/cmdctl.py.in Wed Nov 10 10:44:42 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: branches/trac327/src/bin/host/Makefile.am
==============================================================================
--- branches/trac327/src/bin/host/Makefile.am (original)
+++ branches/trac327/src/bin/host/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,5 +1,6 @@
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
+AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CXXFLAGS = $(B10_CXXFLAGS)
Modified: branches/trac327/src/bin/host/host.cc
==============================================================================
--- branches/trac327/src/bin/host/host.cc (original)
+++ branches/trac327/src/bin/host/host.cc Wed Nov 10 10:44:42 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: branches/trac327/src/bin/loadzone/Makefile.am
==============================================================================
--- branches/trac327/src/bin/loadzone/Makefile.am (original)
+++ branches/trac327/src/bin/loadzone/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,5 +1,4 @@
-SUBDIRS = tests/correct
-SUBDIRS += tests/error
+SUBDIRS = . tests/correct tests/error
bin_SCRIPTS = b10-loadzone
CLEANFILES = b10-loadzone
Modified: branches/trac327/src/bin/loadzone/b10-loadzone.py.in
==============================================================================
--- branches/trac327/src/bin/loadzone/b10-loadzone.py.in (original)
+++ branches/trac327/src/bin/loadzone/b10-loadzone.py.in Wed Nov 10 10:44:42 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: branches/trac327/src/bin/loadzone/tests/error/error.known
==============================================================================
--- branches/trac327/src/bin/loadzone/tests/error/error.known (original)
+++ branches/trac327/src/bin/loadzone/tests/error/error.known Wed Nov 10 10:44:42 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: branches/trac327/src/bin/msgq/Makefile.am
==============================================================================
--- branches/trac327/src/bin/msgq/Makefile.am (original)
+++ branches/trac327/src/bin/msgq/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
pkglibexecdir = $(libexecdir)/@PACKAGE@
Modified: branches/trac327/src/bin/msgq/msgq.py.in
==============================================================================
--- branches/trac327/src/bin/msgq/msgq.py.in (original)
+++ branches/trac327/src/bin/msgq/msgq.py.in Wed Nov 10 10:44:42 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: branches/trac327/src/bin/msgq/tests/Makefile.am
==============================================================================
--- branches/trac327/src/bin/msgq/tests/Makefile.am (original)
+++ branches/trac327/src/bin/msgq/tests/Makefile.am Wed Nov 10 10:44:42 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: branches/trac327/src/bin/msgq/tests/msgq_test.py
==============================================================================
--- branches/trac327/src/bin/msgq/tests/msgq_test.py (original)
+++ branches/trac327/src/bin/msgq/tests/msgq_test.py Wed Nov 10 10:44:42 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: branches/trac327/src/bin/recurse/recursor.cc
==============================================================================
--- branches/trac327/src/bin/recurse/recursor.cc (original)
+++ branches/trac327/src/bin/recurse/recursor.cc Wed Nov 10 10:44:42 2010
@@ -34,6 +34,8 @@
#include <exceptions/exceptions.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <dns/buffer.h>
#include <dns/exceptions.h>
#include <dns/name.h>
@@ -132,14 +134,15 @@
class SectionInserter {
public:
- SectionInserter(MessagePtr message, const Section& sect, bool sign) :
+ SectionInserter(MessagePtr message, const Message::Section sect,
+ bool sign) :
message_(message), section_(sect), sign_(sign)
{}
void operator()(const RRsetPtr rrset) {
message_->addRRset(section_, rrset, true);
}
MessagePtr message_;
- const Section& section_;
+ const Message::Section section_;
bool sign_;
};
@@ -151,8 +154,8 @@
// XXX: with the current implementation, it's not easy to set EDNS0
// depending on whether the query had it. So we'll simply omit it.
const qid_t qid = message->getQid();
- const bool rd = message->getHeaderFlag(MessageFlag::RD());
- const bool cd = message->getHeaderFlag(MessageFlag::CD());
+ const bool rd = message->getHeaderFlag(Message::HEADERFLAG_RD);
+ const bool cd = message->getHeaderFlag(Message::HEADERFLAG_CD);
const Opcode& opcode = message->getOpcode();
vector<QuestionPtr> questions;
@@ -165,13 +168,12 @@
message->clear(Message::RENDER);
message->setQid(qid);
message->setOpcode(opcode);
- message->setHeaderFlag(MessageFlag::QR());
- message->setUDPSize(RecursorImpl::DEFAULT_LOCAL_UDPSIZE);
+ message->setHeaderFlag(Message::HEADERFLAG_QR);
if (rd) {
- message->setHeaderFlag(MessageFlag::RD());
+ message->setHeaderFlag(Message::HEADERFLAG_RD);
}
if (cd) {
- message->setHeaderFlag(MessageFlag::CD());
+ message->setHeaderFlag(Message::HEADERFLAG_CD);
}
for_each(questions.begin(), questions.end(), QuestionInserter(message));
message->setRcode(rcode);
@@ -213,8 +215,8 @@
OutputBufferPtr buffer) const
{
const qid_t qid = message->getQid();
- const bool rd = message->getHeaderFlag(MessageFlag::RD());
- const bool cd = message->getHeaderFlag(MessageFlag::CD());
+ const bool rd = message->getHeaderFlag(Message::HEADERFLAG_RD);
+ const bool cd = message->getHeaderFlag(Message::HEADERFLAG_CD);
const Opcode& opcode = message->getOpcode();
const Rcode& rcode = message->getRcode();
vector<QuestionPtr> questions;
@@ -224,15 +226,14 @@
message->setQid(qid);
message->setOpcode(opcode);
message->setRcode(rcode);
- message->setUDPSize(RecursorImpl::DEFAULT_LOCAL_UDPSIZE);
-
- message->setHeaderFlag(MessageFlag::QR());
- message->setHeaderFlag(MessageFlag::RA());
+
+ message->setHeaderFlag(Message::HEADERFLAG_QR);
+ message->setHeaderFlag(Message::HEADERFLAG_RA);
if (rd) {
- message->setHeaderFlag(MessageFlag::RD());
+ message->setHeaderFlag(Message::HEADERFLAG_RD);
}
if (cd) {
- message->setHeaderFlag(MessageFlag::CD());
+ message->setHeaderFlag(Message::HEADERFLAG_CD);
}
@@ -247,15 +248,18 @@
Message incoming(Message::PARSE);
InputBuffer ibuf(buffer->getData(), buffer->getLength());
incoming.fromWire(ibuf);
- for_each(incoming.beginSection(Section::ANSWER()),
- incoming.endSection(Section::ANSWER()),
- SectionInserter(message, Section::ANSWER(), true));
- for_each(incoming.beginSection(Section::ADDITIONAL()),
- incoming.endSection(Section::ADDITIONAL()),
- SectionInserter(message, Section::ADDITIONAL(), true));
- for_each(incoming.beginSection(Section::AUTHORITY()),
- incoming.endSection(Section::AUTHORITY()),
- SectionInserter(message, Section::AUTHORITY(), true));
+ for_each(incoming.beginSection(Message::SECTION_ANSWER),
+ incoming.endSection(Message::SECTION_ANSWER),
+ SectionInserter(message, Message::SECTION_ANSWER,
+ true));
+ for_each(incoming.beginSection(Message::SECTION_ADDITIONAL),
+ incoming.endSection(Message::SECTION_ADDITIONAL),
+ SectionInserter(message, Message::SECTION_ADDITIONAL,
+ true));
+ for_each(incoming.beginSection(Message::SECTION_AUTHORITY),
+ incoming.endSection(Message::SECTION_ADDITIONAL),
+ SectionInserter(message, Message::SECTION_AUTHORITY,
+ true));
} catch (const Exception& ex) {
// Incoming message couldn't be read, we just SERVFAIL
message->setRcode(Rcode::SERVFAIL());
@@ -268,7 +272,9 @@
MessageRenderer renderer(*buffer);
if (io_message.getSocket().getProtocol() == IPPROTO_UDP) {
- renderer.setLengthLimit(message->getUDPSize());
+ ConstEDNSPtr edns(message->getEDNS());
+ renderer.setLengthLimit(edns ? edns->getUDPSize() :
+ Message::DEFAULT_MAX_UDPSIZE);
} else {
renderer.setLengthLimit(65535);
}
@@ -292,7 +298,7 @@
class ConfigCheck : public SimpleCallback {
public:
ConfigCheck(Recursor* srv) : server_(srv) {}
- virtual void operator()(const IOMessage& io_message UNUSED_PARAM) const {
+ virtual void operator()(const IOMessage&) const {
if (server_->getConfigSession()->hasQueuedMsgs()) {
server_->getConfigSession()->checkCommand();
}
@@ -353,7 +359,7 @@
message->parseHeader(request_buffer);
// Ignore all responses.
- if (message->getHeaderFlag(MessageFlag::QR())) {
+ if (message->getHeaderFlag(Message::HEADERFLAG_QR)) {
if (impl_->verbose_mode_) {
cerr << "[b10-recurse] received unexpected response, ignoring"
<< endl;
@@ -407,7 +413,7 @@
}
makeErrorMessage(message, buffer, Rcode::NOTIMP(),
impl_->verbose_mode_);
- } else if (message->getRRCount(Section::QUESTION()) != 1) {
+ } else if (message->getRRCount(Message::SECTION_QUESTION) != 1) {
makeErrorMessage(message, buffer, Rcode::FORMERR(),
impl_->verbose_mode_);
} else {
@@ -441,13 +447,18 @@
RecursorImpl::processNormalQuery(const Question& question, MessagePtr message,
OutputBufferPtr buffer, DNSServer* server)
{
- const bool dnssec_ok = message->isDNSSECSupported();
+ ConstEDNSPtr edns(message->getEDNS());
+ const bool dnssec_ok = edns && edns->getDNSSECAwareness();
message->makeResponse();
- message->setHeaderFlag(MessageFlag::RA());
+ message->setHeaderFlag(Message::HEADERFLAG_RA);
message->setRcode(Rcode::NOERROR());
- message->setDNSSECSupported(dnssec_ok);
- message->setUDPSize(RecursorImpl::DEFAULT_LOCAL_UDPSIZE);
+ if (edns) {
+ EDNSPtr edns_response(new EDNS());
+ edns_response->setDNSSECAwareness(dnssec_ok);
+ edns_response->setUDPSize(RecursorImpl::DEFAULT_LOCAL_UDPSIZE);
+ message->setEDNS(edns_response);
+ }
rec_query_->sendQuery(question, buffer, server);
}
@@ -498,12 +509,9 @@
}
try {
// Parse forward_addresses
- // FIXME Once the config parser is fixed, remove the slashes. They
- // appear only on the default/startup value and shouldn't be here.
- // See ticket #384
- ConstElementPtr forwardAddressesE(config->get("forward_addresses/"));
+ ConstElementPtr forwardAddressesE(config->get("forward_addresses"));
vector<addr_t> forwardAddresses(parseAddresses(forwardAddressesE));
- ConstElementPtr listenAddressesE(config->get("listen_on/"));
+ ConstElementPtr listenAddressesE(config->get("listen_on"));
vector<addr_t> listenAddresses(parseAddresses(listenAddressesE));
// Everything OK, so commit the changes
// listenAddresses can fail to bind, so try them first
Modified: branches/trac327/src/bin/recurse/tests/Makefile.am
==============================================================================
--- branches/trac327/src/bin/recurse/tests/Makefile.am (original)
+++ branches/trac327/src/bin/recurse/tests/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,3 +1,5 @@
+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
@@ -34,13 +36,3 @@
endif
noinst_PROGRAMS = $(TESTS)
-
-EXTRA_DIST = testdata/iqueryresponse_fromWire
-EXTRA_DIST += testdata/multiquestion_fromWire
-EXTRA_DIST += testdata/queryBadEDNS_fromWire
-EXTRA_DIST += testdata/shortanswer_fromWire
-EXTRA_DIST += testdata/shortmessage_fromWire
-EXTRA_DIST += testdata/shortquestion_fromWire
-EXTRA_DIST += testdata/shortresponse_fromWire
-EXTRA_DIST += testdata/simplequery_fromWire
-EXTRA_DIST += testdata/simpleresponse_fromWire
Modified: branches/trac327/src/bin/recurse/tests/recursor_unittest.cc
==============================================================================
--- branches/trac327/src/bin/recurse/tests/recursor_unittest.cc (original)
+++ branches/trac327/src/bin/recurse/tests/recursor_unittest.cc Wed Nov 10 10:44:42 2010
@@ -20,6 +20,8 @@
#include <asiolink/asiolink.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <dns/buffer.h>
#include <dns/name.h>
#include <dns/message.h>
@@ -48,18 +50,6 @@
namespace {
const char* const DEFAULT_REMOTE_ADDRESS = "192.0.2.1";
const char* const TEST_PORT = "53535";
-
-class DummySocket : public IOSocket {
-private:
- DummySocket(const DummySocket& source);
- DummySocket& operator=(const DummySocket& source);
-public:
- DummySocket(const int protocol) : protocol_(protocol) {}
- virtual int getNative() const { return (-1); }
- virtual int getProtocol() const { return (protocol_); }
-private:
- const int protocol_;
-};
class RecursorTest : public ::testing::Test {
protected:
@@ -114,7 +104,8 @@
endpoint = IOEndpoint::create(protocol,
IOAddress(DEFAULT_REMOTE_ADDRESS), 5300);
UnitTestUtil::readWireData(datafile, data);
- io_sock = new DummySocket(protocol);
+ io_sock = (protocol == IPPROTO_UDP) ? &IOSocket::getDummyUDPSocket() :
+ &IOSocket::getDummyTCPSocket();
io_message = new IOMessage(&data[0], data.size(), *io_sock, *endpoint);
}
@@ -128,7 +119,8 @@
endpoint = IOEndpoint::create(protocol,
IOAddress(DEFAULT_REMOTE_ADDRESS), 5300);
- io_sock = new DummySocket(protocol);
+ io_sock = (protocol == IPPROTO_UDP) ? &IOSocket::getDummyUDPSocket() :
+ &IOSocket::getDummyTCPSocket();
io_message = new IOMessage(request_renderer.getData(),
request_renderer.getLength(),
*io_sock, *endpoint);
@@ -155,18 +147,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.
@@ -178,7 +177,7 @@
i == Opcode::NOTIFY().getCode()) {
continue;
}
- createDataFromFile("simplequery_fromWire");
+ createDataFromFile("simplequery_fromWire.wire");
data[2] = ((i << 3) & 0xff);
parse_message->clear(Message::PARSE);
@@ -201,7 +200,7 @@
// Multiple questions. Should result in FORMERR.
TEST_F(RecursorTest, multiQuestion) {
- createDataFromFile("multiquestion_fromWire");
+ createDataFromFile("multiquestion_fromWire.wire");
server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
@@ -231,7 +230,7 @@
// or malformed or could otherwise cause a protocol error.
TEST_F(RecursorTest, response) {
// A valid (although unusual) response
- createDataFromFile("simpleresponse_fromWire");
+ createDataFromFile("simpleresponse_fromWire.wire");
server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
EXPECT_FALSE(dnsserv.hasAnswer());
@@ -242,7 +241,7 @@
EXPECT_FALSE(dnsserv.hasAnswer());
// A response to iquery. must be dropped rather than returning NOTIMP.
- createDataFromFile("iqueryresponse_fromWire");
+ createDataFromFile("iqueryresponse_fromWire.wire");
server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
EXPECT_FALSE(dnsserv.hasAnswer());
}
@@ -260,7 +259,7 @@
// Query with a broken answer section
TEST_F(RecursorTest, shortAnswer) {
- createDataFromFile("shortanswer_fromWire");
+ createDataFromFile("shortanswer_fromWire.wire");
server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
EXPECT_TRUE(dnsserv.hasAnswer());
@@ -279,17 +278,25 @@
// Query with unsupported version of EDNS.
TEST_F(RecursorTest, ednsBadVers) {
- 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");
+ 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, but
+ // it will be added automatically at the render time.
// Note that the DNSSEC DO bit is cleared even if this bit in the query
// is set. This is a limitation of the current implementation.
headerCheck(*parse_message, default_qid, Rcode::BADVERS(), opcode.getCode(),
QR_FLAG, 1, 0, 0, 1);
- EXPECT_EQ(4096, parse_message->getUDPSize());
- EXPECT_FALSE(parse_message->isDNSSECSupported());
+ EXPECT_FALSE(parse_message->getEDNS()); // EDNS isn't added at this point
+
+ InputBuffer ib(response_obuffer->getData(), response_obuffer->getLength());
+ Message parsed(Message::PARSE);
+ parsed.fromWire(ib);
+ EXPECT_EQ(Rcode::BADVERS(), parsed.getRcode());
+ ConstEDNSPtr edns(parsed.getEDNS());
+ ASSERT_TRUE(edns);
+ EXPECT_FALSE(edns->getDNSSECAwareness());
}
TEST_F(RecursorTest, AXFROverUDP) {
@@ -319,9 +326,10 @@
// Notify should always return NOTAUTH
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.setHeaderFlag(MessageFlag::AA());
+ request_message.setHeaderFlag(Message::HEADERFLAG_AA);
createRequestPacket(request_message, IPPROTO_UDP);
server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
EXPECT_TRUE(dnsserv.hasAnswer());
@@ -369,7 +377,7 @@
TEST_F(RecursorConfig, forwardAddressConfig) {
// Try putting there some address
ElementPtr config(Element::fromJSON("{"
- "\"forward_addresses/\": ["
+ "\"forward_addresses\": ["
" {"
" \"address\": \"192.0.2.1\","
" \"port\": 53"
@@ -385,7 +393,7 @@
// And then remove all addresses
config = Element::fromJSON("{"
- "\"forward_addresses/\": null"
+ "\"forward_addresses\": null"
"}");
result = server.updateConfig(config);
EXPECT_EQ(result->toWire(), isc::config::createAnswer()->toWire());
@@ -402,23 +410,23 @@
TEST_F(RecursorConfig, invalidForwardAddresses) {
// Try torturing it with some invalid inputs
invalidTest("{"
- "\"forward_addresses/\": \"error\""
+ "\"forward_addresses\": \"error\""
"}");
invalidTest("{"
- "\"forward_addresses/\": [{}]"
+ "\"forward_addresses\": [{}]"
"}");
invalidTest("{"
- "\"forward_addresses/\": [{"
+ "\"forward_addresses\": [{"
" \"port\": 1.5,"
" \"address\": \"192.0.2.1\""
"}]}");
invalidTest("{"
- "\"forward_addresses/\": [{"
+ "\"forward_addresses\": [{"
" \"port\": -5,"
" \"address\": \"192.0.2.1\""
"}]}");
invalidTest("{"
- "\"forward_addresses/\": [{"
+ "\"forward_addresses\": [{"
" \"port\": 53,"
" \"address\": \"bad_address\""
"}]}");
@@ -448,7 +456,7 @@
TEST_F(RecursorConfig, DISABLED_listenAddressConfig) {
// Try putting there some address
ElementPtr config(Element::fromJSON("{"
- "\"listen_on/\": ["
+ "\"listen_on\": ["
" {"
" \"address\": \"127.0.0.1\","
" \"port\": 5300"
@@ -467,7 +475,7 @@
// it is impossible, since the sockets are not closed.
// Once #388 is solved, enable this test.
config = Element::fromJSON("{"
- "\"listen_on/\": ["
+ "\"listen_on\": ["
" {"
" \"address\": \"192.0.2.0\","
" \"port\": 5300"
@@ -484,23 +492,23 @@
TEST_F(RecursorConfig, invalidListenAddresses) {
// Try torturing it with some invalid inputs
invalidTest("{"
- "\"listen_on/\": \"error\""
+ "\"listen_on\": \"error\""
"}");
invalidTest("{"
- "\"listen_on/\": [{}]"
+ "\"listen_on\": [{}]"
"}");
invalidTest("{"
- "\"listen_on/\": [{"
+ "\"listen_on\": [{"
" \"port\": 1.5,"
" \"address\": \"192.0.2.1\""
"}]}");
invalidTest("{"
- "\"listen_on/\": [{"
+ "\"listen_on\": [{"
" \"port\": -5,"
" \"address\": \"192.0.2.1\""
"}]}");
invalidTest("{"
- "\"listen_on/\": [{"
+ "\"listen_on\": [{"
" \"port\": 53,"
" \"address\": \"bad_address\""
"}]}");
Modified: branches/trac327/src/bin/usermgr/b10-cmdctl-usermgr.py.in
==============================================================================
--- branches/trac327/src/bin/usermgr/b10-cmdctl-usermgr.py.in (original)
+++ branches/trac327/src/bin/usermgr/b10-cmdctl-usermgr.py.in Wed Nov 10 10:44:42 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: branches/trac327/src/bin/xfrin/Makefile.am
==============================================================================
--- branches/trac327/src/bin/xfrin/Makefile.am (original)
+++ branches/trac327/src/bin/xfrin/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
pkglibexecdir = $(libexecdir)/@PACKAGE@
@@ -7,10 +7,11 @@
b10_xfrindir = $(DESTDIR)$(pkgdatadir)
b10_xfrin_DATA = xfrin.spec
-CLEANFILES = b10-xfrin xfrin.pyc xfrin.spec
+CLEANFILES = b10-xfrin xfrin.pyc
man_MANS = b10-xfrin.8
EXTRA_DIST = $(man_MANS) b10-xfrin.xml
+EXTRA_DIST += xfrin.spec
if ENABLE_MAN
@@ -19,9 +20,6 @@
endif
-xfrin.spec: xfrin.spec.pre
- $(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" xfrin.spec.pre >$@
-
# TODO: does this need $$(DESTDIR) also?
# this is done here since configure.ac AC_OUTPUT doesn't expand exec_prefix
b10-xfrin: xfrin.py
Modified: branches/trac327/src/bin/xfrin/TODO
==============================================================================
--- branches/trac327/src/bin/xfrin/TODO (original)
+++ branches/trac327/src/bin/xfrin/TODO Wed Nov 10 10:44:42 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: branches/trac327/src/bin/xfrin/b10-xfrin.8
==============================================================================
--- branches/trac327/src/bin/xfrin/b10-xfrin.8 (original)
+++ branches/trac327/src/bin/xfrin/b10-xfrin.8 Wed Nov 10 10:44:42 2010
@@ -2,12 +2,12 @@
.\" Title: b10-xfrin
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: March 17, 2010
+.\" Date: September 8, 2010
.\" Manual: BIND10
.\" Source: BIND10
.\" Language: English
.\"
-.TH "B10\-XFRIN" "8" "March 17, 2010" "BIND10" "BIND10"
+.TH "B10\-XFRIN" "8" "September 8, 2010" "BIND10" "BIND10"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -47,7 +47,6 @@
.sp .5v
.RE
.PP
-
This daemon communicates with BIND 10 over a
\fBb10-msgq\fR(8)
C\-Channel connection\&. If this connection is not established,
@@ -60,24 +59,59 @@
\fBb10-cfgmgr\fR(8)\&.
.SH "CONFIGURATION AND COMMANDS"
.PP
-The configurable setting is
+The configurable settings are:
+.PP
+\fImaster_addr\fR
+The default is 127\&.0\&.0\&.1\&.
+.PP
+\fImaster_port\fR
+The default is 53\&.
+.PP
\fItransfers\-in\fR
-which defines the maximum number of inbound zone transfers that can run concurrently\&. The default is 10\&.
+defines the maximum number of inbound zone transfers that can run concurrently\&. The default is 10\&.
.PP
The configuration commands are:
+.PP
+
+\fBnotify\fR
+is sent by
+\fBb10-zonemgr\fR(8)
+when a DNS NOTIFY message is received to initiate a zone transfer\&.
+This is an internal command and not exposed to the administrator\&.
+.PP
+
+\fBrefresh\fR
+triggers the transfer in for a single zone\&. It is the same as
+\fBretransfer\fR
+except it checks the SOA serial first\&.
+This is an internal command and not exposed to the administrator\&.
+
+.PP
+
+\fBrefresh_from_zonemgr\fR
+is sent by
+\fBb10-zonemgr\fR(8)
+according to the SOA\'s REFRESH time to tell
+\fBb10\-xfrin\fR
+that the zone needs to do a zone refresh\&. This is an internal command and not exposed to the administrator\&.
+.PP
+
+\fBretransfer\fR
+triggers the transfer in for a single zone without checking the zone\'s serial number\&. It has the following arguments:
+\fIzone_name\fR
+to define the zone to request,
+\fIzone_class\fR
+to define the class (defaults to
+\(lqIN\(rq),
+\fImaster\fR
+to define the IP address of the authoritative server to transfer from, and
+\fIport\fR
+to define the port number on the authoritative server (defaults to 53)\&.
.PP
\fBshutdown\fR
stops all incoming zone transfers and exits
\fBb10\-xfrin\fR\&. (Note that the BIND 10 boss process will restart this service\&.)
-.PP
-
-\fBretransfer\fR
-triggers the transfer in for a single zone without checking the zone\'s serial number\&. It has the following arguments:
-\fIzone_name\fR
-to define the zone to request and
-\fImaster\fR
-to define the IP address of the authoritative server to transfer from\&.
.if n \{\
.sp
.\}
@@ -99,6 +133,7 @@
\fBb10-cfgmgr\fR(8),
\fBb10-msgq\fR(8),
+\fBb10-zonemgr\fR(8),
\fBbind10\fR(8),
BIND 10 Guide\&.
.SH "HISTORY"
Modified: branches/trac327/src/bin/xfrin/b10-xfrin.xml
==============================================================================
--- branches/trac327/src/bin/xfrin/b10-xfrin.xml (original)
+++ branches/trac327/src/bin/xfrin/b10-xfrin.xml Wed Nov 10 10:44:42 2010
@@ -21,7 +21,7 @@
<refentry>
<refentryinfo>
- <date>March 17, 2010</date>
+ <date>September 8, 2010</date>
</refentryinfo>
<refmeta>
@@ -68,7 +68,6 @@
</simpara></note>
<para>
-<!-- TODO: does it really use msgq? what for? -->
This daemon communicates with BIND 10 over a
<citerefentry><refentrytitle>b10-msgq</refentrytitle><manvolnum>8</manvolnum></citerefentry>
C-Channel connection. If this connection is not established,
@@ -85,39 +84,82 @@
<refsect1>
<title>CONFIGURATION AND COMMANDS</title>
<para>
- The configurable setting is <varname>transfers-in</varname>
- which defines the maximum number of inbound zone transfers
+ The configurable settings are:
+ </para>
+
+ <para><varname>master_addr</varname>
+<!-- TODO: how can there be a single setting for this? -->
+ The default is 127.0.0.1.
+ </para>
+
+ <para><varname>master_port</varname>
+<!-- TODO: what if custom is needed per zone? -->
+ The default is 53.
+ </para>
+
+ <para><varname>transfers-in</varname>
+ defines the maximum number of inbound zone transfers
that can run concurrently. The default is 10.
</para>
<!-- TODO: formating -->
-<!-- TODO: refresh is code but not in spec -->
-<!-- schedule immediate maintenance for a zone(check soa serial ) -->
<para>
The configuration commands are:
</para>
+
+ <para>
+ <command>notify</command> is sent by
+ <citerefentry><refentrytitle>b10-zonemgr</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ when a DNS NOTIFY message is received to initiate a zone
+ transfer.
+<!-- TODO: document that zonemgr or xfrin checks if it needs to or not -->
+ This is an internal command and not exposed to the administrator.
+<!-- not defined in spec -->
+ </para>
+
+ <para>
+ <command>refresh</command> triggers the transfer in for
+ a single zone.
+ It is the same as <command>retransfer</command> except it
+ checks the SOA serial first.
+<!-- TODO more detail -->
+ This is an internal command and not exposed to the administrator.
+<!-- not defined in spec -->
+<!-- TODO: refresh is code but not in spec, see trac ticket #328 -->
+ </para>
+
+ <para>
+ <command>refresh_from_zonemgr</command> is sent by
+ <citerefentry><refentrytitle>b10-zonemgr</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ according to the SOA's REFRESH time
+ to tell <command>b10-xfrin</command> that the zone needs to do
+ a zone refresh.
+ This is an internal command and not exposed to the administrator.
+<!-- not defined in spec -->
+ </para>
+
+ <para>
+ <command>retransfer</command> triggers the transfer in for
+ a single zone without checking the zone's serial number.
+ It has the following arguments: <varname>zone_name</varname>
+ to define the zone to request,
+ <varname>zone_class</varname> to define the class (defaults to
+ <quote>IN</quote>),
+ <varname>master</varname> to define the IP address of
+ the authoritative server to transfer from,
+ and <varname>port</varname> to define the port number on the
+ authoritative server (defaults to 53).
+<!-- TODO: note: not documenting db_file since that will be removed. -->
+ </para>
+<!-- TODO: later hostname for master? -->
+
<para>
<command>shutdown</command> stops all incoming zone transfers
and exits <command>b10-xfrin</command>. (Note that the BIND 10
boss process will restart this service.)
</para>
- <para>
- <command>retransfer</command> triggers the transfer in for
- a single zone without checking the zone's serial number.
- It has the following arguments: <varname>zone_name</varname>
- to define the zone to request and <varname>master</varname>
- to define the IP address of the authoritative server to
- transfer from.
- </para>
-<!-- TODO: later hostname for master? -->
-
<!-- TODO:
add a usage example of xfrin -->
-
-<!-- TODO:
-
-port (defaults to 53)
-db_file (defaults to zone.sqlite3) --> <!-- TODO: fix this -->
<!-- TODO:
@@ -182,6 +224,9 @@
<refentrytitle>b10-msgq</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
+ <refentrytitle>b10-zonemgr</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
<refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citetitle>BIND 10 Guide</citetitle>.
Modified: branches/trac327/src/bin/xfrin/tests/xfrin_test.py
==============================================================================
--- branches/trac327/src/bin/xfrin/tests/xfrin_test.py (original)
+++ branches/trac327/src/bin/xfrin/tests/xfrin_test.py Wed Nov 10 10:44:42 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: branches/trac327/src/bin/xfrin/xfrin.py.in
==============================================================================
--- branches/trac327/src/bin/xfrin/xfrin.py.in (original)
+++ branches/trac327/src/bin/xfrin/xfrin.py.in Wed Nov 10 10:44:42 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: branches/trac327/src/bin/xfrout/Makefile.am
==============================================================================
--- branches/trac327/src/bin/xfrout/Makefile.am (original)
+++ branches/trac327/src/bin/xfrout/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
pkglibexecdir = $(libexecdir)/@PACKAGE@
Modified: branches/trac327/src/bin/xfrout/TODO
==============================================================================
--- branches/trac327/src/bin/xfrout/TODO (original)
+++ branches/trac327/src/bin/xfrout/TODO Wed Nov 10 10:44:42 2010
@@ -1,1 +1,2 @@
-Add unittest code.
+Add unittest code.
+Be able to cancel the outgoing zone transfer, and also be able to disable outgoing zone transfer.
Modified: branches/trac327/src/bin/xfrout/b10-xfrout.8
==============================================================================
--- branches/trac327/src/bin/xfrout/b10-xfrout.8 (original)
+++ branches/trac327/src/bin/xfrout/b10-xfrout.8 Wed Nov 10 10:44:42 2010
@@ -2,12 +2,12 @@
.\" Title: b10-xfrout
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: April 20, 2010
+.\" Date: September 8, 2010
.\" Manual: BIND10
.\" Source: BIND10
.\" Language: English
.\"
-.TH "B10\-XFROUT" "8" "April 20, 2010" "BIND10" "BIND10"
+.TH "B10\-XFROUT" "8" "September 8, 2010" "BIND10" "BIND10"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -27,7 +27,7 @@
.PP
The
\fBb10\-xfrout\fR
-daemon provides the BIND 10 outgoing DNS zone transfer service\&. Normally it is started by the
+daemon provides the BIND 10 outgoing DNS zone transfer service\&. It is also used to send outgoing NOTIFY messages\&. Normally it is started by the
\fBbind10\fR(8)
boss process\&. When the
\fBb10\-auth\fR
@@ -67,13 +67,13 @@
The configurable settings are:
.PP
-\fItransfers\-out\fR
-defines the maximum number of outgoing zone transfers that can run concurrently\&. The default is 10\&.
-.PP
-
\fIdb_file\fR
defines the path to the SQLite3 data store file\&. The default is
/usr/local/var/bind10\-devel/zone\&.sqlite3\&.
+.PP
+
+\fItransfers_out\fR
+defines the maximum number of outgoing zone transfers that can run concurrently\&. The default is 10\&.
.if n \{\
.sp
.\}
@@ -91,25 +91,34 @@
.sp .5v
.RE
.PP
-The configuration command is:
+The configuration commands are:
.PP
\fBshutdown\fR
stops all outbound zone transfers and exits
\fBb10\-xfrout\fR\&. (Note that the BIND 10 boss process will restart this service\&.)
+.PP
+
+\fBzone_new_data_ready\fR
+is sent from
+\fBb10-xfrin\fR(8)
+to indicate that the zone transferred in successfully\&. This triggers
+\fBb10\-xfrout\fR
+to send NOTIFY message(s)\&. This is an internal command and not exposed to the administrator\&.
.SH "SEE ALSO"
.PP
\fBb10-auth\fR(8),
\fBb10-cfgmgr\fR(8),
\fBb10-msgq\fR(8),
+\fBb10-xfrin\fR(8),
\fBbind10\fR(8),
BIND 10 Guide\&.
.SH "HISTORY"
.PP
The
\fBb10\-xfrout\fR
-daemon was implemented in March 2010 by Zhang Likun of CNNIC for the ISC BIND 10 project\&.
+daemon was first implemented in March 2010 by Zhang Likun of CNNIC for the ISC BIND 10 project\&.
.SH "COPYRIGHT"
.br
Copyright \(co 2010 Internet Systems Consortium, Inc. ("ISC")
Modified: branches/trac327/src/bin/xfrout/b10-xfrout.xml
==============================================================================
--- branches/trac327/src/bin/xfrout/b10-xfrout.xml (original)
+++ branches/trac327/src/bin/xfrout/b10-xfrout.xml Wed Nov 10 10:44:42 2010
@@ -21,7 +21,7 @@
<refentry>
<refentryinfo>
- <date>April 20, 2010</date>
+ <date>September 8, 2010</date>
</refentryinfo>
<refmeta>
@@ -54,6 +54,7 @@
<title>DESCRIPTION</title>
<para>The <command>b10-xfrout</command> daemon provides the BIND 10
outgoing DNS zone transfer service.
+ It is also used to send outgoing NOTIFY messages.
Normally it is started by the
<citerefentry><refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum></citerefentry>
boss process.
@@ -97,12 +98,16 @@
defines the path to the SQLite3 data store file.
The default is
<filename>/usr/local/var/bind10-devel/zone.sqlite3</filename>.
+<!-- TODO: db_file will be removed -->
</para>
<para>
<varname>transfers_out</varname>
defines the maximum number of outgoing zone transfers
that can run concurrently. The default is 10.
</para>
+
+<!-- TODO: log configurations not documented yet in here. jreed
+ has some but waiting on decisions ... -->
<note><simpara>
This prototype version uses SQLite3 as its data source backend.
@@ -112,12 +117,22 @@
<!-- TODO: formating -->
<para>
- The configuration command is:
+ The configuration commands are:
</para>
<para>
<command>shutdown</command> stops all outbound zone transfers
and exits <command>b10-xfrout</command>. (Note that the BIND 10
boss process will restart this service.)
+ </para>
+
+ <para>
+ <command>zone_new_data_ready</command> is sent from
+ <citerefentry><refentrytitle>b10-xfrin</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ to indicate that the zone transferred in successfully.
+ This triggers <command>b10-xfrout</command> to send NOTIFY
+ message(s).
+ This is an internal command and not exposed to the administrator.
+<!-- not defined in spec -->
</para>
</refsect1>
@@ -161,6 +176,9 @@
<refentrytitle>b10-msgq</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
+ <refentrytitle>b10-xfrin</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
<refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citetitle>BIND 10 Guide</citetitle>.
@@ -170,8 +188,8 @@
<refsect1>
<title>HISTORY</title>
<para>
- The <command>b10-xfrout</command> daemon was implemented in March 2010
- by Zhang Likun of CNNIC for the ISC BIND 10 project.
+ The <command>b10-xfrout</command> daemon was first implemented
+ in March 2010 by Zhang Likun of CNNIC for the ISC BIND 10 project.
</para>
</refsect1>
</refentry><!--
Modified: branches/trac327/src/bin/xfrout/tests/xfrout_test.py
==============================================================================
--- branches/trac327/src/bin/xfrout/tests/xfrout_test.py (original)
+++ branches/trac327/src/bin/xfrout/tests/xfrout_test.py Wed Nov 10 10:44:42 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: branches/trac327/src/bin/xfrout/xfrout.py.in
==============================================================================
--- branches/trac327/src/bin/xfrout/xfrout.py.in (original)
+++ branches/trac327/src/bin/xfrout/xfrout.py.in Wed Nov 10 10:44:42 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: branches/trac327/src/bin/zonemgr/Makefile.am
==============================================================================
--- branches/trac327/src/bin/zonemgr/Makefile.am (original)
+++ branches/trac327/src/bin/zonemgr/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
pkglibexecdir = $(libexecdir)/@PACKAGE@
@@ -9,6 +9,16 @@
CLEANFILES = b10-zonemgr zonemgr.pyc zonemgr.spec
+man_MANS = b10-zonemgr.8
+EXTRA_DIST = $(man_MANS) b10-zonemgr.xml
+
+if ENABLE_MAN
+
+b10-zonemgr.8: b10-zonemgr.xml
+ xsltproc --novalid --xinclude --nonet -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $(srcdir)/b10-zonemgr.xml
+
+endif
+
zonemgr.spec: zonemgr.spec.pre
$(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" zonemgr.spec.pre >$@
Modified: branches/trac327/src/bin/zonemgr/TODO
==============================================================================
--- branches/trac327/src/bin/zonemgr/TODO (original)
+++ branches/trac327/src/bin/zonemgr/TODO Wed Nov 10 10:44:42 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: branches/trac327/src/bin/zonemgr/tests/Makefile.am
==============================================================================
--- branches/trac327/src/bin/zonemgr/tests/Makefile.am (original)
+++ branches/trac327/src/bin/zonemgr/tests/Makefile.am Wed Nov 10 10:44:42 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: branches/trac327/src/bin/zonemgr/tests/zonemgr_test.py
==============================================================================
--- branches/trac327/src/bin/zonemgr/tests/zonemgr_test.py (original)
+++ branches/trac327/src/bin/zonemgr/tests/zonemgr_test.py Wed Nov 10 10:44:42 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: branches/trac327/src/bin/zonemgr/zonemgr.py.in
==============================================================================
--- branches/trac327/src/bin/zonemgr/zonemgr.py.in (original)
+++ branches/trac327/src/bin/zonemgr/zonemgr.py.in Wed Nov 10 10:44:42 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: branches/trac327/src/bin/zonemgr/zonemgr.spec.pre.in
==============================================================================
--- branches/trac327/src/bin/zonemgr/zonemgr.spec.pre.in (original)
+++ branches/trac327/src/bin/zonemgr/zonemgr.spec.pre.in Wed Nov 10 10:44:42 2010
@@ -2,6 +2,30 @@
"module_spec": {
"module_name": "Zonemgr",
"config_data":[
+ {
+ "item_name": "lowerbound_refresh",
+ "item_type": "integer",
+ "item_optional": false,
+ "item_default": 10
+ },
+ {
+ "item_name": "lowerbound_retry",
+ "item_type": "integer",
+ "item_optional": false,
+ "item_default": 5
+ },
+ {
+ "item_name": "max_transfer_timeout",
+ "item_type": "integer",
+ "item_optional": false,
+ "item_default": 14400
+ },
+ {
+ "item_name": "jitter_scope",
+ "item_type": "real",
+ "item_optional": false,
+ "item_default": 0.25
+ }
],
"commands": [
{
Modified: branches/trac327/src/lib/asiolink/Makefile.am
==============================================================================
--- branches/trac327/src/lib/asiolink/Makefile.am (original)
+++ branches/trac327/src/lib/asiolink/Makefile.am Wed Nov 10 10:44:42 2010
@@ -12,7 +12,8 @@
# which would make the build fail with -Werror (our default setting).
lib_LTLIBRARIES = libasiolink.la
libasiolink_la_SOURCES = asiolink.cc asiolink.h
-libasiolink_la_SOURCES += iosocket.h iomessage.h
+libasiolink_la_SOURCES += iosocket.cc iosocket.h
+libasiolink_la_SOURCES += iomessage.h
libasiolink_la_SOURCES += ioaddress.cc ioaddress.h
libasiolink_la_SOURCES += ioendpoint.cc ioendpoint.h
libasiolink_la_SOURCES += udpdns.cc internal/udpdns.h
Modified: branches/trac327/src/lib/asiolink/asiolink.h
==============================================================================
--- branches/trac327/src/lib/asiolink/asiolink.h (original)
+++ branches/trac327/src/lib/asiolink/asiolink.h Wed Nov 10 10:44:42 2010
@@ -96,7 +96,7 @@
/// http://think-async.com/Asio/asio-1.3.1/doc/asio/reference/asio_handler_allocate.html
namespace asiolink {
-struct DNSServiceImpl;
+class DNSServiceImpl;
struct IOServiceImpl;
/// \brief An exception that is thrown if an error occurs within the IO
Modified: branches/trac327/src/lib/asiolink/internal/tcpdns.h
==============================================================================
--- branches/trac327/src/lib/asiolink/internal/tcpdns.h (original)
+++ branches/trac327/src/lib/asiolink/internal/tcpdns.h Wed Nov 10 10:44:42 2010
@@ -35,26 +35,49 @@
// API.
namespace asiolink {
-/// \brief A TCP-specific \c IOEndpoint object.
+/// \brief The \c TCPEndpoint class is a concrete derived class of
+/// \c IOEndpoint that represents an endpoint of a TCP connection.
+///
+/// In the current implementation, an object of this class is always
+/// instantiated within the wrapper routines. Applications are expected to
+/// get access to the object via the abstract base class, \c IOEndpoint.
+/// This design may be changed when we generalize the wrapper interface.
///
/// Note: this implementation is optimized for the case where this object
/// is created from an ASIO endpoint object in a receiving code path
-/// by avoiding the need to copy of the base endpoint. For TCP, it may
-/// not be a big deal, but when we receive UDP packets at a high rate,
-/// the copy overhead could be significant.
+/// by avoiding to make a copy of the base endpoint. For TCP it may not be
+/// a big deal, but when we receive UDP packets at a high rate, the copy
+/// overhead might be significant.
class TCPEndpoint : public IOEndpoint {
public:
+ ///
+ /// \name Constructors and Destructor
+ ///
+ //@{
+ /// \brief Constructor from a pair of address and port.
+ ///
+ /// \param address The IP address of the endpoint.
+ /// \param port The TCP port number of the endpoint.
TCPEndpoint(const IOAddress& address, const unsigned short port) :
asio_endpoint_placeholder_(
new asio::ip::tcp::endpoint(
asio::ip::address::from_string(address.toText()), port)),
asio_endpoint_(*asio_endpoint_placeholder_)
{}
+
+ /// \brief Constructor from an ASIO TCP endpoint.
+ ///
+ /// This constructor is designed to be an efficient wrapper for the
+ /// corresponding ASIO class, \c tcp::endpoint.
+ ///
+ /// \param asio_endpoint The ASIO representation of the TCP endpoint.
TCPEndpoint(const asio::ip::tcp::endpoint& asio_endpoint) :
asio_endpoint_placeholder_(NULL), asio_endpoint_(asio_endpoint)
{}
-
+
+ /// \brief The destructor.
~TCPEndpoint() { delete asio_endpoint_placeholder_; }
+ //@}
inline IOAddress getAddress() const {
return (asio_endpoint_.address());
@@ -83,12 +106,21 @@
const asio::ip::tcp::endpoint& asio_endpoint_;
};
-/// \brief A TCP-specific \c IOSocket object.
+/// \brief The \c TCPSocket class is a concrete derived class of
+/// \c IOSocket that represents a TCP socket.
+///
+/// In the current implementation, an object of this class is always
+/// instantiated within the wrapper routines. Applications are expected to
+/// get access to the object via the abstract base class, \c IOSocket.
+/// This design may be changed when we generalize the wrapper interface.
class TCPSocket : public IOSocket {
private:
TCPSocket(const TCPSocket& source);
TCPSocket& operator=(const TCPSocket& source);
public:
+ /// \brief Constructor from an ASIO TCP socket.
+ ///
+ /// \param socket The ASIO representation of the TCP socket.
TCPSocket(asio::ip::tcp::socket& socket) : socket_(socket) {}
inline int getNative() const { return (socket_.native()); }
Modified: branches/trac327/src/lib/asiolink/internal/udpdns.h
==============================================================================
--- branches/trac327/src/lib/asiolink/internal/udpdns.h (original)
+++ branches/trac327/src/lib/asiolink/internal/udpdns.h Wed Nov 10 10:44:42 2010
@@ -35,23 +35,40 @@
// API.
namespace asiolink {
-// Note: this implementation is optimized for the case where this object
-// is created from an ASIO endpoint object in a receiving code path
-// by avoiding to make a copy of the base endpoint. Otherwise, when we
-// receive UDP packets at a high rate, the copy overhead might be significant.
+/// \brief The \c UDPEndpoint class is a concrete derived class of
+/// \c IOEndpoint that represents an endpoint of a UDP packet.
+///
+/// Other notes about \c TCPEndpoint applies to this class, too.
class UDPEndpoint : public IOEndpoint {
public:
+ ///
+ /// \name Constructors and Destructor.
+ ///
+ //@{
+ /// \brief Constructor from a pair of address and port.
+ ///
+ /// \param address The IP address of the endpoint.
+ /// \param port The UDP port number of the endpoint.
UDPEndpoint(const IOAddress& address, const unsigned short port) :
asio_endpoint_placeholder_(
new asio::ip::udp::endpoint(asio::ip::address::from_string(address.toText()),
port)),
asio_endpoint_(*asio_endpoint_placeholder_)
{}
+
+ /// \brief Constructor from an ASIO UDP endpoint.
+ ///
+ /// This constructor is designed to be an efficient wrapper for the
+ /// corresponding ASIO class, \c udp::endpoint.
+ ///
+ /// \param asio_endpoint The ASIO representation of the UDP endpoint.
UDPEndpoint(const asio::ip::udp::endpoint& asio_endpoint) :
asio_endpoint_placeholder_(NULL), asio_endpoint_(asio_endpoint)
{}
-
+
+ /// \brief The destructor.
~UDPEndpoint() { delete asio_endpoint_placeholder_; }
+ //@}
inline IOAddress getAddress() const {
return (asio_endpoint_.address());
@@ -80,11 +97,18 @@
const asio::ip::udp::endpoint& asio_endpoint_;
};
+/// \brief The \c UDPSocket class is a concrete derived class of
+/// \c IOSocket that represents a UDP socket.
+///
+/// Other notes about \c TCPSocket applies to this class, too.
class UDPSocket : public IOSocket {
private:
UDPSocket(const UDPSocket& source);
UDPSocket& operator=(const UDPSocket& source);
public:
+ /// \brief Constructor from an ASIO UDP socket.
+ ///
+ /// \param socket The ASIO representation of the UDP socket.
UDPSocket(asio::ip::udp::socket& socket) : socket_(socket) {}
virtual int getNative() const { return (socket_.native()); }
Modified: branches/trac327/src/lib/asiolink/tests/asiolink_unittest.cc
==============================================================================
--- branches/trac327/src/lib/asiolink/tests/asiolink_unittest.cc (original)
+++ branches/trac327/src/lib/asiolink/tests/asiolink_unittest.cc Wed Nov 10 10:44:42 2010
@@ -31,6 +31,7 @@
#include <dns/message.h>
#include <asiolink/asiolink.h>
+#include <asiolink/iosocket.h>
#include <asiolink/internal/tcpdns.h>
#include <asiolink/internal/udpdns.h>
@@ -49,18 +50,6 @@
// for the tests below.
const uint8_t test_data[] = {0, 4, 1, 2, 3, 4};
-class DummySocket : public IOSocket {
-private:
- DummySocket(const DummySocket& source);
- DummySocket& operator=(const DummySocket& source);
-public:
- DummySocket(const int protocol) : protocol_(protocol) {}
- virtual int getNative() const { return (-1); }
- virtual int getProtocol() const { return (protocol_); }
-private:
- const int protocol_;
-};
-
TEST(IOAddressTest, fromText) {
IOAddress io_address_v4("192.0.2.1");
EXPECT_EQ("192.0.2.1", io_address_v4.toText());
@@ -128,10 +117,10 @@
}
TEST(IOSocketTest, dummySockets) {
- EXPECT_EQ(IPPROTO_UDP, DummySocket(IPPROTO_UDP).getProtocol());
- EXPECT_EQ(IPPROTO_TCP, DummySocket(IPPROTO_TCP).getProtocol());
- EXPECT_EQ(-1, DummySocket(IPPROTO_UDP).getNative());
- EXPECT_EQ(-1, DummySocket(IPPROTO_TCP).getNative());
+ EXPECT_EQ(IPPROTO_UDP, IOSocket::getDummyUDPSocket().getProtocol());
+ EXPECT_EQ(IPPROTO_TCP, IOSocket::getDummyTCPSocket().getProtocol());
+ EXPECT_EQ(-1, IOSocket::getDummyUDPSocket().getNative());
+ EXPECT_EQ(-1, IOSocket::getDummyTCPSocket().getNative());
}
TEST(IOServiceTest, badPort) {
Modified: branches/trac327/src/lib/asiolink/udpdns.cc
==============================================================================
--- branches/trac327/src/lib/asiolink/udpdns.cc (original)
+++ branches/trac327/src/lib/asiolink/udpdns.cc Wed Nov 10 10:44:42 2010
@@ -29,6 +29,8 @@
#include <dns/buffer.h>
#include <dns/message.h>
#include <dns/messagerenderer.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <asiolink.h>
#include <internal/coroutine.h>
@@ -202,7 +204,7 @@
msg.setQid(0);
msg.setOpcode(Opcode::QUERY());
msg.setRcode(Rcode::NOERROR());
- msg.setHeaderFlag(MessageFlag::RD());
+ msg.setHeaderFlag(Message::HEADERFLAG_RD);
msg.addQuestion(question_);
MessageRenderer renderer(*msgbuf_);
msg.toWire(renderer);
Modified: branches/trac327/src/lib/bench/Makefile.am
==============================================================================
--- branches/trac327/src/lib/bench/Makefile.am (original)
+++ branches/trac327/src/lib/bench/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,6 +1,7 @@
SUBDIRS = . tests example
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CXXFLAGS = $(B10_CXXFLAGS)
CLEANFILES = *.gcno *.gcda
Modified: branches/trac327/src/lib/bench/benchmark_util.cc
==============================================================================
--- branches/trac327/src/lib/bench/benchmark_util.cc (original)
+++ branches/trac327/src/lib/bench/benchmark_util.cc Wed Nov 10 10:44:42 2010
@@ -26,6 +26,8 @@
#include <dns/name.h>
#include <dns/message.h>
#include <dns/messagerenderer.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <dns/rrtype.h>
#include <dns/rrclass.h>
#include <dns/question.h>
Modified: branches/trac327/src/lib/bench/example/search_bench.cc
==============================================================================
--- branches/trac327/src/lib/bench/example/search_bench.cc (original)
+++ branches/trac327/src/lib/bench/example/search_bench.cc Wed Nov 10 10:44:42 2010
@@ -16,6 +16,7 @@
#include <unistd.h> // for getpid
+#include <cassert>
#include <cstdlib> // for rand
#include <algorithm>
#include <iostream>
@@ -42,9 +43,11 @@
vector<int>::const_iterator end_key = keys_.end();
for (iter = keys_.begin(); iter != end_key; ++iter) {
if (Sorted) {
- binary_search(data_.begin(), data_.end(), *iter);
+ // perform simple sanity check with assert() to ensure
+ // compiler optimization won't skip the search.
+ assert(binary_search(data_.begin(), data_.end(), *iter));
} else {
- find(data_.begin(), data_.end(), *iter);
+ assert(find(data_.begin(), data_.end(), *iter) != data_.end());
}
}
return (keys_.size());
@@ -63,7 +66,7 @@
vector<int>::const_iterator iter;
vector<int>::const_iterator end_key = keys_.end();
for (iter = keys_.begin(); iter != end_key; ++iter) {
- data_.find(*iter);
+ assert(data_.find(*iter) != data_.end());
}
return (keys_.size());
}
Modified: branches/trac327/src/lib/bench/tests/Makefile.am
==============================================================================
--- branches/trac327/src/lib/bench/tests/Makefile.am (original)
+++ branches/trac327/src/lib/bench/tests/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,4 +1,5 @@
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CPPFLAGS += -DTEST_DATA_DIR=\"$(srcdir)/testdata\"
AM_CXXFLAGS = $(B10_CXXFLAGS)
Modified: branches/trac327/src/lib/bench/tests/loadquery_unittest.cc
==============================================================================
--- branches/trac327/src/lib/bench/tests/loadquery_unittest.cc (original)
+++ branches/trac327/src/lib/bench/tests/loadquery_unittest.cc Wed Nov 10 10:44:42 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: branches/trac327/src/lib/cc/Makefile.am
==============================================================================
--- branches/trac327/src/lib/cc/Makefile.am (original)
+++ branches/trac327/src/lib/cc/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,15 +1,22 @@
SUBDIRS = . tests
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
AM_CXXFLAGS = $(B10_CXXFLAGS)
-# ASIO header files used in session.cc will trigger "unused-parameter"
-# error. Unfortunately there doesn't seem to be an easy way to selectively
+if USE_GXX
+# ASIO header files used in session.cc will trigger the "unused-parameter"
+# warning. Unfortunately there doesn't seem to be an easy way to selectively
# avoid the error. As a short term workaround we suppress this warning
# for the entire this module. See also src/bin/auth/Makefile.am.
-if USE_GXX
AM_CXXFLAGS += -Wno-unused-parameter
+endif
+if USE_CLANGPP
+# Likewise, ASIO header files will trigger various warnings with clang++.
+# Worse, there doesn't seem to be any option to disable one of the warnings
+# in any way, so we need to turn off -Werror.
+AM_CXXFLAGS += -Wno-error
endif
lib_LTLIBRARIES = libcc.la
Modified: branches/trac327/src/lib/cc/data.cc
==============================================================================
--- branches/trac327/src/lib/cc/data.cc (original)
+++ branches/trac327/src/lib/cc/data.cc Wed Nov 10 10:44:42 2010
@@ -62,84 +62,82 @@
// installed files we define the methods here.
//
bool
-Element::getValue(long int& t UNUSED_PARAM) {
- return (false);
-}
-
-bool
-Element::getValue(double& t UNUSED_PARAM) {
- return (false);
-}
-
-bool
-Element::getValue(bool& t UNUSED_PARAM) {
- return (false);
-}
-
-bool
-Element::getValue(std::string& t UNUSED_PARAM) {
- return (false);
-}
-
-bool
-Element::getValue(std::vector<ConstElementPtr>& t UNUSED_PARAM) {
- return (false);
-}
-
-bool
-Element::getValue(std::map<std::string, ConstElementPtr>& t UNUSED_PARAM) {
- return (false);
-}
-
-bool
-Element::setValue(const long int v UNUSED_PARAM) {
- return (false);
-}
-
-bool
-Element::setValue(const double v UNUSED_PARAM) {
- return (false);
-}
-
-bool
-Element::setValue(const bool t UNUSED_PARAM) {
- return (false);
-}
-
-bool
-Element::setValue(const std::string& v UNUSED_PARAM) {
- return (false);
-}
-
-bool
-Element::setValue(const std::vector<ConstElementPtr>& v UNUSED_PARAM) {
- return (false);
-}
-
-bool
-Element::setValue(const std::map<std::string,
- ConstElementPtr>& v UNUSED_PARAM)
-{
+Element::getValue(long int&) {
+ return (false);
+}
+
+bool
+Element::getValue(double&) {
+ return (false);
+}
+
+bool
+Element::getValue(bool&) {
+ return (false);
+}
+
+bool
+Element::getValue(std::string&) {
+ return (false);
+}
+
+bool
+Element::getValue(std::vector<ConstElementPtr>&) {
+ return (false);
+}
+
+bool
+Element::getValue(std::map<std::string, ConstElementPtr>&) {
+ return (false);
+}
+
+bool
+Element::setValue(const long int) {
+ return (false);
+}
+
+bool
+Element::setValue(const double) {
+ return (false);
+}
+
+bool
+Element::setValue(const bool) {
+ return (false);
+}
+
+bool
+Element::setValue(const std::string&) {
+ return (false);
+}
+
+bool
+Element::setValue(const std::vector<ConstElementPtr>&) {
+ return (false);
+}
+
+bool
+Element::setValue(const std::map<std::string, ConstElementPtr>&) {
return (false);
}
ConstElementPtr
-Element::get(const int i UNUSED_PARAM) const {
+Element::get(const int) const {
isc_throw(TypeError, "get(int) called on a non-list Element");
}
void
-Element::set(const size_t i UNUSED_PARAM, ConstElementPtr element UNUSED_PARAM) {
+Element::set(const size_t, ConstElementPtr) {
isc_throw(TypeError, "set(int, element) called on a non-list Element");
}
void
-Element::add(ConstElementPtr element UNUSED_PARAM) {
+Element::add(ConstElementPtr) {
isc_throw(TypeError, "add() called on a non-list Element");
}
void
-Element::remove(const int i UNUSED_PARAM) {
+Element::remove(const int) {
isc_throw(TypeError, "remove(int) called on a non-list Element");
}
@@ -149,42 +147,39 @@
}
ConstElementPtr
-Element::get(const std::string& name UNUSED_PARAM) const {
+Element::get(const std::string&) const {
isc_throw(TypeError, "get(string) called on a non-map Element");
}
void
-Element::set(const std::string& name UNUSED_PARAM,
- ConstElementPtr element UNUSED_PARAM)
-{
+Element::set(const std::string&, ConstElementPtr) {
isc_throw(TypeError, "set(name, element) called on a non-map Element");
}
void
-Element::remove(const std::string& name UNUSED_PARAM) {
+Element::remove(const std::string&) {
isc_throw(TypeError, "remove(string) called on a non-map Element");
}
bool
-Element::contains(const std::string& name UNUSED_PARAM) const {
+Element::contains(const std::string&) const {
isc_throw(TypeError, "contains(string) called on a non-map Element");
}
ConstElementPtr
-Element::find(const std::string& identifier UNUSED_PARAM) const {
+Element::find(const std::string&) const {
isc_throw(TypeError, "find(string) called on a non-map Element");
}
bool
-Element::find(const std::string& identifier UNUSED_PARAM,
- ConstElementPtr t UNUSED_PARAM) const
-{
+Element::find(const std::string&, ConstElementPtr) const {
return (false);
}
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 +422,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 +481,7 @@
}
std::string
-Element::typeToName(Element::types type)
-{
+Element::typeToName(Element::types type) {
switch (type) {
case Element::integer:
return (std::string("integer"));
@@ -538,14 +534,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;
@@ -721,7 +719,7 @@
}
ElementPtr
-Element::fromWire(std::stringstream& in, int length) {
+Element::fromWire(std::stringstream& in, int) {
//
// Check protocol version
//
@@ -892,7 +890,7 @@
isc_throw(TypeError, "merge arguments not MapElements");
}
- std::map<std::string, ConstElementPtr> m = other->mapValue();
+ const std::map<std::string, ConstElementPtr>& m = other->mapValue();
for (std::map<std::string, ConstElementPtr>::const_iterator it = m.begin();
it != m.end() ; ++it) {
if ((*it).second && (*it).second->getType() != Element::null) {
Modified: branches/trac327/src/lib/cc/tests/Makefile.am
==============================================================================
--- branches/trac327/src/lib/cc/tests/Makefile.am (original)
+++ branches/trac327/src/lib/cc/tests/Makefile.am Wed Nov 10 10:44:42 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: branches/trac327/src/lib/cc/tests/data_unittests.cc
==============================================================================
--- branches/trac327/src/lib/cc/tests/data_unittests.cc (original)
+++ branches/trac327/src/lib/cc/tests/data_unittests.cc Wed Nov 10 10:44:42 2010
@@ -247,7 +247,7 @@
EXPECT_EQ(b, true);
b = false;
EXPECT_TRUE(el->setValue(b));
- EXPECT_EQ(false, el->boolValue());
+ EXPECT_FALSE(el->boolValue());
el = Element::create("foo");
EXPECT_THROW(el->intValue(), TypeError);
Modified: branches/trac327/src/lib/cc/tests/run_unittests.cc
==============================================================================
--- branches/trac327/src/lib/cc/tests/run_unittests.cc (original)
+++ branches/trac327/src/lib/cc/tests/run_unittests.cc Wed Nov 10 10:44:42 2010
@@ -17,8 +17,7 @@
#include <gtest/gtest.h>
int
-main(int argc, char* argv[])
-{
+main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
return (RUN_ALL_TESTS());
}
Modified: branches/trac327/src/lib/cc/tests/session_unittests.cc
==============================================================================
--- branches/trac327/src/lib/cc/tests/session_unittests.cc (original)
+++ branches/trac327/src/lib/cc/tests/session_unittests.cc Wed Nov 10 10:44:42 2010
@@ -76,7 +76,7 @@
}
void
- acceptHandler(const asio::error_code& error UNUSED_PARAM) {
+ acceptHandler(const asio::error_code&) {
}
void
Modified: branches/trac327/src/lib/config/Makefile.am
==============================================================================
--- branches/trac327/src/lib/config/Makefile.am (original)
+++ branches/trac327/src/lib/config/Makefile.am Wed Nov 10 10:44:42 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: branches/trac327/src/lib/config/ccsession.cc
==============================================================================
--- branches/trac327/src/lib/config/ccsession.cc (original)
+++ branches/trac327/src/lib/config/ccsession.cc Wed Nov 10 10:44:42 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: branches/trac327/src/lib/config/ccsession.h
==============================================================================
--- branches/trac327/src/lib/config/ccsession.h (original)
+++ branches/trac327/src/lib/config/ccsession.h Wed Nov 10 10:44:42 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: branches/trac327/src/lib/config/config_data.h
==============================================================================
--- branches/trac327/src/lib/config/config_data.h (original)
+++ branches/trac327/src/lib/config/config_data.h Wed Nov 10 10:44:42 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: branches/trac327/src/lib/config/module_spec.cc
==============================================================================
--- branches/trac327/src/lib/config/module_spec.cc (original)
+++ branches/trac327/src/lib/config/module_spec.cc Wed Nov 10 10:44:42 2010
@@ -24,6 +24,7 @@
// todo: add more context to thrown ModuleSpecErrors?
+using namespace isc::data;
using namespace isc::config;
namespace {
Modified: branches/trac327/src/lib/config/module_spec.h
==============================================================================
--- branches/trac327/src/lib/config/module_spec.h (original)
+++ branches/trac327/src/lib/config/module_spec.h Wed Nov 10 10:44:42 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: branches/trac327/src/lib/config/tests/Makefile.am
==============================================================================
--- branches/trac327/src/lib/config/tests/Makefile.am (original)
+++ branches/trac327/src/lib/config/tests/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,10 +1,9 @@
+SUBDIRS = testdata .
+
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CXXFLAGS = $(B10_CXXFLAGS)
-# see src/lib/cc/Makefile.am for -Wno-unused-parameter
-if USE_GXX
-AM_CXXFLAGS += -Wno-unused-parameter
-endif
if USE_STATIC_LINK
AM_LDFLAGS = -static
@@ -23,13 +22,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: branches/trac327/src/lib/config/tests/ccsession_unittests.cc
==============================================================================
--- branches/trac327/src/lib/config/tests/ccsession_unittests.cc (original)
+++ branches/trac327/src/lib/config/tests/ccsession_unittests.cc Wed Nov 10 10:44:42 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;
@@ -189,7 +188,7 @@
}
ConstElementPtr my_command_handler(const std::string& command,
- ConstElementPtr arg UNUSED_PARAM)
+ ConstElementPtr arg)
{
if (command == "good_command") {
return (createAnswer());
@@ -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: branches/trac327/src/lib/config/tests/data_def_unittests_config.h.in
==============================================================================
--- branches/trac327/src/lib/config/tests/data_def_unittests_config.h.in (original)
+++ branches/trac327/src/lib/config/tests/data_def_unittests_config.h.in Wed Nov 10 10:44:42 2010
@@ -12,4 +12,4 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#define TEST_DATA_PATH "@abs_srcdir@/../testdata"
+#define TEST_DATA_PATH "@abs_srcdir@/testdata"
Modified: branches/trac327/src/lib/config/tests/fake_session.cc
==============================================================================
--- branches/trac327/src/lib/config/tests/fake_session.cc (original)
+++ branches/trac327/src/lib/config/tests/fake_session.cc Wed Nov 10 10:44:42 2010
@@ -87,17 +87,15 @@
}
void
-FakeSession::startRead(boost::function<void()> read_callback UNUSED_PARAM) {
-}
-
-void
-FakeSession::establish(const char* socket_file) {
-}
-
-bool
-FakeSession::recvmsg(ConstElementPtr& msg, bool nonblock UNUSED_PARAM,
- int seq UNUSED_PARAM)
-{
+FakeSession::startRead(boost::function<void()>) {
+}
+
+void
+FakeSession::establish(const char*) {
+}
+
+bool
+FakeSession::recvmsg(ConstElementPtr& msg, bool, int) {
//cout << "[XX] client asks for message " << endl;
if (messages_ &&
messages_->getType() == Element::list &&
@@ -111,10 +109,7 @@
}
bool
-FakeSession::recvmsg(ConstElementPtr& env, ConstElementPtr& msg,
- bool nonblock UNUSED_PARAM,
- int seq UNUSED_PARAM)
-{
+FakeSession::recvmsg(ConstElementPtr& env, ConstElementPtr& msg, bool, int) {
//cout << "[XX] client asks for message and env" << endl;
env = ElementPtr();
if (messages_ &&
@@ -172,7 +167,7 @@
int
FakeSession::group_sendmsg(ConstElementPtr msg, std::string group,
- std::string to, std::string instance UNUSED_PARAM)
+ std::string to, std::string)
{
//cout << "[XX] client sends message: " << msg << endl;
//cout << "[XX] to: " << group << " . " << instance << "." << to << endl;
Modified: branches/trac327/src/lib/config/tests/fake_session.h
==============================================================================
--- branches/trac327/src/lib/config/tests/fake_session.h (original)
+++ branches/trac327/src/lib/config/tests/fake_session.h Wed Nov 10 10:44:42 2010
@@ -63,7 +63,7 @@
virtual int reply(isc::data::ConstElementPtr envelope,
isc::data::ConstElementPtr newmsg);
virtual bool hasQueuedMsgs() const;
- virtual void setTimeout(size_t milliseconds) {}
+ virtual void setTimeout(size_t) {}
virtual size_t getTimeout() const { return (0); }
isc::data::ConstElementPtr getFirstMessage(std::string& group,
std::string& to) const;
Modified: branches/trac327/src/lib/config/tests/module_spec_unittests.cc
==============================================================================
--- branches/trac327/src/lib/config/tests/module_spec_unittests.cc (original)
+++ branches/trac327/src/lib/config/tests/module_spec_unittests.cc Wed Nov 10 10:44:42 2010
@@ -105,8 +105,7 @@
"badname is not a valid type name");
}
-TEST(ModuleSpec, SpecfileConfigData)
-{
+TEST(ModuleSpec, SpecfileConfigData) {
module_spec_error("spec7.spec",
"module_name missing in { }");
module_spec_error("spec8.spec",
@@ -117,8 +116,7 @@
"commands is not a list of elements");
}
-TEST(ModuleSpec, SpecfileCommands)
-{
+TEST(ModuleSpec, SpecfileCommands) {
module_spec_error("spec17.spec",
"command_name missing in { \"command_args\": [ { \"item_default\": \"\", \"item_name\": \"message\", \"item_optional\": false, \"item_type\": \"string\" } ], \"command_description\": \"Print the given message to stdout\" }");
module_spec_error("spec18.spec",
Modified: branches/trac327/src/lib/config/tests/run_unittests.cc
==============================================================================
--- branches/trac327/src/lib/config/tests/run_unittests.cc (original)
+++ branches/trac327/src/lib/config/tests/run_unittests.cc Wed Nov 10 10:44:42 2010
@@ -17,8 +17,7 @@
#include <gtest/gtest.h>
int
-main(int argc, char* argv[])
-{
+main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
return (RUN_ALL_TESTS());
}
Modified: branches/trac327/src/lib/datasrc/Makefile.am
==============================================================================
--- branches/trac327/src/lib/datasrc/Makefile.am (original)
+++ branches/trac327/src/lib/datasrc/Makefile.am Wed Nov 10 10:44:42 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: branches/trac327/src/lib/datasrc/data_source.cc
==============================================================================
--- branches/trac327/src/lib/datasrc/data_source.cc (original)
+++ branches/trac327/src/lib/datasrc/data_source.cc Wed Nov 10 10:44:42 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);
}
}
}
@@ -1237,72 +1247,65 @@
return (encodeBase32Hex(vector<uint8_t>(digest, digest + SHA1_HASHSIZE)));
}
-//
-// The following methods are effectively empty, and their parameters are
-// unused. To silence compilers that warn unused function parameters,
-// we specify a (compiler dependent) special keyword when available.
-// It's defined in config.h, and to avoid including this header file from
-// installed files we define the methods here.
-//
DataSrc::Result
-DataSrc::init(isc::data::ConstElementPtr config UNUSED_PARAM) {
+DataSrc::init(isc::data::ConstElementPtr) {
return (NOT_IMPLEMENTED);
}
DataSrc::Result
-MetaDataSrc::findRRset(const isc::dns::Name& qname UNUSED_PARAM,
- const isc::dns::RRClass& qclass UNUSED_PARAM,
- const isc::dns::RRType& qtype UNUSED_PARAM,
- isc::dns::RRsetList& target UNUSED_PARAM,
- uint32_t& flags UNUSED_PARAM,
- const isc::dns::Name* zonename UNUSED_PARAM) const
+MetaDataSrc::findRRset(const isc::dns::Name&,
+ const isc::dns::RRClass&,
+ const isc::dns::RRType&,
+ isc::dns::RRsetList&,
+ uint32_t&,
+ const isc::dns::Name*) const
{
return (NOT_IMPLEMENTED);
}
DataSrc::Result
-MetaDataSrc::findExactRRset(const isc::dns::Name& qname UNUSED_PARAM,
- const isc::dns::RRClass& qclass UNUSED_PARAM,
- const isc::dns::RRType& qtype UNUSED_PARAM,
- isc::dns::RRsetList& target UNUSED_PARAM,
- uint32_t& flags UNUSED_PARAM,
- const isc::dns::Name* zonename UNUSED_PARAM) const
+MetaDataSrc::findExactRRset(const isc::dns::Name&,
+ const isc::dns::RRClass&,
+ const isc::dns::RRType&,
+ isc::dns::RRsetList&,
+ uint32_t&,
+ const isc::dns::Name*) const
{
return (NOT_IMPLEMENTED);
}
DataSrc::Result
-MetaDataSrc::findAddrs(const isc::dns::Name& qname UNUSED_PARAM,
- const isc::dns::RRClass& qclass UNUSED_PARAM,
- isc::dns::RRsetList& target UNUSED_PARAM,
- uint32_t& flags UNUSED_PARAM,
- const isc::dns::Name* zonename UNUSED_PARAM) const
+MetaDataSrc::findAddrs(const isc::dns::Name&,
+ const isc::dns::RRClass&,
+ isc::dns::RRsetList&,
+ uint32_t&,
+ const isc::dns::Name*) const
{
return (NOT_IMPLEMENTED);
}
DataSrc::Result
-MetaDataSrc::findReferral(const isc::dns::Name& qname UNUSED_PARAM,
- const isc::dns::RRClass& qclass UNUSED_PARAM,
- isc::dns::RRsetList& target UNUSED_PARAM,
- uint32_t& flags UNUSED_PARAM,
- const isc::dns::Name* zonename UNUSED_PARAM) const
+MetaDataSrc::findReferral(const isc::dns::Name&,
+ const isc::dns::RRClass&,
+ isc::dns::RRsetList&,
+ uint32_t&,
+ const isc::dns::Name*) const
{
return (NOT_IMPLEMENTED);
}
DataSrc::Result
-MetaDataSrc::findPreviousName(const isc::dns::Name& qname UNUSED_PARAM,
- isc::dns::Name& target UNUSED_PARAM,
- const isc::dns::Name* zonename UNUSED_PARAM) const
+MetaDataSrc::findPreviousName(const isc::dns::Name&,
+ isc::dns::Name&,
+ const isc::dns::Name*) const
{
return (NOT_IMPLEMENTED);
}
DataSrc::Result
-MetaDataSrc::findCoveringNSEC3(const isc::dns::Name& zonename UNUSED_PARAM,
- std::string& hash UNUSED_PARAM,
- isc::dns::RRsetList& target UNUSED_PARAM) const
+MetaDataSrc::findCoveringNSEC3(const isc::dns::Name&,
+ std::string&,
+ isc::dns::RRsetList&) const
{
return (NOT_IMPLEMENTED);
}
Modified: branches/trac327/src/lib/datasrc/query.cc
==============================================================================
--- branches/trac327/src/lib/datasrc/query.cc (original)
+++ branches/trac327/src/lib/datasrc/query.cc Wed Nov 10 10:44:42 2010
@@ -29,27 +29,31 @@
namespace datasrc {
QueryTask::QueryTask(const Query& qry, const isc::dns::Name& n,
- const isc::dns::RRType& t, const isc::dns::Section& sect) :
+ const isc::dns::RRType& t,
+ const isc::dns::Message::Section sect) :
q(qry), qname(n), qclass(qry.qclass()), qtype(t), section(sect),
op(AUTH_QUERY), state(GETANSWER), flags(0)
{}
QueryTask::QueryTask(const Query& qry, const isc::dns::Name& n,
- const isc::dns::RRType& t, const isc::dns::Section& sect,
+ const isc::dns::RRType& t,
+ const isc::dns::Message::Section sect,
const Op o) :
q(qry), qname(n), qclass(qry.qclass()), qtype(t), section(sect), op(o),
state(GETANSWER), flags(0)
{}
QueryTask::QueryTask(const Query& qry, const isc::dns::Name& n,
- const isc::dns::RRType& t, const isc::dns::Section& sect,
+ const isc::dns::RRType& t,
+ const isc::dns::Message::Section sect,
const State st) :
q(qry), qname(n), qclass(qry.qclass()), qtype(t), section(sect),
op(AUTH_QUERY), state(st), flags(0)
{}
QueryTask::QueryTask(const Query& qry, const isc::dns::Name& n,
- const isc::dns::RRType& t, const isc::dns::Section& sect,
+ const isc::dns::RRType& t,
+ const isc::dns::Message::Section sect,
const Op o, const State st) :
q(qry), qname(n), qclass(qry.qclass()), qtype(t), section(sect), op(o),
state(st), flags(0)
@@ -58,7 +62,7 @@
QueryTask::QueryTask(const Query& qry, const isc::dns::Name& n,
const isc::dns::RRType& t, const Op o) :
q(qry), qname(n), qclass(qry.qclass()), qtype(t),
- section(Section::ANSWER()), op(o), state(GETANSWER), flags(0)
+ section(Message::SECTION_ANSWER), op(o), state(GETANSWER), flags(0)
{
if (op != SIMPLE_QUERY) {
isc_throw(Unexpected, "invalid constructor for this task operation");
@@ -68,7 +72,7 @@
// A referral query doesn't need to specify section, state, or type.
QueryTask::QueryTask(const Query& qry, const isc::dns::Name& n, const Op o) :
q(qry), qname(n), qclass(qry.qclass()), qtype(RRType::ANY()),
- section(Section::ANSWER()), op(o), state(GETANSWER), flags(0)
+ section(Message::SECTION_ANSWER), op(o), state(GETANSWER), flags(0)
{
if (op != REF_QUERY) {
isc_throw(Unexpected, "invalid constructor for this task operation");
@@ -76,7 +80,7 @@
}
QueryTask::QueryTask(const Query& qry, const isc::dns::Name& n,
- const isc::dns::Section& sect, const Op o,
+ const isc::dns::Message::Section sect, const Op o,
const State st) :
q(qry), qname(n), qclass(qry.qclass()), qtype(RRType::ANY()),
section(sect), op(o), state(st), flags(0)
@@ -93,7 +97,7 @@
cache_(&c), message_(&m), want_additional_(true), want_dnssec_(dnssec)
{
// Check message formatting
- if (message_->getRRCount(Section::QUESTION()) != 1) {
+ if (message_->getRRCount(Message::SECTION_QUESTION) != 1) {
isc_throw(Unexpected, "malformed message: too many questions");
}
@@ -105,7 +109,7 @@
restarts_ = 0;
querytasks_.push(QueryTaskPtr(new QueryTask(*this, *qname_, *qtype_,
- Section::ANSWER())));
+ Message::SECTION_ANSWER)));
}
Query::~Query() {}
Modified: branches/trac327/src/lib/datasrc/query.h
==============================================================================
--- branches/trac327/src/lib/datasrc/query.h (original)
+++ branches/trac327/src/lib/datasrc/query.h Wed Nov 10 10:44:42 2010
@@ -57,7 +57,7 @@
// The section of the reply into which the data should be
// written after it has been fetched from the data source.
- const isc::dns::Section section;
+ const isc::dns::Message::Section section;
// The op field indicates the operation to be carried out by
// this query task:
@@ -127,14 +127,18 @@
// Constructors
QueryTask(const Query& q, const isc::dns::Name& n,
- const isc::dns::RRType& t, const isc::dns::Section& sect);
- QueryTask(const Query& q, const isc::dns::Name& n,
- const isc::dns::RRType& t, const isc::dns::Section& sect, Op o);
- QueryTask(const Query& q, const isc::dns::Name& n,
- const isc::dns::RRType& t, const isc::dns::Section& sect,
+ const isc::dns::RRType& t,
+ const isc::dns::Message::Section sect);
+ QueryTask(const Query& q, const isc::dns::Name& n,
+ const isc::dns::RRType& t,
+ const isc::dns::Message::Section sect, Op o);
+ QueryTask(const Query& q, const isc::dns::Name& n,
+ const isc::dns::RRType& t,
+ const isc::dns::Message::Section sect,
const State st);
QueryTask(const Query& q, const isc::dns::Name& n,
- const isc::dns::RRType& t, const isc::dns::Section& sect,
+ const isc::dns::RRType& t,
+ const isc::dns::Message::Section sect,
Op o, State st);
// These are special constructors for particular query task types,
@@ -147,7 +151,7 @@
QueryTask(const Query& q, const isc::dns::Name& n, Op o);
// A glue (or noglue) query doesn't need to specify type.
QueryTask(const Query& q, const isc::dns::Name& n,
- const isc::dns::Section& sect, Op o, State st);
+ const isc::dns::Message::Section sect, Op o, State st);
~QueryTask();
};
Modified: branches/trac327/src/lib/datasrc/static_datasrc.cc
==============================================================================
--- branches/trac327/src/lib/datasrc/static_datasrc.cc (original)
+++ branches/trac327/src/lib/datasrc/static_datasrc.cc Wed Nov 10 10:44:42 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_;
}
@@ -237,18 +235,12 @@
}
DataSrc::Result
-StaticDataSrc::findPreviousName(const Name& qname UNUSED_PARAM,
- Name& target UNUSED_PARAM,
- const Name* zonename UNUSED_PARAM) const
-{
+StaticDataSrc::findPreviousName(const Name&, Name&, const Name*) const {
return (NOT_IMPLEMENTED);
}
DataSrc::Result
-StaticDataSrc::findCoveringNSEC3(const Name& zonename UNUSED_PARAM,
- string& hash UNUSED_PARAM,
- RRsetList& target UNUSED_PARAM) const
-{
+StaticDataSrc::findCoveringNSEC3(const Name&, string&, RRsetList&) const {
return (NOT_IMPLEMENTED);
}
@@ -260,7 +252,7 @@
// Static data source is "configuration less", so the \c config parameter
// is intentionally ignored.
DataSrc::Result
-StaticDataSrc::init(isc::data::ConstElementPtr config UNUSED_PARAM) {
+StaticDataSrc::init(isc::data::ConstElementPtr) {
return (init());
}
Modified: branches/trac327/src/lib/datasrc/tests/Makefile.am
==============================================================================
--- branches/trac327/src/lib/datasrc/tests/Makefile.am (original)
+++ branches/trac327/src/lib/datasrc/tests/Makefile.am Wed Nov 10 10:44:42 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: branches/trac327/src/lib/datasrc/tests/datasrc_unittest.cc
==============================================================================
--- branches/trac327/src/lib/datasrc/tests/datasrc_unittest.cc (original)
+++ branches/trac327/src/lib/datasrc/tests/datasrc_unittest.cc Wed Nov 10 10:44:42 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: branches/trac327/src/lib/datasrc/tests/query_unittest.cc
==============================================================================
--- branches/trac327/src/lib/datasrc/tests/query_unittest.cc (original)
+++ branches/trac327/src/lib/datasrc/tests/query_unittest.cc Wed Nov 10 10:44:42 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: branches/trac327/src/lib/datasrc/tests/run_unittests.cc
==============================================================================
--- branches/trac327/src/lib/datasrc/tests/run_unittests.cc (original)
+++ branches/trac327/src/lib/datasrc/tests/run_unittests.cc Wed Nov 10 10:44:42 2010
@@ -19,8 +19,7 @@
#include <dns/tests/unittest_util.h>
int
-main(int argc, char* argv[])
-{
+main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
isc::UnitTestUtil::addDataPath(TEST_DATA_DIR);
Modified: branches/trac327/src/lib/datasrc/tests/test_datasrc.cc
==============================================================================
--- branches/trac327/src/lib/datasrc/tests/test_datasrc.cc (original)
+++ branches/trac327/src/lib/datasrc/tests/test_datasrc.cc Wed Nov 10 10:44:42 2010
@@ -307,7 +307,7 @@
}
DataSrc::Result
-TestDataSrc::init(isc::data::ConstElementPtr config UNUSED_PARAM) {
+TestDataSrc::init(isc::data::ConstElementPtr) {
return (init());
}
@@ -623,10 +623,7 @@
}
DataSrc::Result
-TestDataSrc::findCoveringNSEC3(const Name& zonename UNUSED_PARAM,
- string& hash UNUSED_PARAM,
- RRsetList& target UNUSED_PARAM) const
-{
+TestDataSrc::findCoveringNSEC3(const Name&, string&, RRsetList&) const {
return (NOT_IMPLEMENTED);
}
Modified: branches/trac327/src/lib/dns/Makefile.am
==============================================================================
--- branches/trac327/src/lib/dns/Makefile.am (original)
+++ branches/trac327/src/lib/dns/Makefile.am Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/exceptions.cc
==============================================================================
--- branches/trac327/src/lib/dns/exceptions.cc (original)
+++ branches/trac327/src/lib/dns/exceptions.cc Wed Nov 10 10:44:42 2010
@@ -15,7 +15,7 @@
// $Id$
#include <dns/exceptions.h>
-#include <dns/message.h>
+#include <dns/rcode.h>
namespace isc {
namespace dns {
Modified: branches/trac327/src/lib/dns/gen-rdatacode.py.in
==============================================================================
--- branches/trac327/src/lib/dns/gen-rdatacode.py.in (original)
+++ branches/trac327/src/lib/dns/gen-rdatacode.py.in Wed Nov 10 10:44:42 2010
@@ -113,7 +113,7 @@
if re.match('\s+// BEGIN_COMMON_MEMBERS$', line):
content += '''
explicit ''' + type_utxt + '''(const std::string& type_str);
- explicit ''' + type_utxt + '''(InputBuffer& buffer, size_t rdata_len);
+ ''' + type_utxt + '''(InputBuffer& buffer, size_t rdata_len);
''' + type_utxt + '''(const ''' + type_utxt + '''& other);
virtual std::string toText() const;
virtual void toWire(OutputBuffer& buffer) const;
@@ -129,12 +129,13 @@
global rdatadef_mtime
global rdatahdr_mtime
+ if classdir_mtime < getmtime('@srcdir@/rdata'):
+ classdir_mtime = getmtime('@srcdir@/rdata')
+
for dir in list(os.listdir('@srcdir@/rdata')):
classdir = '@srcdir@/rdata' + os.sep + dir
m = re_typecode.match(dir)
if os.path.isdir(classdir) and (m != None or dir == 'generic'):
- if classdir_mtime < getmtime(classdir):
- classdir_mtime = getmtime(classdir)
if dir == 'generic':
class_txt = 'generic'
class_code = generic_code
@@ -219,8 +220,7 @@
codetxt = code2txt[code].upper()
declarationtxt += ' ' * 4 + 'static const RR' + cap_key + '& ' + codetxt + '();\n'
deftxt += '''inline const RR''' + cap_key + '''&
-RR''' + cap_key + '''::''' + codetxt + '''()
-{
+RR''' + cap_key + '''::''' + codetxt + '''() {
static RR''' + cap_key + ''' ''' + lower_key + '''(''' + code + ''');
return (''' + lower_key + ''');
}\n
@@ -284,9 +284,7 @@
generate_rdatadef('@builddir@/rdataclass.cc', rdatadef_mtime)
generate_rdatahdr('@builddir@/rdataclass.h', rdata_declarations,
rdatahdr_mtime)
- generate_typeclasscode('rrtype',
- max(rdatadef_mtime, rdatahdr_mtime),
- typecode2txt, 'Type')
+ generate_typeclasscode('rrtype', rdatahdr_mtime, typecode2txt, 'Type')
generate_typeclasscode('rrclass', classdir_mtime,
classcode2txt, 'Class')
generate_rrparam('rrparamregistry', rdatahdr_mtime)
Modified: branches/trac327/src/lib/dns/message.cc
==============================================================================
--- branches/trac327/src/lib/dns/message.cc (original)
+++ branches/trac327/src/lib/dns/message.cc Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/message.h
==============================================================================
--- branches/trac327/src/lib/dns/message.h (original)
+++ branches/trac327/src/lib/dns/message.h Wed Nov 10 10:44:42 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,9 +511,6 @@
///
/// With EDNS the maximum size can be increased per message.
static const uint16_t DEFAULT_MAX_UDPSIZE = 512;
-
- /// \brief The highest EDNS version this implementation supports.
- static const uint8_t EDNS_SUPPORTED_VERSION = 0;
//@}
private:
Modified: branches/trac327/src/lib/dns/name.h
==============================================================================
--- branches/trac327/src/lib/dns/name.h (original)
+++ branches/trac327/src/lib/dns/name.h Wed Nov 10 10:44:42 2010
@@ -143,8 +143,8 @@
///
/// This constructor simply initializes the object in the straightforward
/// way.
- explicit NameComparisonResult(int order, unsigned int nlabels,
- NameRelation relation) :
+ NameComparisonResult(int order, unsigned int nlabels,
+ NameRelation relation) :
order_(order), nlabels_(nlabels), relation_(relation) {}
//@}
Modified: branches/trac327/src/lib/dns/python/Makefile.am
==============================================================================
--- branches/trac327/src/lib/dns/python/Makefile.am (original)
+++ branches/trac327/src/lib/dns/python/Makefile.am Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/python/README
==============================================================================
--- branches/trac327/src/lib/dns/python/README (original)
+++ branches/trac327/src/lib/dns/python/README Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/python/message_python.cc
==============================================================================
--- branches/trac327/src/lib/dns/python/message_python.cc (original)
+++ branches/trac327/src/lib/dns/python/message_python.cc Wed Nov 10 10:44:42 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, §ion_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!", §ion_type, §ion)) {
- return (NULL);
- }
- return (Py_BuildValue("I", self->message->getRRCount(*section->section)));
+ unsigned int section;
+ if (!PyArg_ParseTuple(args, "I", §ion)) {
+ 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!", §ion_type, §ion)) {
- return (NULL);
- }
+ unsigned int section;
+ if (!PyArg_ParseTuple(args, "I", §ion)) {
+ 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!", §ion_type, §ion,
- &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!", §ion, &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(§ion_type) < 0) {
- return (false);
- }
- Py_INCREF(§ion_type);
- PyModule_AddObject(mod, "Section",
- reinterpret_cast<PyObject*>(§ion_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: branches/trac327/src/lib/dns/python/messagerenderer_python.cc
==============================================================================
--- branches/trac327/src/lib/dns/python/messagerenderer_python.cc (original)
+++ branches/trac327/src/lib/dns/python/messagerenderer_python.cc Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/python/name_python.cc
==============================================================================
--- branches/trac327/src/lib/dns/python/name_python.cc (original)
+++ branches/trac327/src/lib/dns/python/name_python.cc Wed Nov 10 10:44:42 2010
@@ -50,7 +50,7 @@
isc::dns::NameComparisonResult* ncr;
};
-static int NameComparisonResult_init(s_NameComparisonResult* self UNUSED_PARAM, PyObject* args UNUSED_PARAM);
+static int NameComparisonResult_init(s_NameComparisonResult*, PyObject*);
static void NameComparisonResult_destroy(s_NameComparisonResult* self);
static PyObject* NameComparisonResult_getOrder(s_NameComparisonResult* self);
static PyObject* NameComparisonResult_getCommonLabels(s_NameComparisonResult* self);
@@ -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
@@ -123,9 +123,7 @@
};
static int
-NameComparisonResult_init(s_NameComparisonResult* self UNUSED_PARAM,
- PyObject* args UNUSED_PARAM)
-{
+NameComparisonResult_init(s_NameComparisonResult*, PyObject*) {
PyErr_SetString(PyExc_NotImplementedError,
"NameComparisonResult can't be built directly");
return (-1);
@@ -222,7 +220,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 +419,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 +435,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 +450,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 +563,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 +649,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: branches/trac327/src/lib/dns/python/question_python.cc
==============================================================================
--- branches/trac327/src/lib/dns/python/question_python.cc (original)
+++ branches/trac327/src/lib/dns/python/question_python.cc Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/python/rdata_python.cc
==============================================================================
--- branches/trac327/src/lib/dns/python/rdata_python.cc (original)
+++ branches/trac327/src/lib/dns/python/rdata_python.cc Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/python/rrclass_python.cc
==============================================================================
--- branches/trac327/src/lib/dns/python/rrclass_python.cc (original)
+++ branches/trac327/src/lib/dns/python/rrclass_python.cc Wed Nov 10 10:44:42 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
@@ -306,23 +306,23 @@
return (ret);
}
-static PyObject* RRClass_IN(s_RRClass *self UNUSED_PARAM) {
+static PyObject* RRClass_IN(s_RRClass*) {
return (RRClass_createStatic(RRClass::IN()));
}
-static PyObject* RRClass_CH(s_RRClass *self UNUSED_PARAM) {
+static PyObject* RRClass_CH(s_RRClass*) {
return (RRClass_createStatic(RRClass::CH()));
}
-static PyObject* RRClass_HS(s_RRClass *self UNUSED_PARAM) {
+static PyObject* RRClass_HS(s_RRClass*) {
return (RRClass_createStatic(RRClass::HS()));
}
-static PyObject* RRClass_NONE(s_RRClass *self UNUSED_PARAM) {
+static PyObject* RRClass_NONE(s_RRClass*) {
return (RRClass_createStatic(RRClass::NONE()));
}
-static PyObject* RRClass_ANY(s_RRClass *self UNUSED_PARAM) {
+static PyObject* RRClass_ANY(s_RRClass*) {
return (RRClass_createStatic(RRClass::ANY()));
}
// end of RRClass
@@ -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: branches/trac327/src/lib/dns/python/rrset_python.cc
==============================================================================
--- branches/trac327/src/lib/dns/python/rrset_python.cc (original)
+++ branches/trac327/src/lib/dns/python/rrset_python.cc Wed Nov 10 10:44:42 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
@@ -158,7 +158,7 @@
};
static int
-RRset_init(s_RRset* self, PyObject* args UNUSED_PARAM) {
+RRset_init(s_RRset* self, PyObject* args) {
s_Name* name;
s_RRClass* rrclass;
s_RRType* rrtype;
@@ -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: branches/trac327/src/lib/dns/python/rrttl_python.cc
==============================================================================
--- branches/trac327/src/lib/dns/python/rrttl_python.cc (original)
+++ branches/trac327/src/lib/dns/python/rrttl_python.cc Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/python/rrtype_python.cc
==============================================================================
--- branches/trac327/src/lib/dns/python/rrtype_python.cc (original)
+++ branches/trac327/src/lib/dns/python/rrtype_python.cc Wed Nov 10 10:44:42 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
@@ -344,97 +344,97 @@
}
static PyObject*
-RRType_NSEC3PARAM(s_RRType *self UNUSED_PARAM) {
+RRType_NSEC3PARAM(s_RRType*) {
return (RRType_createStatic(RRType::NSEC3PARAM()));
}
static PyObject*
-RRType_DNAME(s_RRType *self UNUSED_PARAM) {
+RRType_DNAME(s_RRType*) {
return (RRType_createStatic(RRType::DNAME()));
}
static PyObject*
-RRType_PTR(s_RRType *self UNUSED_PARAM) {
+RRType_PTR(s_RRType*) {
return (RRType_createStatic(RRType::PTR()));
}
static PyObject*
-RRType_MX(s_RRType *self UNUSED_PARAM) {
+RRType_MX(s_RRType*) {
return (RRType_createStatic(RRType::MX()));
}
static PyObject*
-RRType_DNSKEY(s_RRType *self UNUSED_PARAM) {
+RRType_DNSKEY(s_RRType*) {
return (RRType_createStatic(RRType::DNSKEY()));
}
static PyObject*
-RRType_TXT(s_RRType *self UNUSED_PARAM) {
+RRType_TXT(s_RRType*) {
return (RRType_createStatic(RRType::TXT()));
}
static PyObject*
-RRType_RRSIG(s_RRType *self UNUSED_PARAM) {
+RRType_RRSIG(s_RRType*) {
return (RRType_createStatic(RRType::RRSIG()));
}
static PyObject*
-RRType_NSEC(s_RRType *self UNUSED_PARAM) {
+RRType_NSEC(s_RRType*) {
return (RRType_createStatic(RRType::NSEC()));
}
static PyObject*
-RRType_AAAA(s_RRType *self UNUSED_PARAM) {
+RRType_AAAA(s_RRType*) {
return (RRType_createStatic(RRType::AAAA()));
}
static PyObject*
-RRType_DS(s_RRType *self UNUSED_PARAM) {
+RRType_DS(s_RRType*) {
return (RRType_createStatic(RRType::DS()));
}
static PyObject*
-RRType_OPT(s_RRType *self UNUSED_PARAM) {
+RRType_OPT(s_RRType*) {
return (RRType_createStatic(RRType::OPT()));
}
static PyObject*
-RRType_A(s_RRType *self UNUSED_PARAM) {
+RRType_A(s_RRType*) {
return (RRType_createStatic(RRType::A()));
}
static PyObject*
-RRType_NS(s_RRType *self UNUSED_PARAM) {
+RRType_NS(s_RRType*) {
return (RRType_createStatic(RRType::NS()));
}
static PyObject*
-RRType_CNAME(s_RRType *self UNUSED_PARAM) {
+RRType_CNAME(s_RRType*) {
return (RRType_createStatic(RRType::CNAME()));
}
static PyObject*
-RRType_SOA(s_RRType *self UNUSED_PARAM) {
+RRType_SOA(s_RRType*) {
return (RRType_createStatic(RRType::SOA()));
}
static PyObject*
-RRType_NSEC3(s_RRType *self UNUSED_PARAM) {
+RRType_NSEC3(s_RRType*) {
return (RRType_createStatic(RRType::NSEC3()));
}
static PyObject*
-RRType_IXFR(s_RRType *self UNUSED_PARAM) {
+RRType_IXFR(s_RRType*) {
return (RRType_createStatic(RRType::IXFR()));
}
static PyObject*
-RRType_AXFR(s_RRType *self UNUSED_PARAM) {
+RRType_AXFR(s_RRType*) {
return (RRType_createStatic(RRType::AXFR()));
}
static PyObject*
-RRType_ANY(s_RRType *self UNUSED_PARAM) {
+RRType_ANY(s_RRType*) {
return (RRType_createStatic(RRType::ANY()));
}
@@ -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: branches/trac327/src/lib/dns/python/tests/Makefile.am
==============================================================================
--- branches/trac327/src/lib/dns/python/tests/Makefile.am (original)
+++ branches/trac327/src/lib/dns/python/tests/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,7 +1,10 @@
-PYTESTS = message_python_test.py
+PYTESTS = edns_python_test.py
+PYTESTS += message_python_test.py
PYTESTS += messagerenderer_python_test.py
PYTESTS += name_python_test.py
PYTESTS += question_python_test.py
+PYTESTS += opcode_python_test.py
+PYTESTS += rcode_python_test.py
PYTESTS += rdata_python_test.py
PYTESTS += rrclass_python_test.py
PYTESTS += rrset_python_test.py
@@ -9,6 +12,7 @@
PYTESTS += rrtype_python_test.py
EXTRA_DIST = $(PYTESTS)
+EXTRA_DIST += testutil.py
# If necessary (rare cases), explicitly specify paths to dynamic libraries
# required by loadable python modules.
@@ -23,8 +27,8 @@
check-local:
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
- env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/lib/dns/python/.libs \
- TESTDATA_PATH=$(abs_top_srcdir)/src/lib/dns/tests/testdata \
+ env PYTHONPATH=$(abs_top_srcdir)/src/lib/dns/.libs:$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/lib/dns/python/.libs \
+ TESTDATA_PATH=$(abs_top_srcdir)/src/lib/dns/tests/testdata:$(abs_top_builddir)/src/lib/dns/tests/testdata \
$(LIBRARY_PATH_PLACEHOLDER) \
$(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
done
Modified: branches/trac327/src/lib/dns/python/tests/message_python_test.py
==============================================================================
--- branches/trac327/src/lib/dns/python/tests/message_python_test.py (original)
+++ branches/trac327/src/lib/dns/python/tests/message_python_test.py Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/python/tests/messagerenderer_python_test.py
==============================================================================
--- branches/trac327/src/lib/dns/python/tests/messagerenderer_python_test.py (original)
+++ branches/trac327/src/lib/dns/python/tests/messagerenderer_python_test.py Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/python/tests/name_python_test.py
==============================================================================
--- branches/trac327/src/lib/dns/python/tests/name_python_test.py (original)
+++ branches/trac327/src/lib/dns/python/tests/name_python_test.py Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/python/tests/question_python_test.py
==============================================================================
--- branches/trac327/src/lib/dns/python/tests/question_python_test.py (original)
+++ branches/trac327/src/lib/dns/python/tests/question_python_test.py Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/python/tests/rdata_python_test.py
==============================================================================
--- branches/trac327/src/lib/dns/python/tests/rdata_python_test.py (original)
+++ branches/trac327/src/lib/dns/python/tests/rdata_python_test.py Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/python/tests/rrclass_python_test.py
==============================================================================
--- branches/trac327/src/lib/dns/python/tests/rrclass_python_test.py (original)
+++ branches/trac327/src/lib/dns/python/tests/rrclass_python_test.py Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/python/tests/rrset_python_test.py
==============================================================================
--- branches/trac327/src/lib/dns/python/tests/rrset_python_test.py (original)
+++ branches/trac327/src/lib/dns/python/tests/rrset_python_test.py Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/python/tests/rrttl_python_test.py
==============================================================================
--- branches/trac327/src/lib/dns/python/tests/rrttl_python_test.py (original)
+++ branches/trac327/src/lib/dns/python/tests/rrttl_python_test.py Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/python/tests/rrtype_python_test.py
==============================================================================
--- branches/trac327/src/lib/dns/python/tests/rrtype_python_test.py (original)
+++ branches/trac327/src/lib/dns/python/tests/rrtype_python_test.py Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/question.cc
==============================================================================
--- branches/trac327/src/lib/dns/question.cc (original)
+++ branches/trac327/src/lib/dns/question.cc Wed Nov 10 10:44:42 2010
@@ -42,15 +42,13 @@
}
string
-Question::toText() const
-{
+Question::toText() const {
return (name_.toText() + " " + rrclass_.toText() + " " +
rrtype_.toText() + "\n");
}
unsigned int
-Question::toWire(OutputBuffer& buffer) const
-{
+Question::toWire(OutputBuffer& buffer) const {
name_.toWire(buffer);
rrtype_.toWire(buffer);
rrclass_.toWire(buffer); // number of "entries", which is always 1
@@ -59,8 +57,7 @@
}
unsigned int
-Question::toWire(MessageRenderer& renderer) const
-{
+Question::toWire(MessageRenderer& renderer) const {
renderer.writeName(name_);
rrtype_.toWire(renderer);
rrclass_.toWire(renderer);
@@ -69,8 +66,7 @@
}
ostream&
-operator<<(std::ostream& os, const Question& question)
-{
+operator<<(std::ostream& os, const Question& question) {
os << question.toText();
return (os);
}
Modified: branches/trac327/src/lib/dns/rdata.cc
==============================================================================
--- branches/trac327/src/lib/dns/rdata.cc (original)
+++ branches/trac327/src/lib/dns/rdata.cc Wed Nov 10 10:44:42 2010
@@ -82,8 +82,7 @@
}
int
-compareNames(const Name& n1, const Name& n2)
-{
+compareNames(const Name& n1, const Name& n2) {
size_t len1 = n1.getLength();
size_t len2 = n2.getLength();
size_t cmplen = min(len1, len2);
@@ -107,8 +106,7 @@
vector<uint8_t> data_;
};
-Generic::Generic(InputBuffer& buffer, size_t rdata_len)
-{
+Generic::Generic(InputBuffer& buffer, size_t rdata_len) {
if (rdata_len > MAX_RDLENGTH) {
isc_throw(InvalidRdataLength, "RDLENGTH too large");
}
@@ -119,8 +117,7 @@
impl_ = new GenericImpl(data);
}
-Generic::Generic(const string& rdata_string)
-{
+Generic::Generic(const string& rdata_string) {
istringstream iss(rdata_string);
string unknown_mark;
iss >> unknown_mark;
@@ -181,8 +178,7 @@
impl_ = new GenericImpl(data);
}
-Generic::~Generic()
-{
+Generic::~Generic() {
delete impl_;
}
@@ -191,8 +187,7 @@
{}
Generic&
-Generic::operator=(const Generic& source)
-{
+Generic::operator=(const Generic& source) {
if (impl_ == source.impl_) {
return (*this);
}
@@ -218,8 +213,7 @@
}
string
-Generic::toText() const
-{
+Generic::toText() const {
ostringstream oss;
oss << "\\# " << impl_->data_.size() << " ";
@@ -231,21 +225,18 @@
}
void
-Generic::toWire(OutputBuffer& buffer) const
-{
+Generic::toWire(OutputBuffer& buffer) const {
buffer.writeData(&impl_->data_[0], impl_->data_.size());
}
void
-Generic::toWire(MessageRenderer& renderer) const
-{
+Generic::toWire(MessageRenderer& renderer) const {
renderer.writeData(&impl_->data_[0], impl_->data_.size());
}
namespace {
inline int
-compare_internal(const GenericImpl& lhs, const GenericImpl& rhs)
-{
+compare_internal(const GenericImpl& lhs, const GenericImpl& rhs) {
size_t this_len = lhs.data_.size();
size_t other_len = rhs.data_.size();
size_t len = (this_len < other_len) ? this_len : other_len;
@@ -262,16 +253,14 @@
}
int
-Generic::compare(const Rdata& other) const
-{
+Generic::compare(const Rdata& other) const {
const Generic& other_rdata = dynamic_cast<const Generic&>(other);
return (compare_internal(*impl_, *other_rdata.impl_));
}
std::ostream&
-operator<<(std::ostream& os, const Generic& rdata)
-{
+operator<<(std::ostream& os, const Generic& rdata) {
return (os << rdata.toText());
}
} // end of namespace generic
Modified: branches/trac327/src/lib/dns/rdata/ch_3/a_1.cc
==============================================================================
--- branches/trac327/src/lib/dns/rdata/ch_3/a_1.cc (original)
+++ branches/trac327/src/lib/dns/rdata/ch_3/a_1.cc Wed Nov 10 10:44:42 2010
@@ -14,8 +14,6 @@
// $Id$
-#include <config.h> // for UNUSED_PARAM
-
#include <string>
#include <exceptions/exceptions.h>
@@ -30,42 +28,36 @@
// BEGIN_ISC_NAMESPACE
// BEGIN_RDATA_NAMESPACE
-A::A(const string& addrstr UNUSED_PARAM)
-{
+A::A(const string&) {
// TBD
}
-A::A(InputBuffer& buffer UNUSED_PARAM, size_t rdata_len UNUSED_PARAM)
-{
+A::A(InputBuffer&, size_t) {
// TBD
}
-A::A(const A& source UNUSED_PARAM) : Rdata() {
+A::A(const A&) : Rdata() {
// TBD
}
void
-A::toWire(OutputBuffer& buffer UNUSED_PARAM) const
-{
+A::toWire(OutputBuffer&) const {
// TBD
}
void
-A::toWire(MessageRenderer& renderer UNUSED_PARAM) const
-{
+A::toWire(MessageRenderer&) const {
// TBD
}
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&) const {
return (0); // dummy. TBD
}
Modified: branches/trac327/src/lib/dns/rdata/generic/cname_5.cc
==============================================================================
--- branches/trac327/src/lib/dns/rdata/generic/cname_5.cc (original)
+++ branches/trac327/src/lib/dns/rdata/generic/cname_5.cc Wed Nov 10 10:44:42 2010
@@ -33,7 +33,7 @@
cname_(namestr)
{}
-CNAME::CNAME(InputBuffer& buffer, size_t rdata_len UNUSED_PARAM) :
+CNAME::CNAME(InputBuffer& buffer, size_t) :
Rdata(), cname_(buffer)
{
// we don't need rdata_len for parsing. if necessary, the caller will
@@ -49,34 +49,29 @@
{}
void
-CNAME::toWire(OutputBuffer& buffer) const
-{
+CNAME::toWire(OutputBuffer& buffer) const {
cname_.toWire(buffer);
}
void
-CNAME::toWire(MessageRenderer& renderer) const
-{
+CNAME::toWire(MessageRenderer& renderer) const {
renderer.writeName(cname_);
}
string
-CNAME::toText() const
-{
+CNAME::toText() const {
return (cname_.toText());
}
int
-CNAME::compare(const Rdata& other) const
-{
+CNAME::compare(const Rdata& other) const {
const CNAME& other_cname = dynamic_cast<const CNAME&>(other);
return (compareNames(cname_, other_cname.cname_));
}
const Name&
-CNAME::getCname() const
-{
+CNAME::getCname() const {
return (cname_);
}
Modified: branches/trac327/src/lib/dns/rdata/generic/dname_39.cc
==============================================================================
--- branches/trac327/src/lib/dns/rdata/generic/dname_39.cc (original)
+++ branches/trac327/src/lib/dns/rdata/generic/dname_39.cc Wed Nov 10 10:44:42 2010
@@ -33,7 +33,7 @@
dname_(namestr)
{}
-DNAME::DNAME(InputBuffer& buffer, size_t rdata_len UNUSED_PARAM) :
+DNAME::DNAME(InputBuffer& buffer, size_t) :
dname_(buffer)
{
// we don't need rdata_len for parsing. if necessary, the caller will
@@ -49,34 +49,29 @@
{}
void
-DNAME::toWire(OutputBuffer& buffer) const
-{
+DNAME::toWire(OutputBuffer& buffer) const {
dname_.toWire(buffer);
}
void
-DNAME::toWire(MessageRenderer& renderer) const
-{
+DNAME::toWire(MessageRenderer& renderer) const {
renderer.writeName(dname_);
}
string
-DNAME::toText() const
-{
+DNAME::toText() const {
return (dname_.toText());
}
int
-DNAME::compare(const Rdata& other) const
-{
+DNAME::compare(const Rdata& other) const {
const DNAME& other_dname = dynamic_cast<const DNAME&>(other);
return (compareNames(dname_, other_dname.dname_));
}
const Name&
-DNAME::getDname() const
-{
+DNAME::getDname() const {
return (dname_);
}
Modified: branches/trac327/src/lib/dns/rdata/generic/dnskey_48.cc
==============================================================================
--- branches/trac327/src/lib/dns/rdata/generic/dnskey_48.cc (original)
+++ branches/trac327/src/lib/dns/rdata/generic/dnskey_48.cc Wed Nov 10 10:44:42 2010
@@ -103,8 +103,7 @@
{}
DNSKEY&
-DNSKEY::operator=(const DNSKEY& source)
-{
+DNSKEY::operator=(const DNSKEY& source) {
if (impl_ == source.impl_) {
return (*this);
}
@@ -116,14 +115,12 @@
return (*this);
}
-DNSKEY::~DNSKEY()
-{
+DNSKEY::~DNSKEY() {
delete impl_;
}
string
-DNSKEY::toText() const
-{
+DNSKEY::toText() const {
return (boost::lexical_cast<string>(static_cast<int>(impl_->flags_)) +
" " + boost::lexical_cast<string>(static_cast<int>(impl_->protocol_)) +
" " + boost::lexical_cast<string>(static_cast<int>(impl_->algorithm_)) +
@@ -131,8 +128,7 @@
}
void
-DNSKEY::toWire(OutputBuffer& buffer) const
-{
+DNSKEY::toWire(OutputBuffer& buffer) const {
buffer.writeUint16(impl_->flags_);
buffer.writeUint8(impl_->protocol_);
buffer.writeUint8(impl_->algorithm_);
@@ -140,8 +136,7 @@
}
void
-DNSKEY::toWire(MessageRenderer& renderer) const
-{
+DNSKEY::toWire(MessageRenderer& renderer) const {
renderer.writeUint16(impl_->flags_);
renderer.writeUint8(impl_->protocol_);
renderer.writeUint8(impl_->algorithm_);
@@ -149,8 +144,7 @@
}
int
-DNSKEY::compare(const Rdata& other) const
-{
+DNSKEY::compare(const Rdata& other) const {
const DNSKEY& other_dnskey = dynamic_cast<const DNSKEY&>(other);
if (impl_->flags_ != other_dnskey.impl_->flags_) {
@@ -176,8 +170,7 @@
}
uint16_t
-DNSKEY::getTag() const
-{
+DNSKEY::getTag() const {
if (impl_->algorithm_ == 1) {
int len = impl_->keydata_.size();
return ((impl_->keydata_[len - 3] << 8) + impl_->keydata_[len - 2]);
Modified: branches/trac327/src/lib/dns/rdata/generic/ds_43.cc
==============================================================================
--- branches/trac327/src/lib/dns/rdata/generic/ds_43.cc (original)
+++ branches/trac327/src/lib/dns/rdata/generic/ds_43.cc Wed Nov 10 10:44:42 2010
@@ -77,8 +77,7 @@
impl_ = new DSImpl(tag, algorithm, digest_type, digest);
}
-DS::DS(InputBuffer& buffer, size_t rdata_len)
-{
+DS::DS(InputBuffer& buffer, size_t rdata_len) {
if (rdata_len < 4) {
isc_throw(InvalidRdataLength, "DS too short");
}
@@ -99,8 +98,7 @@
{}
DS&
-DS::operator=(const DS& source)
-{
+DS::operator=(const DS& source) {
if (impl_ == source.impl_) {
return (*this);
}
@@ -112,14 +110,12 @@
return (*this);
}
-DS::~DS()
-{
+DS::~DS() {
delete impl_;
}
string
-DS::toText() const
-{
+DS::toText() const {
using namespace boost;
return (lexical_cast<string>(static_cast<int>(impl_->tag_)) +
" " + lexical_cast<string>(static_cast<int>(impl_->algorithm_)) +
@@ -128,8 +124,7 @@
}
void
-DS::toWire(OutputBuffer& buffer) const
-{
+DS::toWire(OutputBuffer& buffer) const {
buffer.writeUint16(impl_->tag_);
buffer.writeUint8(impl_->algorithm_);
buffer.writeUint8(impl_->digest_type_);
@@ -137,8 +132,7 @@
}
void
-DS::toWire(MessageRenderer& renderer) const
-{
+DS::toWire(MessageRenderer& renderer) const {
renderer.writeUint16(impl_->tag_);
renderer.writeUint8(impl_->algorithm_);
renderer.writeUint8(impl_->digest_type_);
@@ -146,8 +140,7 @@
}
int
-DS::compare(const Rdata& other) const
-{
+DS::compare(const Rdata& other) const {
const DS& other_ds = dynamic_cast<const DS&>(other);
if (impl_->tag_ != other_ds.impl_->tag_) {
Modified: branches/trac327/src/lib/dns/rdata/generic/mx_15.cc
==============================================================================
--- branches/trac327/src/lib/dns/rdata/generic/mx_15.cc (original)
+++ branches/trac327/src/lib/dns/rdata/generic/mx_15.cc Wed Nov 10 10:44:42 2010
@@ -34,7 +34,7 @@
// BEGIN_ISC_NAMESPACE
// BEGIN_RDATA_NAMESPACE
-MX::MX(InputBuffer& buffer, size_t rdata_len UNUSED_PARAM) :
+MX::MX(InputBuffer& buffer, size_t) :
preference_(buffer.readUint16()), mxname_(buffer)
{
// we don't need rdata_len for parsing. if necessary, the caller will
@@ -67,28 +67,24 @@
{}
void
-MX::toWire(OutputBuffer& buffer) const
-{
+MX::toWire(OutputBuffer& buffer) const {
buffer.writeUint16(preference_);
mxname_.toWire(buffer);
}
void
-MX::toWire(MessageRenderer& renderer) const
-{
+MX::toWire(MessageRenderer& renderer) const {
renderer.writeUint16(preference_);
renderer.writeName(mxname_);
}
string
-MX::toText() const
-{
+MX::toText() const {
return (lexical_cast<string>(preference_) + " " + mxname_.toText());
}
int
-MX::compare(const Rdata& other) const
-{
+MX::compare(const Rdata& other) const {
const MX& other_mx = dynamic_cast<const MX&>(other);
if (preference_ < other_mx.preference_) {
@@ -101,14 +97,12 @@
}
const Name&
-MX::getMXName() const
-{
+MX::getMXName() const {
return (mxname_);
}
uint16_t
-MX::getMXPref() const
-{
+MX::getMXPref() const {
return (preference_);
}
Modified: branches/trac327/src/lib/dns/rdata/generic/mx_15.h
==============================================================================
--- branches/trac327/src/lib/dns/rdata/generic/mx_15.h (original)
+++ branches/trac327/src/lib/dns/rdata/generic/mx_15.h Wed Nov 10 10:44:42 2010
@@ -35,7 +35,7 @@
// BEGIN_COMMON_MEMBERS
// END_COMMON_MEMBERS
- explicit MX(uint16_t preference, const Name& mxname);
+ MX(uint16_t preference, const Name& mxname);
///
/// Specialized methods
Modified: branches/trac327/src/lib/dns/rdata/generic/ns_2.cc
==============================================================================
--- branches/trac327/src/lib/dns/rdata/generic/ns_2.cc (original)
+++ branches/trac327/src/lib/dns/rdata/generic/ns_2.cc Wed Nov 10 10:44:42 2010
@@ -33,7 +33,7 @@
nsname_(namestr)
{}
-NS::NS(InputBuffer& buffer, size_t rdata_len UNUSED_PARAM) :
+NS::NS(InputBuffer& buffer, size_t) :
nsname_(buffer)
{
// we don't need rdata_len for parsing. if necessary, the caller will
@@ -45,34 +45,29 @@
{}
void
-NS::toWire(OutputBuffer& buffer) const
-{
+NS::toWire(OutputBuffer& buffer) const {
nsname_.toWire(buffer);
}
void
-NS::toWire(MessageRenderer& renderer) const
-{
+NS::toWire(MessageRenderer& renderer) const {
renderer.writeName(nsname_);
}
string
-NS::toText() const
-{
+NS::toText() const {
return (nsname_.toText());
}
int
-NS::compare(const Rdata& other) const
-{
+NS::compare(const Rdata& other) const {
const NS& other_ns = dynamic_cast<const NS&>(other);
return (compareNames(nsname_, other_ns.nsname_));
}
const Name&
-NS::getNSName() const
-{
+NS::getNSName() const {
return (nsname_);
}
Modified: branches/trac327/src/lib/dns/rdata/generic/nsec3_50.cc
==============================================================================
--- branches/trac327/src/lib/dns/rdata/generic/nsec3_50.cc (original)
+++ branches/trac327/src/lib/dns/rdata/generic/nsec3_50.cc Wed Nov 10 10:44:42 2010
@@ -127,8 +127,7 @@
impl_ = new NSEC3Impl(hashalg, flags, iterations, salt, next, typebits);
}
-NSEC3::NSEC3(InputBuffer& buffer, size_t rdata_len)
-{
+NSEC3::NSEC3(InputBuffer& buffer, size_t rdata_len) {
if (rdata_len < 5) {
isc_throw(InvalidRdataLength, "NSEC3 too short");
}
@@ -189,8 +188,7 @@
{}
NSEC3&
-NSEC3::operator=(const NSEC3& source)
-{
+NSEC3::operator=(const NSEC3& source) {
if (impl_ == source.impl_) {
return (*this);
}
@@ -202,14 +200,12 @@
return (*this);
}
-NSEC3::~NSEC3()
-{
+NSEC3::~NSEC3() {
delete impl_;
}
string
-NSEC3::toText() const
-{
+NSEC3::toText() const {
ostringstream s;
int len = 0;
for (int i = 0; i < impl_->typebits_.size(); i += len) {
@@ -241,8 +237,7 @@
}
void
-NSEC3::toWire(OutputBuffer& buffer) const
-{
+NSEC3::toWire(OutputBuffer& buffer) const {
buffer.writeUint8(impl_->hashalg_);
buffer.writeUint8(impl_->flags_);
buffer.writeUint16(impl_->iterations_);
@@ -254,8 +249,7 @@
}
void
-NSEC3::toWire(MessageRenderer& renderer) const
-{
+NSEC3::toWire(MessageRenderer& renderer) const {
renderer.writeUint8(impl_->hashalg_);
renderer.writeUint8(impl_->flags_);
renderer.writeUint16(impl_->iterations_);
@@ -267,8 +261,7 @@
}
int
-NSEC3::compare(const Rdata& other) const
-{
+NSEC3::compare(const Rdata& other) const {
const NSEC3& other_nsec3 = dynamic_cast<const NSEC3&>(other);
if (impl_->hashalg_ != other_nsec3.impl_->hashalg_) {
Modified: branches/trac327/src/lib/dns/rdata/generic/nsec3param_51.cc
==============================================================================
--- branches/trac327/src/lib/dns/rdata/generic/nsec3param_51.cc (original)
+++ branches/trac327/src/lib/dns/rdata/generic/nsec3param_51.cc Wed Nov 10 10:44:42 2010
@@ -73,8 +73,7 @@
impl_ = new NSEC3PARAMImpl(hashalg, flags, iterations, salt);
}
-NSEC3PARAM::NSEC3PARAM(InputBuffer& buffer, size_t rdata_len)
-{
+NSEC3PARAM::NSEC3PARAM(InputBuffer& buffer, size_t rdata_len) {
if (rdata_len < 4) {
isc_throw(InvalidRdataLength, "NSEC3PARAM too short");
}
@@ -102,8 +101,7 @@
{}
NSEC3PARAM&
-NSEC3PARAM::operator=(const NSEC3PARAM& source)
-{
+NSEC3PARAM::operator=(const NSEC3PARAM& source) {
if (impl_ == source.impl_) {
return (*this);
}
@@ -115,14 +113,12 @@
return (*this);
}
-NSEC3PARAM::~NSEC3PARAM()
-{
+NSEC3PARAM::~NSEC3PARAM() {
delete impl_;
}
string
-NSEC3PARAM::toText() const
-{
+NSEC3PARAM::toText() const {
using namespace boost;
return (lexical_cast<string>(static_cast<int>(impl_->hashalg_)) +
" " + lexical_cast<string>(static_cast<int>(impl_->flags_)) +
@@ -131,8 +127,7 @@
}
void
-NSEC3PARAM::toWire(OutputBuffer& buffer) const
-{
+NSEC3PARAM::toWire(OutputBuffer& buffer) const {
buffer.writeUint8(impl_->hashalg_);
buffer.writeUint8(impl_->flags_);
buffer.writeUint16(impl_->iterations_);
@@ -141,8 +136,7 @@
}
void
-NSEC3PARAM::toWire(MessageRenderer& renderer) const
-{
+NSEC3PARAM::toWire(MessageRenderer& renderer) const {
renderer.writeUint8(impl_->hashalg_);
renderer.writeUint8(impl_->flags_);
renderer.writeUint16(impl_->iterations_);
@@ -151,8 +145,7 @@
}
int
-NSEC3PARAM::compare(const Rdata& other) const
-{
+NSEC3PARAM::compare(const Rdata& other) const {
const NSEC3PARAM& other_param = dynamic_cast<const NSEC3PARAM&>(other);
if (impl_->hashalg_ != other_param.impl_->hashalg_) {
Modified: branches/trac327/src/lib/dns/rdata/generic/opt_41.cc
==============================================================================
--- branches/trac327/src/lib/dns/rdata/generic/opt_41.cc (original)
+++ branches/trac327/src/lib/dns/rdata/generic/opt_41.cc Wed Nov 10 10:44:42 2010
@@ -28,13 +28,11 @@
// BEGIN_ISC_NAMESPACE
// BEGIN_RDATA_NAMESPACE
-OPT::OPT(const string& type_str UNUSED_PARAM)
-{
+OPT::OPT(const string&) {
isc_throw(InvalidRdataText, "OPT RR cannot be constructed from text");
}
-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&) : 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&) const {
// nothing to do, as this simple version doesn't support any options.
}
void
-OPT::toWire(MessageRenderer& renderer UNUSED_PARAM) const
-{
+OPT::toWire(MessageRenderer&) const {
// nothing to do, as this simple version doesn't support any options.
}
int
-OPT::compare(const Rdata& other) const
-{
+OPT::compare(const Rdata& other) const {
//const OPT& other_opt = dynamic_cast<const OPT&>(other);
- dynamic_cast<const OPT&>(other); // right now we don't need other_opt
+ // right now we don't need other_opt:
+ static_cast<void>(dynamic_cast<const OPT&>(other));
return (0);
}
Modified: branches/trac327/src/lib/dns/rdata/generic/ptr_12.cc
==============================================================================
--- branches/trac327/src/lib/dns/rdata/generic/ptr_12.cc (original)
+++ branches/trac327/src/lib/dns/rdata/generic/ptr_12.cc Wed Nov 10 10:44:42 2010
@@ -33,7 +33,7 @@
ptr_name_(type_str)
{}
-PTR::PTR(InputBuffer& buffer, size_t rdata_len UNUSED_PARAM) :
+PTR::PTR(InputBuffer& buffer, size_t) :
ptr_name_(buffer)
{
// we don't need rdata_len for parsing. if necessary, the caller will
@@ -45,26 +45,22 @@
{}
std::string
-PTR::toText() const
-{
+PTR::toText() const {
return (ptr_name_.toText());
}
void
-PTR::toWire(OutputBuffer& buffer) const
-{
+PTR::toWire(OutputBuffer& buffer) const {
ptr_name_.toWire(buffer);
}
void
-PTR::toWire(MessageRenderer& renderer) const
-{
+PTR::toWire(MessageRenderer& renderer) const {
renderer.writeName(ptr_name_);
}
int
-PTR::compare(const Rdata& other) const
-{
+PTR::compare(const Rdata& other) const {
// The compare method normally begins with this dynamic cast.
const PTR& other_ptr = dynamic_cast<const PTR&>(other);
@@ -73,8 +69,7 @@
}
const Name&
-PTR::getPTRName() const
-{
+PTR::getPTRName() const {
return (ptr_name_);
}
Modified: branches/trac327/src/lib/dns/rdata/generic/rrsig_46.cc
==============================================================================
--- branches/trac327/src/lib/dns/rdata/generic/rrsig_46.cc (original)
+++ branches/trac327/src/lib/dns/rdata/generic/rrsig_46.cc Wed Nov 10 10:44:42 2010
@@ -106,8 +106,7 @@
Name(signer_txt), signature);
}
-RRSIG::RRSIG(InputBuffer& buffer, size_t rdata_len)
-{
+RRSIG::RRSIG(InputBuffer& buffer, size_t rdata_len) {
size_t pos = buffer.getPosition();
if (rdata_len < RRSIG_MINIMUM_LEN) {
@@ -142,8 +141,7 @@
{}
RRSIG&
-RRSIG::operator=(const RRSIG& source)
-{
+RRSIG::operator=(const RRSIG& source) {
if (impl_ == source.impl_) {
return (*this);
}
@@ -155,14 +153,12 @@
return (*this);
}
-RRSIG::~RRSIG()
-{
+RRSIG::~RRSIG() {
delete impl_;
}
string
-RRSIG::toText() const
-{
+RRSIG::toText() const {
string expire = timeToText(impl_->timeexpire_);
string inception = timeToText(impl_->timeinception_);
@@ -178,8 +174,7 @@
}
void
-RRSIG::toWire(OutputBuffer& buffer) const
-{
+RRSIG::toWire(OutputBuffer& buffer) const {
impl_->covered_.toWire(buffer);
buffer.writeUint8(impl_->algorithm_);
buffer.writeUint8(impl_->labels_);
@@ -192,8 +187,7 @@
}
void
-RRSIG::toWire(MessageRenderer& renderer) const
-{
+RRSIG::toWire(MessageRenderer& renderer) const {
impl_->covered_.toWire(renderer);
renderer.writeUint8(impl_->algorithm_);
renderer.writeUint8(impl_->labels_);
@@ -206,8 +200,7 @@
}
int
-RRSIG::compare(const Rdata& other) const
-{
+RRSIG::compare(const Rdata& other) const {
const RRSIG& other_rrsig = dynamic_cast<const RRSIG&>(other);
if (impl_->covered_.getCode() != other_rrsig.impl_->covered_.getCode()) {
Modified: branches/trac327/src/lib/dns/rdata/generic/soa_6.cc
==============================================================================
--- branches/trac327/src/lib/dns/rdata/generic/soa_6.cc (original)
+++ branches/trac327/src/lib/dns/rdata/generic/soa_6.cc Wed Nov 10 10:44:42 2010
@@ -34,7 +34,7 @@
// BEGIN_ISC_NAMESPACE
// BEGIN_RDATA_NAMESPACE
-SOA::SOA(InputBuffer& buffer, size_t rdata_len UNUSED_PARAM) :
+SOA::SOA(InputBuffer& buffer, size_t) :
mname_(buffer), rname_(buffer)
{
// we don't need rdata_len for parsing. if necessary, the caller will
@@ -94,24 +94,21 @@
}
void
-SOA::toWire(OutputBuffer& buffer) const
-{
+SOA::toWire(OutputBuffer& buffer) const {
mname_.toWire(buffer);
rname_.toWire(buffer);
buffer.writeData(numdata_, sizeof(numdata_));
}
void
-SOA::toWire(MessageRenderer& renderer) const
-{
+SOA::toWire(MessageRenderer& renderer) const {
renderer.writeName(mname_);
renderer.writeName(rname_);
renderer.writeData(numdata_, sizeof(numdata_));
}
string
-SOA::toText() const
-{
+SOA::toText() const {
InputBuffer b(numdata_, sizeof(numdata_));
uint32_t serial = b.readUint32();
uint32_t refresh = b.readUint32();
@@ -128,8 +125,7 @@
}
int
-SOA::compare(const Rdata& other) const
-{
+SOA::compare(const Rdata& other) const {
const SOA& other_soa = dynamic_cast<const SOA&>(other);
int order = compareNames(mname_, other_soa.mname_);
Modified: branches/trac327/src/lib/dns/rdata/generic/soa_6.h
==============================================================================
--- branches/trac327/src/lib/dns/rdata/generic/soa_6.h (original)
+++ branches/trac327/src/lib/dns/rdata/generic/soa_6.h Wed Nov 10 10:44:42 2010
@@ -33,9 +33,9 @@
// BEGIN_COMMON_MEMBERS
// END_COMMON_MEMBERS
- explicit SOA(const Name& mname, const Name& rname, uint32_t serial,
- uint32_t refresh, uint32_t retry, uint32_t expire,
- uint32_t minimum);
+ SOA(const Name& mname, const Name& rname, uint32_t serial,
+ uint32_t refresh, uint32_t retry, uint32_t expire,
+ uint32_t minimum);
private:
/// Note: this is a prototype version; we may reconsider
/// this representation later.
Modified: branches/trac327/src/lib/dns/rdata/hs_4/a_1.cc
==============================================================================
--- branches/trac327/src/lib/dns/rdata/hs_4/a_1.cc (original)
+++ branches/trac327/src/lib/dns/rdata/hs_4/a_1.cc Wed Nov 10 10:44:42 2010
@@ -14,8 +14,6 @@
// $Id$
-#include <config.h> // for UNUSED_PARAM
-
#include <string>
#include <exceptions/exceptions.h>
@@ -30,43 +28,36 @@
// BEGIN_ISC_NAMESPACE
// BEGIN_RDATA_NAMESPACE
-A::A(const string& addrstr UNUSED_PARAM)
-{
+A::A(const string&) {
// TBD
}
-A::A(InputBuffer& buffer UNUSED_PARAM, size_t rdata_len UNUSED_PARAM)
-{
+A::A(InputBuffer&, size_t) {
// TBD
}
-A::A(const A& source UNUSED_PARAM) : Rdata()
-{
+A::A(const A&) : Rdata() {
// TBD
}
void
-A::toWire(OutputBuffer& buffer UNUSED_PARAM) const
-{
+A::toWire(OutputBuffer&) const {
// TBD
}
void
-A::toWire(MessageRenderer& renderer UNUSED_PARAM) const
-{
+A::toWire(MessageRenderer&) const {
// TBD
}
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&) const {
return (0); // dummy. TBD
}
Modified: branches/trac327/src/lib/dns/rdata/template.cc
==============================================================================
--- branches/trac327/src/lib/dns/rdata/template.cc (original)
+++ branches/trac327/src/lib/dns/rdata/template.cc Wed Nov 10 10:44:42 2010
@@ -34,36 +34,29 @@
// If you added member functions specific to this derived class, you'll need
// to implement them here, of course.
-MyType::MyType(const string& type_str)
-{
+MyType::MyType(const string& type_str) {
}
-MyType::MyType(InputBuffer& buffer, size_t rdata_len)
-{
+MyType::MyType(InputBuffer& buffer, size_t rdata_len) {
}
-MyType::MyType(const MyType& source)
-{
+MyType::MyType(const MyType& source) {
}
std::string
-MyType::toText() const
-{
+MyType::toText() const {
}
void
-MyType::toWire(OutputBuffer& buffer) const
-{
+MyType::toWire(OutputBuffer& buffer) const {
}
void
-MyType::toWire(MessageRenderer& renderer) const
-{
+MyType::toWire(MessageRenderer& renderer) const {
}
int
-MyType::compare(const Rdata& other) const
-{
+MyType::compare(const Rdata& other) const {
// The compare method normally begins with this dynamic cast.
const MyType& other_mytype = dynamic_cast<const MyType&>(other);
// ...
Modified: branches/trac327/src/lib/dns/rrclass-placeholder.h
==============================================================================
--- branches/trac327/src/lib/dns/rrclass-placeholder.h (original)
+++ branches/trac327/src/lib/dns/rrclass-placeholder.h Wed Nov 10 10:44:42 2010
@@ -211,7 +211,7 @@
/// \brief Same as \c equals().
bool operator==(const RRClass& other) const { return (equals(other)); }
- /// \brief Return true iff two RRClasses are equal.
+ /// \brief Return true iff two RRClasses are not equal.
///
/// This method never throws an exception.
///
@@ -260,16 +260,14 @@
// END_WELL_KNOWN_CLASS_DEFINITIONS
inline const RRClass&
-RRClass::NONE()
-{
+RRClass::NONE() {
static RRClass rrclass(RRCLASS_NONE);
return (rrclass);
}
inline const RRClass&
-RRClass::ANY()
-{
+RRClass::ANY() {
static RRClass rrclass(RRCLASS_ANY);
return (rrclass);
Modified: branches/trac327/src/lib/dns/rrclass.cc
==============================================================================
--- branches/trac327/src/lib/dns/rrclass.cc (original)
+++ branches/trac327/src/lib/dns/rrclass.cc Wed Nov 10 10:44:42 2010
@@ -31,13 +31,11 @@
namespace isc {
namespace dns {
-RRClass::RRClass(const string& classstr)
-{
+RRClass::RRClass(const string& classstr) {
classcode_ = RRParamRegistry::getRegistry().textToClassCode(classstr);
}
-RRClass::RRClass(InputBuffer& buffer)
-{
+RRClass::RRClass(InputBuffer& buffer) {
if (buffer.getLength() - buffer.getPosition() < sizeof(uint16_t)) {
isc_throw(IncompleteRRClass, "incomplete wire-format RR class");
}
@@ -45,26 +43,22 @@
}
const string
-RRClass::toText() const
-{
+RRClass::toText() const {
return (RRParamRegistry::getRegistry().codeToClassText(classcode_));
}
void
-RRClass::toWire(OutputBuffer& buffer) const
-{
+RRClass::toWire(OutputBuffer& buffer) const {
buffer.writeUint16(classcode_);
}
void
-RRClass::toWire(MessageRenderer& renderer) const
-{
+RRClass::toWire(MessageRenderer& renderer) const {
renderer.writeUint16(classcode_);
}
ostream&
-operator<<(ostream& os, const RRClass& rrclass)
-{
+operator<<(ostream& os, const RRClass& rrclass) {
os << rrclass.toText();
return (os);
}
Modified: branches/trac327/src/lib/dns/rrparamregistry-placeholder.cc
==============================================================================
--- branches/trac327/src/lib/dns/rrparamregistry-placeholder.cc (original)
+++ branches/trac327/src/lib/dns/rrparamregistry-placeholder.cc Wed Nov 10 10:44:42 2010
@@ -49,8 +49,7 @@
/// containers below.
///
bool
-CICharLess(char c1, char c2)
-{
+CICharLess(char c1, char c2) {
return (tolower(static_cast<unsigned char>(c1)) <
tolower(static_cast<unsigned char>(c2)));
}
@@ -84,29 +83,25 @@
typedef map<uint16_t, RRTypeParamPtr> CodeRRTypeMap;
inline const string&
-RRTypeParam::UNKNOWN_PREFIX()
-{
+RRTypeParam::UNKNOWN_PREFIX() {
static const string p("TYPE");
return (p);
}
inline size_t
-RRTypeParam::UNKNOWN_PREFIXLEN()
-{
+RRTypeParam::UNKNOWN_PREFIXLEN() {
static size_t plen = UNKNOWN_PREFIX().size();
return (plen);
}
inline const string&
-RRTypeParam::UNKNOWN_MAX()
-{
+RRTypeParam::UNKNOWN_MAX() {
static const string p("TYPE65535");
return (p);
}
inline size_t
-RRTypeParam::UNKNOWN_MAXLEN()
-{
+RRTypeParam::UNKNOWN_MAXLEN() {
static size_t plen = UNKNOWN_MAX().size();
return (plen);
}
@@ -130,29 +125,25 @@
typedef map<uint16_t, RRClassParamPtr> CodeRRClassMap;
inline const string&
-RRClassParam::UNKNOWN_PREFIX()
-{
+RRClassParam::UNKNOWN_PREFIX() {
static const string p("CLASS");
return (p);
}
inline size_t
-RRClassParam::UNKNOWN_PREFIXLEN()
-{
+RRClassParam::UNKNOWN_PREFIXLEN() {
static size_t plen = UNKNOWN_PREFIX().size();
return (plen);
}
inline const string&
-RRClassParam::UNKNOWN_MAX()
-{
+RRClassParam::UNKNOWN_MAX() {
static const string p("CLASS65535");
return (p);
}
inline size_t
-RRClassParam::UNKNOWN_MAXLEN()
-{
+RRClassParam::UNKNOWN_MAXLEN() {
static size_t plen = UNKNOWN_MAX().size();
return (plen);
}
@@ -209,8 +200,7 @@
GenericRdataFactoryMap genericrdata_factories;
};
-RRParamRegistry::RRParamRegistry()
-{
+RRParamRegistry::RRParamRegistry() {
impl_ = new RRParamRegistryImpl;
// set up parameters for well-known RRs
@@ -223,14 +213,12 @@
}
}
-RRParamRegistry::~RRParamRegistry()
-{
+RRParamRegistry::~RRParamRegistry() {
delete impl_;
}
RRParamRegistry&
-RRParamRegistry::getRegistry()
-{
+RRParamRegistry::getRegistry() {
static RRParamRegistry registry;
return (registry);
@@ -301,8 +289,7 @@
}
bool
-RRParamRegistry::removeRdataFactory(const RRType& rrtype)
-{
+RRParamRegistry::removeRdataFactory(const RRType& rrtype) {
GenericRdataFactoryMap::iterator found =
impl_->genericrdata_factories.find(rrtype);
if (found != impl_->genericrdata_factories.end()) {
@@ -320,15 +307,13 @@
/// included in <cstring>. To be as much as portable within the C++ standard
/// we take the "in house" approach here.
///
-bool CICharEqual(char c1, char c2)
-{
+bool CICharEqual(char c1, char c2) {
return (tolower(static_cast<unsigned char>(c1)) ==
tolower(static_cast<unsigned char>(c2)));
}
bool
-caseStringEqual(const string& s1, const string& s2, size_t n)
-{
+caseStringEqual(const string& s1, const string& s2, size_t n) {
assert(s1.size() >= n && s2.size() >= n);
return (mismatch(s1.begin(), s1.begin() + n, s2.begin(), CICharEqual).first
@@ -378,8 +363,7 @@
template <typename MC, typename MS>
inline bool
-removeParam(uint16_t code, MC& codemap, MS& stringmap)
-{
+removeParam(uint16_t code, MC& codemap, MS& stringmap) {
typename MC::iterator found = codemap.find(code);
if (found != codemap.end()) {
@@ -397,8 +381,7 @@
template <typename PT, typename MS, typename ET>
inline uint16_t
-textToCode(const string& code_str, MS& stringmap)
-{
+textToCode(const string& code_str, MS& stringmap) {
typename MS::const_iterator found;
found = stringmap.find(code_str);
@@ -424,8 +407,7 @@
template <typename PT, typename MC>
inline string
-codeToText(uint16_t code, MC& codemap)
-{
+codeToText(uint16_t code, MC& codemap) {
typename MC::const_iterator found;
found = codemap.find(code);
@@ -440,57 +422,49 @@
}
bool
-RRParamRegistry::addType(const string& type_string, uint16_t code)
-{
+RRParamRegistry::addType(const string& type_string, uint16_t code) {
return (addParam<RRTypeParam, CodeRRTypeMap, StrRRTypeMap, RRTypeExists>
(type_string, code, impl_->code2typemap, impl_->str2typemap));
}
bool
-RRParamRegistry::removeType(uint16_t code)
-{
+RRParamRegistry::removeType(uint16_t code) {
return (removeParam<CodeRRTypeMap, StrRRTypeMap>(code, impl_->code2typemap,
impl_->str2typemap));
}
uint16_t
-RRParamRegistry::textToTypeCode(const string& type_string) const
-{
+RRParamRegistry::textToTypeCode(const string& type_string) const {
return (textToCode<RRTypeParam, StrRRTypeMap,
InvalidRRType>(type_string, impl_->str2typemap));
}
string
-RRParamRegistry::codeToTypeText(uint16_t code) const
-{
+RRParamRegistry::codeToTypeText(uint16_t code) const {
return (codeToText<RRTypeParam, CodeRRTypeMap>(code, impl_->code2typemap));
}
bool
-RRParamRegistry::addClass(const string& class_string, uint16_t code)
-{
+RRParamRegistry::addClass(const string& class_string, uint16_t code) {
return (addParam<RRClassParam, CodeRRClassMap, StrRRClassMap, RRClassExists>
(class_string, code, impl_->code2classmap, impl_->str2classmap));
}
bool
-RRParamRegistry::removeClass(uint16_t code)
-{
+RRParamRegistry::removeClass(uint16_t code) {
return (removeParam<CodeRRClassMap, StrRRClassMap>(code,
impl_->code2classmap,
impl_->str2classmap));
}
uint16_t
-RRParamRegistry::textToClassCode(const string& class_string) const
-{
+RRParamRegistry::textToClassCode(const string& class_string) const {
return (textToCode<RRClassParam, StrRRClassMap,
InvalidRRClass>(class_string, impl_->str2classmap));
}
string
-RRParamRegistry::codeToClassText(uint16_t code) const
-{
+RRParamRegistry::codeToClassText(uint16_t code) const {
return (codeToText<RRClassParam, CodeRRClassMap>(code,
impl_->code2classmap));
}
Modified: branches/trac327/src/lib/dns/rrset.cc
==============================================================================
--- branches/trac327/src/lib/dns/rrset.cc (original)
+++ branches/trac327/src/lib/dns/rrset.cc Wed Nov 10 10:44:42 2010
@@ -35,14 +35,12 @@
namespace isc {
namespace dns {
void
-AbstractRRset::addRdata(const Rdata& rdata)
-{
+AbstractRRset::addRdata(const Rdata& rdata) {
addRdata(createRdata(getType(), getClass(), rdata));
}
string
-AbstractRRset::toText() const
-{
+AbstractRRset::toText() const {
string s;
RdataIteratorPtr it = getRdataIterator();
@@ -64,8 +62,7 @@
namespace {
template <typename T>
inline unsigned int
-rrsetToWire(const AbstractRRset& rrset, T& output, const size_t limit)
-{
+rrsetToWire(const AbstractRRset& rrset, T& output, const size_t limit) {
unsigned int n = 0;
RdataIteratorPtr it = rrset.getRdataIterator();
@@ -105,14 +102,12 @@
}
unsigned int
-AbstractRRset::toWire(OutputBuffer& buffer) const
-{
+AbstractRRset::toWire(OutputBuffer& buffer) const {
return (rrsetToWire<OutputBuffer>(*this, buffer, 0));
}
unsigned int
-AbstractRRset::toWire(MessageRenderer& renderer) const
-{
+AbstractRRset::toWire(MessageRenderer& renderer) const {
const unsigned int rrs_written = rrsetToWire<MessageRenderer>(
*this, renderer, renderer.getLengthLimit());
if (getRdataCount() > rrs_written) {
@@ -122,8 +117,7 @@
}
ostream&
-operator<<(ostream& os, const AbstractRRset& rrset)
-{
+operator<<(ostream& os, const AbstractRRset& rrset) {
os << rrset.toText();
return (os);
}
@@ -151,80 +145,67 @@
impl_ = new BasicRRsetImpl(name, rrclass, rrtype, ttl);
}
-BasicRRset::~BasicRRset()
-{
+BasicRRset::~BasicRRset() {
delete impl_;
}
void
-BasicRRset::addRdata(ConstRdataPtr rdata)
-{
+BasicRRset::addRdata(ConstRdataPtr rdata) {
impl_->rdatalist_.push_back(rdata);
}
void
-BasicRRset::addRdata(const Rdata& rdata)
-{
+BasicRRset::addRdata(const Rdata& rdata) {
AbstractRRset::addRdata(rdata);
}
unsigned int
-BasicRRset::getRdataCount() const
-{
+BasicRRset::getRdataCount() const {
return (impl_->rdatalist_.size());
}
const Name&
-BasicRRset::getName() const
-{
+BasicRRset::getName() const {
return (impl_->name_);
}
const RRClass&
-BasicRRset::getClass() const
-{
+BasicRRset::getClass() const {
return (impl_->rrclass_);
}
const RRType&
-BasicRRset::getType() const
-{
+BasicRRset::getType() const {
return (impl_->rrtype_);
}
const RRTTL&
-BasicRRset::getTTL() const
-{
+BasicRRset::getTTL() const {
return (impl_->ttl_);
}
void
-BasicRRset::setName(const Name& name)
-{
+BasicRRset::setName(const Name& name) {
impl_->name_ = name;
}
void
-BasicRRset::setTTL(const RRTTL& ttl)
-{
+BasicRRset::setTTL(const RRTTL& ttl) {
impl_->ttl_ = ttl;
}
string
-BasicRRset::toText() const
-{
+BasicRRset::toText() const {
return (AbstractRRset::toText());
}
unsigned int
-BasicRRset::toWire(OutputBuffer& buffer) const
-{
+BasicRRset::toWire(OutputBuffer& buffer) const {
return (AbstractRRset::toWire(buffer));
}
unsigned int
-BasicRRset::toWire(MessageRenderer& renderer) const
-{
+BasicRRset::toWire(MessageRenderer& renderer) const {
return (AbstractRRset::toWire(renderer));
}
@@ -256,8 +237,7 @@
}
RdataIteratorPtr
-BasicRRset::getRdataIterator() const
-{
+BasicRRset::getRdataIterator() const {
return (RdataIteratorPtr(new BasicRdataIterator(impl_->rdatalist_)));
}
}
Modified: branches/trac327/src/lib/dns/rrset.h
==============================================================================
--- branches/trac327/src/lib/dns/rrset.h (original)
+++ branches/trac327/src/lib/dns/rrset.h Wed Nov 10 10:44:42 2010
@@ -530,8 +530,8 @@
/// \param rrclass The RR class of the RRset.
/// \param rrtype The RR type of the RRset.
/// \param ttl The TTL of the RRset.
- explicit BasicRRset(const Name& name, const RRClass& rrclass,
- const RRType& rrtype, const RRTTL& ttl);
+ BasicRRset(const Name& name, const RRClass& rrclass,
+ const RRType& rrtype, const RRTTL& ttl);
/// \brief The destructor.
virtual ~BasicRRset();
//@}
@@ -668,7 +668,7 @@
/// QNAME/QTYPE/QCLASS as a single object.
class RRset : public BasicRRset {
public:
- explicit RRset(const Name& name, const RRClass& rrclass,
+ RRset(const Name& name, const RRClass& rrclass,
const RRType& rrtype, const RRTTL& ttl);
virtual ~RRset();
@@ -692,8 +692,8 @@
/// \brief Adds an RRSIG RR to this RRset's signatures
virtual void addRRsig(const rdata::RdataPtr rdata) {
if (!rrsig_) {
- rrsig_ = RRsetPtr(new RRset(this->getName(), this->getClass(),
- RRType::RRSIG(), this->getTTL()));
+ rrsig_ = RRsetPtr(new RRset(getName(), getClass(),
+ RRType::RRSIG(), getTTL()));
}
rrsig_->addRdata(rdata);
}
@@ -703,8 +703,8 @@
RdataIteratorPtr it = sigs.getRdataIterator();
if (!rrsig_) {
- rrsig_ = RRsetPtr(new RRset(this->getName(), this->getClass(),
- RRType::RRSIG(), this->getTTL()));
+ rrsig_ = RRsetPtr(new RRset(getName(), getClass(),
+ RRType::RRSIG(), getTTL()));
}
for (it->first(); !it->isLast(); it->next()) {
Modified: branches/trac327/src/lib/dns/rrsetlist.cc
==============================================================================
--- branches/trac327/src/lib/dns/rrsetlist.cc (original)
+++ branches/trac327/src/lib/dns/rrsetlist.cc Wed Nov 10 10:44:42 2010
@@ -41,8 +41,7 @@
}
void
-RRsetList::append(RRsetList& source)
-{
+RRsetList::append(RRsetList& source) {
BOOST_FOREACH(RRsetPtr rrset, source) {
addRRset(rrset);
}
Modified: branches/trac327/src/lib/dns/rrttl.cc
==============================================================================
--- branches/trac327/src/lib/dns/rrttl.cc (original)
+++ branches/trac327/src/lib/dns/rrttl.cc Wed Nov 10 10:44:42 2010
@@ -29,8 +29,7 @@
namespace isc {
namespace dns {
-RRTTL::RRTTL(const string& ttlstr)
-{
+RRTTL::RRTTL(const string& ttlstr) {
// Some systems (at least gcc-4.4) flow negative values over into
// unsigned integer, where older systems failed to parse. We want
// that failure here, so we extract into int64 and check the value
@@ -45,8 +44,7 @@
}
}
-RRTTL::RRTTL(InputBuffer& buffer)
-{
+RRTTL::RRTTL(InputBuffer& buffer) {
if (buffer.getLength() - buffer.getPosition() < sizeof(uint32_t)) {
isc_throw(IncompleteRRTTL, "incomplete wire-format TTL value");
}
@@ -54,28 +52,24 @@
}
const string
-RRTTL::toText() const
-{
+RRTTL::toText() const {
ostringstream oss;
oss << ttlval_;
return (oss.str());
}
void
-RRTTL::toWire(OutputBuffer& buffer) const
-{
+RRTTL::toWire(OutputBuffer& buffer) const {
buffer.writeUint32(ttlval_);
}
void
-RRTTL::toWire(MessageRenderer& renderer) const
-{
+RRTTL::toWire(MessageRenderer& renderer) const {
renderer.writeUint32(ttlval_);
}
ostream&
-operator<<(ostream& os, const RRTTL& rrttl)
-{
+operator<<(ostream& os, const RRTTL& rrttl) {
os << rrttl.toText();
return (os);
}
Modified: branches/trac327/src/lib/dns/rrtype-placeholder.h
==============================================================================
--- branches/trac327/src/lib/dns/rrtype-placeholder.h (original)
+++ branches/trac327/src/lib/dns/rrtype-placeholder.h Wed Nov 10 10:44:42 2010
@@ -223,7 +223,7 @@
/// \brief Same as \c equals().
bool operator==(const RRType& other) const { return (equals(other)); }
- /// \brief Return true iff two RRTypes are equal.
+ /// \brief Return true iff two RRTypes are not equal.
///
/// This method never throws an exception.
///
@@ -276,22 +276,19 @@
// END_WELL_KNOWN_TYPE_DEFINITIONS
inline const RRType&
-RRType::IXFR()
-{
+RRType::IXFR() {
static RRType rrtype(RRTYPE_IXFR);
return (rrtype);
}
inline const RRType&
-RRType::AXFR()
-{
+RRType::AXFR() {
static RRType rrtype(RRTYPE_AXFR);
return (rrtype);
}
inline const RRType&
-RRType::ANY()
-{
+RRType::ANY() {
static RRType rrtype(RRTYPE_ANY);
return (rrtype);
}
Modified: branches/trac327/src/lib/dns/rrtype.cc
==============================================================================
--- branches/trac327/src/lib/dns/rrtype.cc (original)
+++ branches/trac327/src/lib/dns/rrtype.cc Wed Nov 10 10:44:42 2010
@@ -33,13 +33,11 @@
namespace isc {
namespace dns {
-RRType::RRType(const string& typestr)
-{
+RRType::RRType(const string& typestr) {
typecode_ = RRParamRegistry::getRegistry().textToTypeCode(typestr);
}
-RRType::RRType(InputBuffer& buffer)
-{
+RRType::RRType(InputBuffer& buffer) {
if (buffer.getLength() - buffer.getPosition() < sizeof(uint16_t)) {
isc_throw(IncompleteRRType, "incomplete wire-format RR type");
}
@@ -47,26 +45,22 @@
}
const string
-RRType::toText() const
-{
+RRType::toText() const {
return (RRParamRegistry::getRegistry().codeToTypeText(typecode_));
}
void
-RRType::toWire(OutputBuffer& buffer) const
-{
+RRType::toWire(OutputBuffer& buffer) const {
buffer.writeUint16(typecode_);
}
void
-RRType::toWire(MessageRenderer& renderer) const
-{
+RRType::toWire(MessageRenderer& renderer) const {
renderer.writeUint16(typecode_);
}
ostream&
-operator<<(ostream& os, const RRType& rrtype)
-{
+operator<<(ostream& os, const RRType& rrtype) {
os << rrtype.toText();
return (os);
}
Modified: branches/trac327/src/lib/dns/tests/Makefile.am
==============================================================================
--- branches/trac327/src/lib/dns/tests/Makefile.am (original)
+++ branches/trac327/src/lib/dns/tests/Makefile.am Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/tests/buffer_unittest.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/buffer_unittest.cc (original)
+++ branches/trac327/src/lib/dns/tests/buffer_unittest.cc Wed Nov 10 10:44:42 2010
@@ -48,8 +48,7 @@
const uint8_t BufferTest::testdata[5] = {1, 2, 3, 4, 5};
-TEST_F(BufferTest, inputBufferRead)
-{
+TEST_F(BufferTest, inputBufferRead) {
EXPECT_EQ(5, ibuffer.getLength());
EXPECT_EQ(1, ibuffer.readUint8());
EXPECT_EQ(1, ibuffer.getPosition());
@@ -66,8 +65,7 @@
EXPECT_EQ(0, memcmp(vdata, testdata, sizeof(testdata)));
}
-TEST_F(BufferTest, inputBufferException)
-{
+TEST_F(BufferTest, inputBufferException) {
EXPECT_THROW(ibuffer.setPosition(6), isc::dns::InvalidBufferPosition);
ibuffer.setPosition(sizeof(testdata));
@@ -84,8 +82,7 @@
isc::dns::InvalidBufferPosition);
}
-TEST_F(BufferTest, outputBufferExtend)
-{
+TEST_F(BufferTest, outputBufferExtend) {
EXPECT_EQ(0, obuffer.getCapacity());
EXPECT_EQ(0, obuffer.getLength());
obuffer.writeUint8(10);
@@ -93,8 +90,7 @@
EXPECT_EQ(1, obuffer.getLength());
}
-TEST_F(BufferTest, outputBufferWrite)
-{
+TEST_F(BufferTest, outputBufferWrite) {
const uint8_t* cp;
obuffer.writeUint8(1);
@@ -126,8 +122,7 @@
EXPECT_EQ(0, memcmp(cp + 7, testdata, sizeof(testdata)));
}
-TEST_F(BufferTest, outputBufferWriteat)
-{
+TEST_F(BufferTest, outputBufferWriteat) {
obuffer.writeUint32(data32);
expected_size += sizeof(data32);
@@ -153,8 +148,7 @@
isc::dns::InvalidBufferPosition);
}
-TEST_F(BufferTest, outputBufferSkip)
-{
+TEST_F(BufferTest, outputBufferSkip) {
obuffer.skip(4);
EXPECT_EQ(4, obuffer.getLength());
@@ -162,8 +156,7 @@
EXPECT_EQ(6, obuffer.getLength());
}
-TEST_F(BufferTest, outputBufferTrim)
-{
+TEST_F(BufferTest, outputBufferTrim) {
obuffer.writeData(testdata, sizeof(testdata));
EXPECT_EQ(5, obuffer.getLength());
@@ -176,8 +169,7 @@
EXPECT_THROW(obuffer.trim(3), OutOfRange);
}
-TEST_F(BufferTest, outputBufferReadat)
-{
+TEST_F(BufferTest, outputBufferReadat) {
obuffer.writeData(testdata, sizeof(testdata));
for (int i = 0; i < sizeof(testdata); i ++) {
EXPECT_EQ(testdata[i], obuffer[i]);
@@ -185,8 +177,7 @@
EXPECT_THROW(obuffer[sizeof(testdata)], isc::dns::InvalidBufferPosition);
}
-TEST_F(BufferTest, outputBufferClear)
-{
+TEST_F(BufferTest, outputBufferClear) {
obuffer.writeData(testdata, sizeof(testdata));
obuffer.clear();
EXPECT_EQ(0, obuffer.getLength());
Modified: branches/trac327/src/lib/dns/tests/message_unittest.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/message_unittest.cc (original)
+++ branches/trac327/src/lib/dns/tests/message_unittest.cc Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/tests/messagerenderer_unittest.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/messagerenderer_unittest.cc (original)
+++ branches/trac327/src/lib/dns/tests/messagerenderer_unittest.cc Wed Nov 10 10:44:42 2010
@@ -130,7 +130,7 @@
// name compression in case sensitive manner. See the data file
// description for details.
renderer.setCompressMode(MessageRenderer::CASE_SENSITIVE);
- UnitTestUtil::readWireData("name_toWire5", data);
+ UnitTestUtil::readWireData("name_toWire5.wire", data);
renderer.writeName(Name("a.example.com."));
renderer.writeName(Name("b.eXample.com."));
renderer.writeName(Name("c.eXample.com."));
@@ -140,7 +140,7 @@
TEST_F(MessageRendererTest, writeNameMixedCaseCompress) {
renderer.setCompressMode(MessageRenderer::CASE_SENSITIVE);
- UnitTestUtil::readWireData("name_toWire6", data);
+ UnitTestUtil::readWireData("name_toWire6.wire", data);
renderer.writeName(Name("a.example.com."));
renderer.writeName(Name("b.eXample.com."));
Modified: branches/trac327/src/lib/dns/tests/name_unittest.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/name_unittest.cc (original)
+++ branches/trac327/src/lib/dns/tests/name_unittest.cc Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/tests/question_unittest.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/question_unittest.cc (original)
+++ branches/trac327/src/lib/dns/tests/question_unittest.cc Wed Nov 10 10:44:42 2010
@@ -56,8 +56,7 @@
};
Question
-questionFromWire(const char* datafile, size_t position = 0)
-{
+questionFromWire(const char* datafile, size_t position = 0) {
vector<unsigned char> data;
UnitTestUtil::readWireData(datafile, data);
@@ -67,8 +66,7 @@
return (Question(buffer));
}
-TEST_F(QuestionTest, fromWire)
-{
+TEST_F(QuestionTest, fromWire) {
Question q = questionFromWire("question_fromWire");
EXPECT_EQ(example_name1, q.getName());
@@ -88,14 +86,12 @@
EXPECT_THROW(questionFromWire("question_fromWire", 36), IncompleteRRClass);
}
-TEST_F(QuestionTest, toText)
-{
+TEST_F(QuestionTest, toText) {
EXPECT_EQ("foo.example.com. IN NS\n", test_question1.toText());
EXPECT_EQ("bar.example.com. CH A\n", test_question2.toText());
}
-TEST_F(QuestionTest, toWireBuffer)
-{
+TEST_F(QuestionTest, toWireBuffer) {
test_question1.toWire(obuffer);
test_question2.toWire(obuffer);
UnitTestUtil::readWireData("question_toWire1", wiredata);
@@ -103,8 +99,7 @@
obuffer.getLength(), &wiredata[0], wiredata.size());
}
-TEST_F(QuestionTest, toWireRenderer)
-{
+TEST_F(QuestionTest, toWireRenderer) {
test_question1.toWire(renderer);
test_question2.toWire(renderer);
UnitTestUtil::readWireData("question_toWire2", wiredata);
@@ -113,15 +108,13 @@
}
// test operator<<. We simply confirm it appends the result of toText().
-TEST_F(QuestionTest, LeftShiftOperator)
-{
+TEST_F(QuestionTest, LeftShiftOperator) {
ostringstream oss;
oss << test_question1;
EXPECT_EQ(test_question1.toText(), oss.str());
}
-TEST_F(QuestionTest, comparison)
-{
+TEST_F(QuestionTest, comparison) {
const Name a("a"), b("b");
const RRClass in(RRClass::IN()), ch(RRClass::CH());
const RRType ns(RRType::NS()), aaaa(RRType::AAAA());
Modified: branches/trac327/src/lib/dns/tests/rdata_cname_unittest.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/rdata_cname_unittest.cc (original)
+++ branches/trac327/src/lib/dns/tests/rdata_cname_unittest.cc Wed Nov 10 10:44:42 2010
@@ -50,8 +50,7 @@
// compressed.
0x03, 0x63, 0x6e, 0x32, 0xc0, 0x03 };
-TEST_F(Rdata_CNAME_Test, createFromText)
-{
+TEST_F(Rdata_CNAME_Test, createFromText) {
EXPECT_EQ(0, rdata_cname.compare(generic::CNAME("cn.example.com")));
// explicitly add a trailing dot. should be the same RDATA.
EXPECT_EQ(0, rdata_cname.compare(generic::CNAME("cn.example.com.")));
@@ -64,8 +63,7 @@
"cn.example.com")));
}
-TEST_F(Rdata_CNAME_Test, createFromWire)
-{
+TEST_F(Rdata_CNAME_Test, createFromWire) {
EXPECT_EQ(0, rdata_cname.compare(
*rdataFactoryFromFile(RRType("CNAME"), RRClass("IN"),
"rdata_cname_fromWire")));
@@ -90,16 +88,14 @@
InvalidRdataLength);
}
-TEST_F(Rdata_CNAME_Test, toWireBuffer)
-{
+TEST_F(Rdata_CNAME_Test, toWireBuffer) {
rdata_cname.toWire(obuffer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
obuffer.getData(), obuffer.getLength(),
wiredata_cname, sizeof(wiredata_cname));
}
-TEST_F(Rdata_CNAME_Test, toWireRenderer)
-{
+TEST_F(Rdata_CNAME_Test, toWireRenderer) {
rdata_cname.toWire(renderer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
obuffer.getData(), obuffer.getLength(),
@@ -110,13 +106,11 @@
wiredata_cname2, sizeof(wiredata_cname2));
}
-TEST_F(Rdata_CNAME_Test, toText)
-{
+TEST_F(Rdata_CNAME_Test, toText) {
EXPECT_EQ("cn.example.com.", rdata_cname.toText());
}
-TEST_F(Rdata_CNAME_Test, getCname)
-{
+TEST_F(Rdata_CNAME_Test, getCname) {
EXPECT_EQ(Name("cn.example.com."), rdata_cname.getCname());
}
}
Modified: branches/trac327/src/lib/dns/tests/rdata_dname_unittest.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/rdata_dname_unittest.cc (original)
+++ branches/trac327/src/lib/dns/tests/rdata_dname_unittest.cc Wed Nov 10 10:44:42 2010
@@ -50,8 +50,7 @@
// compressed.
0x03, 0x64, 0x6e, 0x32, 0xc0, 0x03 };
-TEST_F(Rdata_DNAME_Test, createFromText)
-{
+TEST_F(Rdata_DNAME_Test, createFromText) {
EXPECT_EQ(0, rdata_dname.compare(generic::DNAME("dn.example.com")));
// explicitly add a trailing dot. should be the same RDATA.
EXPECT_EQ(0, rdata_dname.compare(generic::DNAME("dn.example.com.")));
@@ -64,8 +63,7 @@
"dn.example.com")));
}
-TEST_F(Rdata_DNAME_Test, createFromWire)
-{
+TEST_F(Rdata_DNAME_Test, createFromWire) {
EXPECT_EQ(0, rdata_dname.compare(
*rdataFactoryFromFile(RRType("DNAME"), RRClass("IN"),
"rdata_dname_fromWire")));
@@ -90,16 +88,14 @@
InvalidRdataLength);
}
-TEST_F(Rdata_DNAME_Test, toWireBuffer)
-{
+TEST_F(Rdata_DNAME_Test, toWireBuffer) {
rdata_dname.toWire(obuffer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
obuffer.getData(), obuffer.getLength(),
wiredata_dname, sizeof(wiredata_dname));
}
-TEST_F(Rdata_DNAME_Test, toWireRenderer)
-{
+TEST_F(Rdata_DNAME_Test, toWireRenderer) {
rdata_dname.toWire(renderer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
obuffer.getData(), obuffer.getLength(),
@@ -110,13 +106,11 @@
wiredata_dname2, sizeof(wiredata_dname2));
}
-TEST_F(Rdata_DNAME_Test, toText)
-{
+TEST_F(Rdata_DNAME_Test, toText) {
EXPECT_EQ("dn.example.com.", rdata_dname.toText());
}
-TEST_F(Rdata_DNAME_Test, getDname)
-{
+TEST_F(Rdata_DNAME_Test, getDname) {
EXPECT_EQ(Name("dn.example.com."), rdata_dname.getDname());
}
}
Modified: branches/trac327/src/lib/dns/tests/rdata_ns_unittest.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/rdata_ns_unittest.cc (original)
+++ branches/trac327/src/lib/dns/tests/rdata_ns_unittest.cc Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/tests/rdata_nsec_unittest.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/rdata_nsec_unittest.cc (original)
+++ branches/trac327/src/lib/dns/tests/rdata_nsec_unittest.cc Wed Nov 10 10:44:42 2010
@@ -70,39 +70,39 @@
// A malformed NSEC bitmap length field that could cause overflow.
EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
- "rdata_nsec_fromWire4"),
+ "rdata_nsec_fromWire4.wire"),
DNSMessageFORMERR);
// The bitmap field is incomplete (only the first byte is included)
EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
- "rdata_nsec_fromWire5"),
+ "rdata_nsec_fromWire5.wire"),
DNSMessageFORMERR);
// Bitmap length is 0, which is invalid.
EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
- "rdata_nsec_fromWire6"),
+ "rdata_nsec_fromWire6.wire"),
DNSMessageFORMERR);
// A boundary case: longest possible bitmaps (32 maps). This should be
// accepted.
EXPECT_NO_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
- "rdata_nsec_fromWire7"));
+ "rdata_nsec_fromWire7.wire"));
// Another boundary condition: 33 bitmaps, which should be rejected.
EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
- "rdata_nsec_fromWire8"),
+ "rdata_nsec_fromWire8.wire"),
DNSMessageFORMERR);
// Disordered bitmap window blocks.
EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
- "rdata_nsec_fromWire9"),
+ "rdata_nsec_fromWire9.wire"),
DNSMessageFORMERR);
// Bitmap ending with all-zero bytes. Not necessarily harmful except
// the additional overhead of parsing, but invalid according to the
// spec anyway.
EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
- "rdata_nsec_fromWire10"),
+ "rdata_nsec_fromWire10.wire"),
DNSMessageFORMERR);
}
Modified: branches/trac327/src/lib/dns/tests/rdata_opt_unittest.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/rdata_opt_unittest.cc (original)
+++ branches/trac327/src/lib/dns/tests/rdata_opt_unittest.cc Wed Nov 10 10:44:42 2010
@@ -38,14 +38,12 @@
const generic::OPT rdata_opt;
-TEST_F(Rdata_OPT_Test, createFromText)
-{
+TEST_F(Rdata_OPT_Test, createFromText) {
// OPT RR cannot be created from text.
EXPECT_THROW(generic::OPT("this does not matter"), InvalidRdataText);
}
-TEST_F(Rdata_OPT_Test, createFromWire)
-{
+TEST_F(Rdata_OPT_Test, createFromWire) {
// Valid cases: in the simple implementation with no supported options,
// we can only check these don't throw.
EXPECT_NO_THROW(rdataFactoryFromFile(RRType::OPT(), RRClass("CLASS4096"),
@@ -59,25 +57,21 @@
InvalidRdataLength);
}
-TEST_F(Rdata_OPT_Test, toWireBuffer)
-{
+TEST_F(Rdata_OPT_Test, toWireBuffer) {
rdata_opt.toWire(obuffer);
EXPECT_EQ(0, obuffer.getLength());
}
-TEST_F(Rdata_OPT_Test, toWireRenderer)
-{
+TEST_F(Rdata_OPT_Test, toWireRenderer) {
rdata_opt.toWire(renderer);
EXPECT_EQ(0, obuffer.getLength());
}
-TEST_F(Rdata_OPT_Test, toText)
-{
+TEST_F(Rdata_OPT_Test, toText) {
EXPECT_EQ("", rdata_opt.toText());
}
-TEST_F(Rdata_OPT_Test, compare)
-{
+TEST_F(Rdata_OPT_Test, compare) {
// This simple implementation always returns "true"
EXPECT_EQ(0, rdata_opt.compare(
*rdataFactoryFromFile(RRType::OPT(), RRClass::CH(),
Modified: branches/trac327/src/lib/dns/tests/rdata_ptr_unittest.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/rdata_ptr_unittest.cc (original)
+++ branches/trac327/src/lib/dns/tests/rdata_ptr_unittest.cc Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/tests/rdata_rrsig_unittest.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/rdata_rrsig_unittest.cc (original)
+++ branches/trac327/src/lib/dns/tests/rdata_rrsig_unittest.cc Wed Nov 10 10:44:42 2010
@@ -131,7 +131,7 @@
// RDLEN is too short
EXPECT_THROW(rdataFactoryFromFile(RRType::RRSIG(), RRClass::IN(),
- "rdata_rrsig_fromWire2"),
+ "rdata_rrsig_fromWire2.wire"),
InvalidRdataLength);
}
}
Modified: branches/trac327/src/lib/dns/tests/rdata_soa_unittest.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/rdata_soa_unittest.cc (original)
+++ branches/trac327/src/lib/dns/tests/rdata_soa_unittest.cc Wed Nov 10 10:44:42 2010
@@ -65,7 +65,7 @@
obuffer.skip(2);
rdata_soa.toWire(obuffer);
vector<unsigned char> data;
- UnitTestUtil::readWireData("rdata_soa_toWireUncompressed", data);
+ UnitTestUtil::readWireData("rdata_soa_toWireUncompressed.wire", data);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
static_cast<const uint8_t *>(obuffer.getData()) + 2,
obuffer.getLength() - 2, &data[2], data.size() - 2);
Modified: branches/trac327/src/lib/dns/tests/rdata_txt_unittest.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/rdata_txt_unittest.cc (original)
+++ branches/trac327/src/lib/dns/tests/rdata_txt_unittest.cc Wed Nov 10 10:44:42 2010
@@ -109,12 +109,12 @@
// Empty character string
EXPECT_EQ(0, rdata_txt_empty.compare(
*rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
- "rdata_txt_fromWire2")));
+ "rdata_txt_fromWire2.wire")));
// Multiple character strings
obuffer.clear();
rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
- "rdata_txt_fromWire3")->toWire(obuffer);
+ "rdata_txt_fromWire3.wire")->toWire(obuffer);
// the result should be 'wiredata_txt' repeated twice
vector<uint8_t> expected_data(wiredata_txt, wiredata_txt +
sizeof(wiredata_txt));
@@ -145,12 +145,12 @@
// RDATA is empty, which is invalid for TXT.
EXPECT_THROW(rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
- "rdata_txt_fromWire4"),
+ "rdata_txt_fromWire4.wire"),
DNSMessageFORMERR);
// character-string length is too large, which could cause overrun.
EXPECT_THROW(rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
- "rdata_txt_fromWire5"),
+ "rdata_txt_fromWire5.wire"),
DNSMessageFORMERR);
}
Modified: branches/trac327/src/lib/dns/tests/rdata_unittest.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/rdata_unittest.cc (original)
+++ branches/trac327/src/lib/dns/tests/rdata_unittest.cc Wed Nov 10 10:44:42 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: branches/trac327/src/lib/dns/tests/rrclass_unittest.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/rrclass_unittest.cc (original)
+++ branches/trac327/src/lib/dns/tests/rrclass_unittest.cc Wed Nov 10 10:44:42 2010
@@ -51,8 +51,7 @@
0x00, 0x80, 0x00, 0xff, 0xff };
RRClass
-RRClassTest::rrclassFactoryFromWire(const char* datafile)
-{
+RRClassTest::rrclassFactoryFromWire(const char* datafile) {
std::vector<unsigned char> data;
UnitTestUtil::readWireData(datafile, data);
@@ -61,8 +60,7 @@
return (RRClass(buffer));
}
-TEST_F(RRClassTest, fromText)
-{
+TEST_F(RRClassTest, fromText) {
EXPECT_EQ("IN", RRClass("IN").toText());
EXPECT_EQ("CH", RRClass("CH").toText());
@@ -81,29 +79,25 @@
EXPECT_THROW(RRClass("CLASS65000 "), InvalidRRClass);
}
-TEST_F(RRClassTest, fromWire)
-{
+TEST_F(RRClassTest, fromWire) {
EXPECT_EQ(0x1234,
rrclassFactoryFromWire("rrcode16_fromWire1").getCode());
EXPECT_THROW(rrclassFactoryFromWire("rrcode16_fromWire2"),
IncompleteRRClass);
}
-TEST_F(RRClassTest, caseConstruct)
-{
+TEST_F(RRClassTest, caseConstruct) {
EXPECT_EQ("IN", RRClass("in").toText());
EXPECT_EQ("CH", RRClass("ch").toText());
EXPECT_EQ("CLASS65535", RRClass("class65535").toText());
}
-TEST_F(RRClassTest, toText)
-{
+TEST_F(RRClassTest, toText) {
EXPECT_EQ("IN", RRClass(1).toText());
EXPECT_EQ("CLASS65000", RRClass(65000).toText());
}
-TEST_F(RRClassTest, toWireBuffer)
-{
+TEST_F(RRClassTest, toWireBuffer) {
rrclass_1.toWire(obuffer);
rrclass_0x80.toWire(obuffer);
rrclass_0x800.toWire(obuffer);
@@ -115,8 +109,7 @@
wiredata, sizeof(wiredata));
}
-TEST_F(RRClassTest, toWireRenderer)
-{
+TEST_F(RRClassTest, toWireRenderer) {
rrclass_1.toWire(renderer);
rrclass_0x80.toWire(renderer);
rrclass_0x800.toWire(renderer);
@@ -128,14 +121,12 @@
wiredata, sizeof(wiredata));
}
-TEST_F(RRClassTest, wellKnownClasss)
-{
+TEST_F(RRClassTest, wellKnownClasss) {
EXPECT_EQ(1, RRClass::IN().getCode());
EXPECT_EQ("IN", RRClass::IN().toText());
}
-TEST_F(RRClassTest, compare)
-{
+TEST_F(RRClassTest, compare) {
EXPECT_TRUE(RRClass(1) == RRClass("IN"));
EXPECT_TRUE(RRClass(1).equals(RRClass("IN")));
EXPECT_TRUE(RRClass(0).nequals(RRClass("IN")));
@@ -145,8 +136,7 @@
}
// test operator<<. We simply confirm it appends the result of toText().
-TEST_F(RRClassTest, LeftShiftOperator)
-{
+TEST_F(RRClassTest, LeftShiftOperator) {
ostringstream oss;
oss << RRClass::IN();
EXPECT_EQ(RRClass::IN().toText(), oss.str());
Modified: branches/trac327/src/lib/dns/tests/rrparamregistry_unittest.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/rrparamregistry_unittest.cc (original)
+++ branches/trac327/src/lib/dns/tests/rrparamregistry_unittest.cc Wed Nov 10 10:44:42 2010
@@ -70,8 +70,7 @@
const string RRParamRegistryTest::test_class_str("TESTCLASS");
const string RRParamRegistryTest::test_type_str("TESTTYPE");
-TEST_F(RRParamRegistryTest, addRemove)
-{
+TEST_F(RRParamRegistryTest, addRemove) {
RRParamRegistry::getRegistry().addType(test_type_str, test_type_code);
RRParamRegistry::getRegistry().addClass(test_class_str, test_class_code);
EXPECT_EQ(65533, RRClass("TESTCLASS").getCode());
@@ -90,8 +89,7 @@
EXPECT_FALSE(RRParamRegistry::getRegistry().removeClass(test_class_code));
}
-TEST_F(RRParamRegistryTest, addError)
-{
+TEST_F(RRParamRegistryTest, addError) {
// An attempt to override a pre-registered class should fail with an
// exception, and the pre-registered one should remain in the registry.
EXPECT_THROW(RRParamRegistry::getRegistry().addClass(test_class_str, 1),
@@ -114,8 +112,7 @@
{ return (RdataPtr(new in::A(dynamic_cast<const in::A&>(source)))); }
};
-TEST_F(RRParamRegistryTest, addRemoveFactory)
-{
+TEST_F(RRParamRegistryTest, addRemoveFactory) {
// By default, the test type/code pair should be considered "unknown",
// so the following should trigger an exception.
EXPECT_THROW(createRdata(RRType(test_type_code), RRClass(test_class_code),
Modified: branches/trac327/src/lib/dns/tests/rrset_unittest.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/rrset_unittest.cc (original)
+++ branches/trac327/src/lib/dns/tests/rrset_unittest.cc Wed Nov 10 10:44:42 2010
@@ -72,57 +72,49 @@
static const int MAX_RDATA_COUNT = 100;
};
-TEST_F(RRsetTest, getRdataCount)
-{
+TEST_F(RRsetTest, getRdataCount) {
for (int i = 0; i < MAX_RDATA_COUNT; ++i) {
EXPECT_EQ(i, rrset_a_empty.getRdataCount());
rrset_a_empty.addRdata(in::A("192.0.2.1"));
}
}
-TEST_F(RRsetTest, getName)
-{
+TEST_F(RRsetTest, getName) {
EXPECT_EQ(test_name, rrset_a.getName());
EXPECT_EQ(test_domain, rrset_ns.getName());
}
-TEST_F(RRsetTest, getClass)
-{
+TEST_F(RRsetTest, getClass) {
EXPECT_EQ(RRClass("IN"), rrset_a.getClass());
EXPECT_EQ(RRClass("CH"), rrset_ch_txt.getClass());
}
-TEST_F(RRsetTest, getType)
-{
+TEST_F(RRsetTest, getType) {
EXPECT_EQ(RRType("A"), rrset_a.getType());
EXPECT_EQ(RRType("NS"), rrset_ns.getType());
EXPECT_EQ(RRType("TXT"), rrset_ch_txt.getType());
}
-TEST_F(RRsetTest, getTTL)
-{
+TEST_F(RRsetTest, getTTL) {
EXPECT_EQ(RRTTL(3600), rrset_a.getTTL());
EXPECT_EQ(RRTTL(86400), rrset_ns.getTTL());
EXPECT_EQ(RRTTL(0), rrset_ch_txt.getTTL());
}
-TEST_F(RRsetTest, setTTL)
-{
+TEST_F(RRsetTest, setTTL) {
rrset_a.setTTL(RRTTL(86400));
EXPECT_EQ(RRTTL(86400), rrset_a.getTTL());
rrset_a.setTTL(RRTTL(0));
EXPECT_EQ(RRTTL(0), rrset_a.getTTL());
}
-TEST_F(RRsetTest, setName)
-{
+TEST_F(RRsetTest, setName) {
rrset_a.setName(test_nsname);
EXPECT_EQ(test_nsname, rrset_a.getName());
}
void
-addRdataTestCommon(const RRset& rrset)
-{
+addRdataTestCommon(const RRset& rrset) {
EXPECT_EQ(2, rrset.getRdataCount());
RdataIteratorPtr it = rrset.getRdataIterator();
@@ -136,8 +128,7 @@
EXPECT_TRUE(it->isLast());
}
-TEST_F(RRsetTest, addRdata)
-{
+TEST_F(RRsetTest, addRdata) {
addRdataTestCommon(rrset_a);
// Reference version of addRdata() doesn't allow to add a different
@@ -145,8 +136,7 @@
EXPECT_THROW(rrset_a.addRdata(generic::NS(test_nsname)), std::bad_cast);
}
-TEST_F(RRsetTest, addRdataPtr)
-{
+TEST_F(RRsetTest, addRdataPtr) {
rrset_a_empty.addRdata(createRdata(rrset_a_empty.getType(),
rrset_a_empty.getClass(),
"192.0.2.1"));
@@ -163,8 +153,7 @@
EXPECT_EQ(3, rrset_a_empty.getRdataCount());
}
-TEST_F(RRsetTest, iterator)
-{
+TEST_F(RRsetTest, iterator) {
// Iterator for an empty RRset.
RdataIteratorPtr it = rrset_a_empty.getRdataIterator();
it->first();
@@ -187,8 +176,7 @@
}
}
-TEST_F(RRsetTest, toText)
-{
+TEST_F(RRsetTest, toText) {
EXPECT_EQ("test.example.com. 3600 IN A 192.0.2.1\n"
"test.example.com. 3600 IN A 192.0.2.2\n",
rrset_a.toText());
@@ -197,8 +185,7 @@
EXPECT_THROW(rrset_a_empty.toText(), EmptyRRset);
}
-TEST_F(RRsetTest, toWireBuffer)
-{
+TEST_F(RRsetTest, toWireBuffer) {
rrset_a.toWire(buffer);
UnitTestUtil::readWireData("rrset_toWire1", wiredata);
@@ -210,8 +197,7 @@
EXPECT_THROW(rrset_a_empty.toWire(buffer), EmptyRRset);
}
-TEST_F(RRsetTest, toWireRenderer)
-{
+TEST_F(RRsetTest, toWireRenderer) {
rrset_ns.addRdata(generic::NS(test_nsname));
rrset_a.toWire(renderer);
@@ -227,8 +213,7 @@
}
// test operator<<. We simply confirm it appends the result of toText().
-TEST_F(RRsetTest, LeftShiftOperator)
-{
+TEST_F(RRsetTest, LeftShiftOperator) {
ostringstream oss;
oss << rrset_a;
EXPECT_EQ(rrset_a.toText(), oss.str());
Modified: branches/trac327/src/lib/dns/tests/rrttl_unittest.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/rrttl_unittest.cc (original)
+++ branches/trac327/src/lib/dns/tests/rrttl_unittest.cc Wed Nov 10 10:44:42 2010
@@ -57,8 +57,7 @@
0xff, 0xff, 0xff, 0xff };
RRTTL
-RRTTLTest::rrttlFactoryFromWire(const char* datafile)
-{
+RRTTLTest::rrttlFactoryFromWire(const char* datafile) {
std::vector<unsigned char> data;
UnitTestUtil::readWireData(datafile, data);
@@ -67,8 +66,7 @@
return (RRTTL(buffer));
}
-TEST_F(RRTTLTest, fromText)
-{
+TEST_F(RRTTLTest, fromText) {
EXPECT_EQ(0, ttl_0.getValue());
EXPECT_EQ(3600, ttl_1h.getValue());
EXPECT_EQ(86400, ttl_1d.getValue());
@@ -82,16 +80,14 @@
EXPECT_THROW(RRTTL("4294967296"), InvalidRRTTL); // must be 32-bit
}
-TEST_F(RRTTLTest, fromWire)
-{
+TEST_F(RRTTLTest, fromWire) {
EXPECT_EQ(0x12345678,
rrttlFactoryFromWire("rrcode32_fromWire1").getValue());
EXPECT_THROW(rrttlFactoryFromWire("rrcode32_fromWire2"),
IncompleteRRTTL);
}
-TEST_F(RRTTLTest, toText)
-{
+TEST_F(RRTTLTest, toText) {
EXPECT_EQ("0", ttl_0.toText());
EXPECT_EQ("3600", ttl_1h.toText());
EXPECT_EQ("86400", ttl_1d.toText());
@@ -99,8 +95,7 @@
EXPECT_EQ("4294967295", ttl_max.toText());
}
-TEST_F(RRTTLTest, toWireBuffer)
-{
+TEST_F(RRTTLTest, toWireBuffer) {
ttl_0.toWire(obuffer);
ttl_1h.toWire(obuffer);
ttl_1d.toWire(obuffer);
@@ -112,8 +107,7 @@
wiredata, sizeof(wiredata));
}
-TEST_F(RRTTLTest, toWireRenderer)
-{
+TEST_F(RRTTLTest, toWireRenderer) {
ttl_0.toWire(renderer);
ttl_1h.toWire(renderer);
ttl_1d.toWire(renderer);
@@ -125,8 +119,7 @@
wiredata, sizeof(wiredata));
}
-TEST_F(RRTTLTest, equal)
-{
+TEST_F(RRTTLTest, equal) {
EXPECT_TRUE(RRTTL("3600") == ttl_1h);
EXPECT_TRUE(RRTTL("86400").equals(ttl_1d));
@@ -139,8 +132,7 @@
// The test logic is simple, and all tests are just straightforward variations
// of the first one.
//
-TEST_F(RRTTLTest, leq)
-{
+TEST_F(RRTTLTest, leq) {
// small <= large is true
EXPECT_TRUE(ttl_small.leq(ttl_large));
EXPECT_TRUE(ttl_small <= ttl_large);
@@ -154,8 +146,7 @@
EXPECT_FALSE(ttl_large <= ttl_small);
}
-TEST_F(RRTTLTest, geq)
-{
+TEST_F(RRTTLTest, geq) {
EXPECT_TRUE(ttl_large.geq(ttl_small));
EXPECT_TRUE(ttl_large >= ttl_small);
@@ -166,8 +157,7 @@
EXPECT_FALSE(ttl_small >= ttl_large);
}
-TEST_F(RRTTLTest, lthan)
-{
+TEST_F(RRTTLTest, lthan) {
EXPECT_TRUE(ttl_small.lthan(ttl_large));
EXPECT_TRUE(ttl_small < ttl_large);
@@ -178,8 +168,7 @@
EXPECT_FALSE(ttl_large < ttl_small);
}
-TEST_F(RRTTLTest, gthan)
-{
+TEST_F(RRTTLTest, gthan) {
EXPECT_TRUE(ttl_large.gthan(ttl_small));
EXPECT_TRUE(ttl_large > ttl_small);
@@ -191,8 +180,7 @@
}
// test operator<<. We simply confirm it appends the result of toText().
-TEST_F(RRTTLTest, LeftShiftOperator)
-{
+TEST_F(RRTTLTest, LeftShiftOperator) {
ostringstream oss;
oss << ttl_1h;
EXPECT_EQ(ttl_1h.toText(), oss.str());
Modified: branches/trac327/src/lib/dns/tests/rrtype_unittest.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/rrtype_unittest.cc (original)
+++ branches/trac327/src/lib/dns/tests/rrtype_unittest.cc Wed Nov 10 10:44:42 2010
@@ -51,8 +51,7 @@
0x00, 0x80, 0x00, 0xff, 0xff };
RRType
-RRTypeTest::rrtypeFactoryFromWire(const char* datafile)
-{
+RRTypeTest::rrtypeFactoryFromWire(const char* datafile) {
std::vector<unsigned char> data;
UnitTestUtil::readWireData(datafile, data);
@@ -61,8 +60,7 @@
return (RRType(buffer));
}
-TEST_F(RRTypeTest, fromText)
-{
+TEST_F(RRTypeTest, fromText) {
EXPECT_EQ("A", RRType("A").toText());
EXPECT_EQ("NS", RRType("NS").toText());
@@ -85,29 +83,25 @@
EXPECT_THROW(RRType("TYPE65000 "), InvalidRRType);
}
-TEST_F(RRTypeTest, fromWire)
-{
+TEST_F(RRTypeTest, fromWire) {
EXPECT_EQ(0x1234,
rrtypeFactoryFromWire("rrcode16_fromWire1").getCode());
EXPECT_THROW(rrtypeFactoryFromWire("rrcode16_fromWire2"), IncompleteRRType);
}
// from string, lower case
-TEST_F(RRTypeTest, caseConstruct)
-{
+TEST_F(RRTypeTest, caseConstruct) {
EXPECT_EQ("A", RRType("a").toText());
EXPECT_EQ("NS", RRType("ns").toText());
EXPECT_EQ("TYPE65535", RRType("type65535").toText());
}
-TEST_F(RRTypeTest, toText)
-{
+TEST_F(RRTypeTest, toText) {
EXPECT_EQ("A", RRType(1).toText());
EXPECT_EQ("TYPE65000", RRType(65000).toText());
}
-TEST_F(RRTypeTest, toWireBuffer)
-{
+TEST_F(RRTypeTest, toWireBuffer) {
rrtype_1.toWire(obuffer);
rrtype_0x80.toWire(obuffer);
rrtype_0x800.toWire(obuffer);
@@ -119,8 +113,7 @@
wiredata, sizeof(wiredata));
}
-TEST_F(RRTypeTest, toWireRenderer)
-{
+TEST_F(RRTypeTest, toWireRenderer) {
rrtype_1.toWire(renderer);
rrtype_0x80.toWire(renderer);
rrtype_0x800.toWire(renderer);
@@ -132,14 +125,12 @@
wiredata, sizeof(wiredata));
}
-TEST_F(RRTypeTest, wellKnownTypes)
-{
+TEST_F(RRTypeTest, wellKnownTypes) {
EXPECT_EQ(1, RRType::A().getCode());
EXPECT_EQ("A", RRType::A().toText());
}
-TEST_F(RRTypeTest, compare)
-{
+TEST_F(RRTypeTest, compare) {
EXPECT_TRUE(RRType(1) == RRType("A"));
EXPECT_TRUE(RRType(1).equals(RRType("A")));
EXPECT_TRUE(RRType(0) != RRType("A"));
@@ -150,8 +141,7 @@
}
// test operator<<. We simply confirm it appends the result of toText().
-TEST_F(RRTypeTest, LeftShiftOperator)
-{
+TEST_F(RRTypeTest, LeftShiftOperator) {
ostringstream oss;
oss << RRType::A();
EXPECT_EQ(RRType::A().toText(), oss.str());
Modified: branches/trac327/src/lib/dns/tests/run_unittests.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/run_unittests.cc (original)
+++ branches/trac327/src/lib/dns/tests/run_unittests.cc Wed Nov 10 10:44:42 2010
@@ -21,7 +21,8 @@
int
main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
- isc::UnitTestUtil::addDataPath(TEST_DATA_DIR);
+ isc::UnitTestUtil::addDataPath(TEST_DATA_SRCDIR);
+ isc::UnitTestUtil::addDataPath(TEST_DATA_BUILDDIR);
return (RUN_ALL_TESTS());
}
Modified: branches/trac327/src/lib/dns/tests/testdata/gen-wiredata.py.in
==============================================================================
--- branches/trac327/src/lib/dns/tests/testdata/gen-wiredata.py.in (original)
+++ branches/trac327/src/lib/dns/tests/testdata/gen-wiredata.py.in Wed Nov 10 10:44:42 2010
@@ -19,9 +19,9 @@
from datetime import datetime
from optparse import OptionParser
-re_hex = re.compile('0x[0-9a-fA-F]+')
-re_decimal = re.compile('\d+$')
-re_string = re.compile("\'(.*)\'$")
+re_hex = re.compile(r'0x[0-9a-fA-F]+')
+re_decimal = re.compile(r'\d+$')
+re_string = re.compile(r"\'(.*)\'$")
dnssec_timefmt = '%Y%m%d%H%M%S'
@@ -365,9 +365,6 @@
parser.add_option('-o', '--output', action='store', dest='output',
default=None, metavar='FILE',
help='output file name [default: prefix of input_file]')
- parser.add_option('-m', '--mode', action='store', dest='mode',
- default='message', metavar='[message|custom]',
- help='specify dump mode [default: %default]')
(options, args) = parser.parse_args()
if len(args) == 0:
@@ -389,9 +386,10 @@
print_header(output, configfile)
- if options.mode == 'custom':
+ # First try the 'custom' mode; if it fails assume the standard mode.
+ try:
sections = config.get('custom', 'sections').split(':')
- else:
+ except configparser.NoSectionError:
sections = ['header', 'question', 'edns']
for s in sections:
Modified: branches/trac327/src/lib/dns/tests/unittest_util.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/unittest_util.cc (original)
+++ branches/trac327/src/lib/dns/tests/unittest_util.cc Wed Nov 10 10:44:42 2010
@@ -25,6 +25,7 @@
#include <gtest/gtest.h>
+#include <dns/rcode.h>
#include <dns/name.h>
#include <dns/message.h>
#include <dns/tests/unittest_util.h>
@@ -133,10 +134,7 @@
}
::testing::AssertionResult
-UnitTestUtil::matchWireData(const char* dataexp1 UNUSED_PARAM,
- const char* lenexp1 UNUSED_PARAM,
- const char* dataexp2 UNUSED_PARAM,
- const char* lenexp2 UNUSED_PARAM,
+UnitTestUtil::matchWireData(const char*, const char*, const char*, const char*,
const void* data1, size_t len1,
const void* data2, size_t len2)
{
@@ -163,8 +161,7 @@
}
::testing::AssertionResult
-UnitTestUtil::matchName(const char* nameexp1 UNUSED_PARAM,
- const char* nameexp2 UNUSED_PARAM,
+UnitTestUtil::matchName(const char*, const char*,
const isc::dns::Name& name1,
const isc::dns::Name& name2)
{
@@ -191,6 +188,7 @@
{
message.clear(Message::RENDER);
message.setOpcode(opcode);
+ message.setRcode(Rcode::NOERROR());
message.setQid(qid);
message.addQuestion(Question(name, rrclass, rrtype));
}
Modified: branches/trac327/src/lib/dns/util/sha1.cc
==============================================================================
--- branches/trac327/src/lib/dns/util/sha1.cc (original)
+++ branches/trac327/src/lib/dns/util/sha1.cc Wed Nov 10 10:44:42 2010
@@ -312,8 +312,7 @@
* sha Error Code.
*
*/
-static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte)
-{
+static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte) {
int i;
SHA1PadMessage(context, Pad_Byte);
/* message may be sensitive, clear it out */
@@ -350,8 +349,7 @@
* Nothing.
*
*/
-static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte)
-{
+static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte) {
/*
* Check to see if the current message block is too small to hold
* the initial padding bits and length. If so, we will pad the
Modified: branches/trac327/src/lib/exceptions/exceptions.cc
==============================================================================
--- branches/trac327/src/lib/exceptions/exceptions.cc (original)
+++ branches/trac327/src/lib/exceptions/exceptions.cc Wed Nov 10 10:44:42 2010
@@ -23,8 +23,7 @@
namespace isc {
const char*
-Exception::what() const throw()
-{
+Exception::what() const throw() {
const char* whatstr = "isc::Exception";
// XXX: even though it's very unlikely that c_str() throws an exception,
Modified: branches/trac327/src/lib/exceptions/exceptions.h
==============================================================================
--- branches/trac327/src/lib/exceptions/exceptions.h (original)
+++ branches/trac327/src/lib/exceptions/exceptions.h Wed Nov 10 10:44:42 2010
@@ -103,20 +103,25 @@
const std::string what_;
};
-///
/// \brief A generic exception that is thrown if a parameter given
/// to a method would refer to or modify out-of-range data.
-///
class OutOfRange : public Exception {
public:
OutOfRange(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) {}
};
-///
+/// \brief A generic exception that is thrown if a parameter given
+/// to a method or function is considered invalid and no other specific
+/// exceptions are suitable to describe the error.
+class InvalidParameter : public Exception {
+public:
+ InvalidParameter(const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) {}
+};
+
/// \brief A generic exception that is thrown if a parameter given
/// to a method is considered invalid in that context.
-///
class BadValue : public Exception {
public:
BadValue(const char* file, size_t line, const char* what) :
Modified: branches/trac327/src/lib/exceptions/tests/run_unittests.cc
==============================================================================
--- branches/trac327/src/lib/exceptions/tests/run_unittests.cc (original)
+++ branches/trac327/src/lib/exceptions/tests/run_unittests.cc Wed Nov 10 10:44:42 2010
@@ -17,8 +17,7 @@
#include <gtest/gtest.h>
int
-main(int argc, char* argv[])
-{
+main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
return (RUN_ALL_TESTS());
}
Modified: branches/trac327/src/lib/python/isc/Makefile.am
==============================================================================
--- branches/trac327/src/lib/python/isc/Makefile.am (original)
+++ branches/trac327/src/lib/python/isc/Makefile.am Wed Nov 10 10:44:42 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: branches/trac327/src/lib/python/isc/cc/Makefile.am
==============================================================================
--- branches/trac327/src/lib/python/isc/cc/Makefile.am (original)
+++ branches/trac327/src/lib/python/isc/cc/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
python_PYTHON = __init__.py data.py session.py message.py
Modified: branches/trac327/src/lib/python/isc/cc/data.py
==============================================================================
--- branches/trac327/src/lib/python/isc/cc/data.py (original)
+++ branches/trac327/src/lib/python/isc/cc/data.py Wed Nov 10 10:44:42 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: branches/trac327/src/lib/python/isc/cc/session.py
==============================================================================
--- branches/trac327/src/lib/python/isc/cc/session.py (original)
+++ branches/trac327/src/lib/python/isc/cc/session.py Wed Nov 10 10:44:42 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: branches/trac327/src/lib/python/isc/cc/tests/session_test.py
==============================================================================
--- branches/trac327/src/lib/python/isc/cc/tests/session_test.py (original)
+++ branches/trac327/src/lib/python/isc/cc/tests/session_test.py Wed Nov 10 10:44:42 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: branches/trac327/src/lib/python/isc/config/Makefile.am
==============================================================================
--- branches/trac327/src/lib/python/isc/config/Makefile.am (original)
+++ branches/trac327/src/lib/python/isc/config/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
python_PYTHON = __init__.py ccsession.py cfgmgr.py config_data.py module_spec.py
Modified: branches/trac327/src/lib/python/isc/config/ccsession.py
==============================================================================
--- branches/trac327/src/lib/python/isc/config/ccsession.py (original)
+++ branches/trac327/src/lib/python/isc/config/ccsession.py Wed Nov 10 10:44:42 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: branches/trac327/src/lib/python/isc/config/cfgmgr.py
==============================================================================
--- branches/trac327/src/lib/python/isc/config/cfgmgr.py (original)
+++ branches/trac327/src/lib/python/isc/config/cfgmgr.py Wed Nov 10 10:44:42 2010
@@ -283,7 +283,10 @@
update_cmd = ccsession.create_command(ccsession.COMMAND_CONFIG_UPDATE,
conf_part)
seq = self.cc.group_sendmsg(update_cmd, module_name)
- answer, env = self.cc.group_recvmsg(False, seq)
+ try:
+ answer, env = self.cc.group_recvmsg(False, seq)
+ except isc.cc.SessionTimeout:
+ answer = ccsession.create_answer(1, "Timeout waiting for answer from " + module_name)
else:
conf_part = data.set(self.config.data, module_name, {})
data.merge(conf_part[module_name], cmd[1])
@@ -292,7 +295,10 @@
conf_part[module_name])
seq = self.cc.group_sendmsg(update_cmd, module_name)
# replace 'our' answer with that of the module
- answer, env = self.cc.group_recvmsg(False, seq)
+ try:
+ answer, env = self.cc.group_recvmsg(False, seq)
+ except isc.cc.SessionTimeout:
+ answer = ccsession.create_answer(1, "Timeout waiting for answer from " + module_name)
if answer:
rcode, val = ccsession.parse_answer(answer)
if rcode == 0:
@@ -313,15 +319,19 @@
update_cmd = ccsession.create_command(ccsession.COMMAND_CONFIG_UPDATE,
self.config.data[module])
seq = self.cc.group_sendmsg(update_cmd, module)
- answer, env = self.cc.group_recvmsg(False, seq)
- if answer == None:
+ try:
+ answer, env = self.cc.group_recvmsg(False, seq)
+ if answer == None:
+ got_error = True
+ err_list.append("No answer message from " + module)
+ else:
+ rcode, val = ccsession.parse_answer(answer)
+ if rcode != 0:
+ got_error = True
+ err_list.append(val)
+ except isc.cc.SessionTimeout:
got_error = True
- err_list.append("No answer message from " + module)
- else:
- rcode, val = ccsession.parse_answer(answer)
- if rcode != 0:
- got_error = True
- err_list.append(val)
+ err_list.append("CC Timeout waiting on answer message from " + module)
if not got_error:
self.write_config()
return ccsession.create_answer(0)
@@ -394,8 +404,13 @@
"""Runs the configuration manager."""
self.running = True
while (self.running):
+ # we just wait eternally for any command here, so disable
+ # timeouts for this specific recv
+ self.cc.set_timeout(0)
msg, env = self.cc.group_recvmsg(False)
- # ignore 'None' value (current result of timeout)
+ # and set it back to whatever we default to
+ self.cc.set_timeout(isc.cc.Session.MSGQ_DEFAULT_TIMEOUT)
+ # ignore 'None' value (even though they should not occur)
# and messages that are answers to questions we did
# not ask
if msg is not None and not 'result' in msg:
Modified: branches/trac327/src/lib/python/isc/config/module_spec.py
==============================================================================
--- branches/trac327/src/lib/python/isc/config/module_spec.py (original)
+++ branches/trac327/src/lib/python/isc/config/module_spec.py Wed Nov 10 10:44:42 2010
@@ -316,7 +316,9 @@
item_name = spec['item_name']
item_optional = spec['item_optional']
- if item_name in data:
+ if not data and item_optional:
+ return True
+ elif item_name in data:
return _validate_item(spec, full, data[item_name], errors)
elif full and not item_optional:
if errors != None:
Modified: branches/trac327/src/lib/python/isc/config/tests/Makefile.am
==============================================================================
--- branches/trac327/src/lib/python/isc/config/tests/Makefile.am (original)
+++ branches/trac327/src/lib/python/isc/config/tests/Makefile.am Wed Nov 10 10:44:42 2010
@@ -10,7 +10,7 @@
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python \
- CONFIG_TESTDATA_PATH=$(abs_top_srcdir)/src/lib/config/testdata \
- CONFIG_WR_TESTDATA_PATH=$(abs_top_builddir)/src/lib/config/testdata \
+ CONFIG_TESTDATA_PATH=$(abs_top_srcdir)/src/lib/config/tests/testdata \
+ CONFIG_WR_TESTDATA_PATH=$(abs_top_builddir)/src/lib/config/tests/testdata \
$(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
done
Modified: branches/trac327/src/lib/python/isc/config/tests/ccsession_test.py
==============================================================================
--- branches/trac327/src/lib/python/isc/config/tests/ccsession_test.py (original)
+++ branches/trac327/src/lib/python/isc/config/tests/ccsession_test.py Wed Nov 10 10:44:42 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: branches/trac327/src/lib/python/isc/config/tests/cfgmgr_test.py
==============================================================================
--- branches/trac327/src/lib/python/isc/config/tests/cfgmgr_test.py (original)
+++ branches/trac327/src/lib/python/isc/config/tests/cfgmgr_test.py Wed Nov 10 10:44:42 2010
@@ -255,6 +255,7 @@
self.fake_session.get_message(self.name, None))
self.assertEqual(len(self.fake_session.message_queue), 0)
+ self.fake_session.group_sendmsg(None, 'ConfigManager')
self._handle_msg_helper({ "command": [ "set_config", [ ] ] },
{'result': [1, 'Wrong number of arguments']} )
self._handle_msg_helper({ "command": [ "set_config", [ self.name, { "test": 125 }] ] },
Modified: branches/trac327/src/lib/python/isc/config/tests/unittest_fakesession.py
==============================================================================
--- branches/trac327/src/lib/python/isc/config/tests/unittest_fakesession.py (original)
+++ branches/trac327/src/lib/python/isc/config/tests/unittest_fakesession.py Wed Nov 10 10:44:42 2010
@@ -15,6 +15,15 @@
# $Id$
+import isc
+
+class WouldBlockForever(Exception):
+ """
+ This is thrown by the FakeModuleCCSession if it would need
+ to block forever for incoming message.
+ """
+ pass
+
#
# We can probably use a more general version of this
#
@@ -24,6 +33,10 @@
# each entry is of the form [ channel, instance, message ]
self.message_queue = []
self._socket = "ok we just need something not-None here atm"
+ # if self.timeout is set to anything other than 0, and
+ # the message_queue is empty when receive is called, throw
+ # a SessionTimeout
+ self._timeout = 0
def group_subscribe(self, group_name, instance_name = None):
if not group_name in self.subscriptions:
@@ -58,12 +71,21 @@
if 'group' in env:
self.message_queue.append([ env['group'], None, msg])
- def group_recvmsg(self, blocking, seq = None):
+ def group_recvmsg(self, nonblock=True, seq = None):
for qm in self.message_queue:
- if qm[0] in self.subscriptions and (qm[1] == None or qm[1] in self.subscriptions[qm[0]]):
+ if qm[0] in self.subscriptions and (qm[1] == None or qm[1] in
+ self.subscriptions[qm[0]]):
self.message_queue.remove(qm)
return qm[2], {'group': qm[0], 'from': qm[1]}
- return None, None
+ if self._timeout == 0:
+ if nonblock:
+ return None, None
+ else:
+ raise WouldBlockForever(
+ "Blocking read without timeout and no message ready")
+ else:
+ raise isc.cc.SessionTimeout("Timeout set but no data to "
+ "return to group_recvmsg()")
def get_message(self, channel, target = None):
for qm in self.message_queue:
@@ -75,4 +97,9 @@
def close(self):
# need to pass along somehow that this function has been called,
self._socket = "closed"
- pass
+
+ def set_timeout(self, timeout):
+ self._timeout = timeout
+
+ def get_timeout(self):
+ return self._timeout
Modified: branches/trac327/src/lib/python/isc/datasrc/master.py
==============================================================================
--- branches/trac327/src/lib/python/isc/datasrc/master.py (original)
+++ branches/trac327/src/lib/python/isc/datasrc/master.py Wed Nov 10 10:44:42 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: branches/trac327/src/lib/python/isc/dns/__init__.py
==============================================================================
--- branches/trac327/src/lib/python/isc/dns/__init__.py (original)
+++ branches/trac327/src/lib/python/isc/dns/__init__.py Wed Nov 10 10:44:42 2010
@@ -1,1 +1,1 @@
-from libdns_python_name import *
+from pydnspp import *
Modified: branches/trac327/src/lib/python/isc/log/Makefile.am
==============================================================================
--- branches/trac327/src/lib/python/isc/log/Makefile.am (original)
+++ branches/trac327/src/lib/python/isc/log/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
python_PYTHON = __init__.py log.py
Modified: branches/trac327/src/lib/python/isc/log/log.py
==============================================================================
--- branches/trac327/src/lib/python/isc/log/log.py (original)
+++ branches/trac327/src/lib/python/isc/log/log.py Wed Nov 10 10:44:42 2010
@@ -19,6 +19,7 @@
To use, simply 'import isc.log.log' and log away!
"""
import os
+import sys
import syslog
import logging
import logging.handlers
@@ -31,47 +32,73 @@
'error' : logging.ERROR,
'critical' : logging.CRITICAL}
-
FORMATTER = logging.Formatter("%(name)s: %(levelname)s: %(message)s")
TIME_FORMATTER = logging.Formatter("%(asctime)s.%(msecs)03d %(name)s: %(levelname)s: %(message)s",
"%d-%b-%Y %H:%M:%S")
+def log_err(err_type, err_msg):
+ sys.stderr.write(err_type + ": " + "%s.\n" % str(err_msg)[str(err_msg).find(']')+1:])
+
+
class NSFileLogHandler(logging.handlers.RotatingFileHandler):
"""RotatingFileHandler: replace RotatingFileHandler with a custom handler"""
def __init__(self, filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=0):
- dir = os.path.split(filename)
- if not (os.path.exists(dir[0])):
- os.makedirs(dir[0])
- super(NSFileLogHandler, self).__init__(filename, mode, maxBytes,
+ abs_file_name = self._get_abs_file_path(filename)
+ """Create log directory beforehand, because the underlying logging framework won't
+ create non-exsiting log directory on writing logs.
+ """
+ if not (os.path.exists(os.path.dirname(abs_file_name))):
+ os.makedirs(os.path.dirname(abs_file_name))
+ super(NSFileLogHandler, self).__init__(abs_file_name, mode, maxBytes,
backupCount, encoding, delay)
+
+ def handleError(self, record):
+ """Overwrite handleError to provide more user-friendly error messages"""
+ if logging.raiseExceptions:
+ ei = sys.exc_info()
+ if (ei[1]):
+ sys.stderr.write("[b10-logging] : " + str(ei[1]))
+
+ def _get_abs_file_path(self, file_name):
+ """ Get absolute file path"""
+ # For a bare filename, log_dir will be set the current directory.
+ if not os.path.dirname(file_name):
+ abs_file_dir = os.getcwd()
+ else:
+ abs_file_dir = os.path.abspath(os.path.dirname(file_name))
+ abs_file_name = os.path.join(abs_file_dir, os.path.basename(file_name))
+ return abs_file_name
def shouldRollover(self, record):
"""Rewrite RotatingFileHandler.shouldRollover.
If the log file is deleted at runtime, a new file will be created.
"""
- dfn = self.baseFilename
+ dfn = self.baseFilename
if (self.stream) and (not os.path.exists(dfn)): #Does log file exist?
- self.stream.close()
- dir = os.path.split(dfn)
- if not (os.path.exists(dir[0])): #Does log subdirectory exist?
- os.makedirs(dir[0])
+ self.stream = None
+ """ Log directory may be deleted while bind10 running or updated with a
+ non-existing directory. Need to create log directory beforehand, because
+ the underlying logging framework won't create non-exsiting log directory
+ on writing logs.
+ """
+ if not (os.path.exists(os.path.dirname(dfn))): #Does log subdirectory exist?
+ os.makedirs(os.path.dirname(dfn))
self.stream = self._open()
return super(NSFileLogHandler, self).shouldRollover(record)
def update_config(self, file_name, backup_count, max_bytes):
"""Update RotatingFileHandler configuration.
-
- If the file path does not exist, we will use the old log file.
+ Changes will be picked up in the next call to shouldRollover().
+
input:
log file name
max backup count
predetermined log file size
"""
- dir = os.path.split(file_name)
- if (os.path.exists(dir[0])):
- self.baseFilename = file_name
+ abs_file_name = self._get_abs_file_path(file_name)
+ self.baseFilename = abs_file_name
self.maxBytes = max_bytes
self.backupCount = backup_count
@@ -162,8 +189,9 @@
try:
self._file_handler = NSFileLogHandler(filename = log_file,
maxBytes = max_bytes, backupCount = backup_count)
- except IOError:
+ except (IOError, OSError) as e:
self._file_handler = None
+ log_err("[b10-logging] Add file handler fail", str(e))
return
self._file_handler.setFormatter(TIME_FORMATTER)
self.addHandler(self._file_handler)
@@ -244,6 +272,9 @@
logger.log_message('info', "We have a %s", "mysterious problem").
"""
logLevel = LEVELS.get(level, logging.NOTSET)
- self.log(logLevel, msg, *args, **kwargs)
-
-
+ try:
+ self.log(logLevel, msg, *args, **kwargs)
+ except (TypeError, KeyError) as e:
+ sys.stderr.write("[b10-logging] Log message fail %s\n" % (str(e)))
+
+
Modified: branches/trac327/src/lib/python/isc/log/tests/log_test.py
==============================================================================
--- branches/trac327/src/lib/python/isc/log/tests/log_test.py (original)
+++ branches/trac327/src/lib/python/isc/log/tests/log_test.py Wed Nov 10 10:44:42 2010
@@ -20,6 +20,7 @@
from isc.log.log import *
import unittest
import os
+import sys
import tempfile
@@ -46,21 +47,48 @@
self.handler.shouldRollover(record)
self.assertTrue(os.path.exists(self.FILE_LOG1.name))
+ def test_get_absolute_file_path(self):
+ abs_file_name = self.handler._get_abs_file_path(self.FILE_LOG1.name)
+ self.assertEqual(abs_file_name, self.FILE_LOG1.name)
+ # test bare filename
+ file_name1 = "bind10.py"
+ abs_file_name = self.handler._get_abs_file_path(file_name1)
+ self.assertEqual(abs_file_name, os.path.join(os.getcwd(), file_name1))
+ # test relative path
+ file_name2 = "./bind10.py"
+ abs_file_name = self.handler._get_abs_file_path(file_name2)
+ self.assertEqual(abs_file_name, os.path.join(os.getcwd(), os.path.basename(file_name2)))
+
def test_update_config(self):
self.handler.update_config(self.FILE_LOG2.name, 3, 512)
self.assertEqual(self.handler.baseFilename, self.FILE_LOG2.name)
self.assertEqual(self.handler.maxBytes, 512)
self.assertEqual(self.handler.backupCount, 3)
- dir = os.path.split(self.FILE_LOG3.name)
- path = dir[0] + "path_not_exists"
- update_file = os.path.join(path, dir[1])
-
- if not os.path.exists(path):
- self.handler.update_config(update_file, 4, 1024)
- self.assertEqual(self.handler.baseFilename, self.FILE_LOG2.name)
- self.assertEqual(self.handler.maxBytes, 1024)
- self.assertEqual(self.handler.backupCount, 4)
+ # check the existence of new log file.
+ # emit() will call shouldRollover() to update the log file
+ if(os.path.exists(self.FILE_LOG2.name)):
+ os.remove(self.FILE_LOG2.name)
+ record = logging.LogRecord(None, None, "", 0, "rotate file handler", (), None, None)
+ self.handler.emit(record)
+ self.assertTrue(os.path.exists(self.FILE_LOG2.name))
+
+ def test_handle_Error(self):
+ if(os.path.exists(self.FILE_LOG3.name)):
+ os.remove(self.FILE_LOG3.name)
+ # redirect error message to file
+ savederr = sys.stderr
+ errfd = open(self.FILE_LOG3.name, 'w+')
+ sys.stderr = errfd
+ record = logging.LogRecord(None, None, "", 0, "record message", (), None, None)
+ try:
+ raise ValueError("ValueError")
+ except ValueError:
+ self.handler.handleError(record)
+
+ self.assertEqual("[b10-logging] : ValueError", errfd.read())
+ sys.stderr = savederr
+ errfd.close()
def tearDown(self):
self.handler.flush()
@@ -78,50 +106,46 @@
self.assertEqual(sysLevel, syslog.LOG_ERR)
def test_emit(self):
- record = logging.LogRecord(None, None, "", 0, "syslog handler", (), None, None)
+ syslog_message = "bind10 syslog testing"
+ record = logging.LogRecord(None, None, "", 0, syslog_message, (), None, None)
self.handler.emit(record)
-
class TestLogging(unittest.TestCase):
def setUp(self):
- self.FILE_STREAM_LOG1= tempfile.NamedTemporaryFile(mode='w',
+ self.FILE_STREAM_LOG1 = tempfile.NamedTemporaryFile(mode='w',
prefix="b10",
delete=True)
- self.FILE_STREAM_LOG2= tempfile.NamedTemporaryFile(mode='w',
+ self.FILE_STREAM_LOG2 = tempfile.NamedTemporaryFile(mode='w',
prefix="b10",
delete=True)
- self.FILE_STREAM_LOG3= tempfile.NamedTemporaryFile(mode='w',
+ self.FILE_STREAM_LOG3 = tempfile.NamedTemporaryFile(mode='w',
prefix="b10",
delete=True)
self.file_stream_logger = NSLogger('File_Stream_Logger',
self.FILE_STREAM_LOG1.name,
'debug', 5, 1024, True)
self.syslog_logger = NSLogger('SysLogger', '', 'info', 5, 1024, False)
+ self.stderr_bak = sys.stderr
+ sys.stderr = open(os.devnull, 'w')
def test_logging_init(self):
self.assertNotEqual(self.file_stream_logger._file_handler, None)
self.assertNotEqual(self.file_stream_logger._stream_handler, None)
self.assertEqual(self.file_stream_logger._syslog_handler, None)
- ret = self.file_stream_logger._file_handler in self.file_stream_logger.handlers
- self.assertTrue(ret)
- ret = self.file_stream_logger._stream_handler in self.file_stream_logger.handlers
- self.assertTrue(ret)
- ret = self.file_stream_logger._syslog_handler in self.file_stream_logger.handlers
- self.assertFalse(ret)
+ self.assertIn(self.file_stream_logger._file_handler, self.file_stream_logger.handlers)
+ self.assertIn(self.file_stream_logger._stream_handler, self.file_stream_logger.handlers)
+ self.assertNotIn(self.file_stream_logger._syslog_handler, self.file_stream_logger.handlers)
logLevel = LEVELS.get('debug', logging.NOTSET)
self.assertEqual(self.file_stream_logger.getEffectiveLevel(), logLevel)
self.assertEqual(self.syslog_logger._file_handler, None)
self.assertEqual(self.syslog_logger._stream_handler, None)
self.assertNotEqual(self.syslog_logger._syslog_handler, None)
- ret = self.syslog_logger._file_handler in self.syslog_logger.handlers
- self.assertFalse(ret)
- ret = self.syslog_logger._stream_handler in self.syslog_logger.handlers
- self.assertFalse(ret)
- ret = self.syslog_logger._syslog_handler in self.syslog_logger.handlers
- self.assertTrue(ret)
+ self.assertNotIn(self.syslog_logger._file_handler, self.syslog_logger.handlers)
+ self.assertNotIn(self.syslog_logger._stream_handler, self.syslog_logger.handlers)
+ self.assertIn(self.syslog_logger._syslog_handler, self.syslog_logger.handlers)
logLevel = LEVELS.get('info', logging.NOTSET)
self.assertEqual(self.syslog_logger.getEffectiveLevel(), logLevel)
@@ -131,41 +155,52 @@
self.syslog_logger.removeHandler(self.syslog_logger._file_handler)
self.syslog_logger._add_rotate_handler('', 5, 1024)
- ret = self.syslog_logger._file_handler in self.syslog_logger.handlers
- self.assertFalse(ret)
+ self.assertNotIn(self.syslog_logger._file_handler, self.syslog_logger.handlers)
self.syslog_logger._add_rotate_handler(self.FILE_STREAM_LOG1.name, 5, 1024)
- ret = self.syslog_logger._file_handler in self.syslog_logger.handlers
- self.assertTrue(ret)
+ self.assertIn(self.syslog_logger._file_handler, self.syslog_logger.handlers)
+
+ # test IOError exception
+ self.syslog_logger.removeHandler(self.syslog_logger._file_handler)
+ log_file = self.FILE_STREAM_LOG1.name + '/logfile'
+ self.syslog_logger._add_rotate_handler(log_file, 5, 1024)
+ self.assertNotIn(self.syslog_logger._file_handler, self.syslog_logger.handlers)
def test_add_stream_handler(self):
if(self.file_stream_logger._stream_handler in self.file_stream_logger.handlers):
self.file_stream_logger.removeHandler(self.file_stream_logger._stream_handler)
self.file_stream_logger._add_stream_handler()
- ret = self.file_stream_logger._stream_handler in self.file_stream_logger.handlers
- self.assertTrue(ret)
+ self.assertIn(self.file_stream_logger._stream_handler, self.file_stream_logger.handlers)
def test_add_syslog_handler(self):
if(self.syslog_logger._syslog_handler in self.syslog_logger.handlers):
self.syslog_logger.removeHandler(self.syslog_logger._syslog_handler)
self.syslog_logger._add_syslog_handler()
- ret = self.syslog_logger._syslog_handler in self.syslog_logger.handlers
- self.assertTrue(ret)
+ self.assertIn(self.syslog_logger._syslog_handler, self.syslog_logger.handlers)
def test_update_rotate_handler(self):
self.file_stream_logger._update_rotate_handler(self.FILE_STREAM_LOG2.name, 4, 1024)
- ret = self.file_stream_logger._file_handler in self.file_stream_logger.handlers
- self.assertTrue(ret)
+ self.assertIn(self.file_stream_logger._file_handler, self.file_stream_logger.handlers)
self.file_stream_logger._update_rotate_handler('', 5, 1024)
- ret = self.file_stream_logger._file_handler in self.file_stream_logger.handlers
- self.assertFalse(ret)
+ self.assertNotIn(self.file_stream_logger._file_handler, self.file_stream_logger.handlers)
self.file_stream_logger._update_rotate_handler(self.FILE_STREAM_LOG1.name, 4, 1024)
- ret = self.file_stream_logger._file_handler in self.file_stream_logger.handlers
- self.assertTrue(ret)
+ self.assertIn(self.file_stream_logger._file_handler, self.file_stream_logger.handlers)
+
+ def test_get_config(self):
+ config_data = {'log_file' : self.FILE_STREAM_LOG1.name,
+ 'log_severity' : 'critical',
+ 'log_versions' : 4,
+ 'log_max_bytes' : 1024}
+ self.file_stream_logger._get_config(config_data)
+ self.assertEqual(self.file_stream_logger._log_file, self.FILE_STREAM_LOG1.name)
+ self.assertEqual(self.file_stream_logger._severity, 'critical')
+ self.assertEqual(self.file_stream_logger._versions, 4)
+ self.assertEqual(self.file_stream_logger._max_bytes, 1024)
+
def test_update_config(self):
update_config = {'log_file' : self.FILE_STREAM_LOG1.name,
@@ -183,15 +218,20 @@
'log_max_bytes' : 1024}
self.file_stream_logger.update_config(update_config)
self.file_stream_logger.log_message('debug', 'debug message')
- self.file_stream_logger.log_message('info', 'info message')
self.file_stream_logger.log_message('warning', 'warning message')
self.file_stream_logger.log_message('error', 'error message')
+ #test non-exist log level
+ self.assertRaises(None, self.file_stream_logger.log_message('not-exist', 'not exist message'))
+ #test log_message KeyError exception
+ self.assertRaises(None, self.file_stream_logger.log_message('critical', 'critical message', extra=['message', 'asctime']))
self.assertTrue(os.path.exists(self.FILE_STREAM_LOG3.name))
def tearDown(self):
self.FILE_STREAM_LOG1.close()
self.FILE_STREAM_LOG2.close()
self.FILE_STREAM_LOG3.close()
+ sys.stderr.flush();
+ sys.stderr = self.stderr_bak
if __name__ == '__main__':
unittest.main()
Modified: branches/trac327/src/lib/python/isc/notify/Makefile.am
==============================================================================
--- branches/trac327/src/lib/python/isc/notify/Makefile.am (original)
+++ branches/trac327/src/lib/python/isc/notify/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
python_PYTHON = __init__.py notify_out.py
Modified: branches/trac327/src/lib/python/isc/notify/notify_out.py
==============================================================================
--- branches/trac327/src/lib/python/isc/notify/notify_out.py (original)
+++ branches/trac327/src/lib/python/isc/notify/notify_out.py Wed Nov 10 10:44:42 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: branches/trac327/src/lib/python/isc/notify/tests/notify_out_test.py
==============================================================================
--- branches/trac327/src/lib/python/isc/notify/tests/notify_out_test.py (original)
+++ branches/trac327/src/lib/python/isc/notify/tests/notify_out_test.py Wed Nov 10 10:44:42 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: branches/trac327/src/lib/xfr/Makefile.am
==============================================================================
--- branches/trac327/src/lib/xfr/Makefile.am (original)
+++ branches/trac327/src/lib/xfr/Makefile.am Wed Nov 10 10:44:42 2010
@@ -1,8 +1,12 @@
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
+AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CXXFLAGS = $(B10_CXXFLAGS) -Wno-strict-aliasing
AM_CXXFLAGS += -Wno-unused-parameter # see src/lib/cc/Makefile.am
+if USE_CLANGPP
+AM_CXXFLAGS += -Wno-error
+endif
CLEANFILES = *.gcno *.gcda
Modified: branches/trac327/src/lib/xfr/fd_share.cc
==============================================================================
--- branches/trac327/src/lib/xfr/fd_share.cc (original)
+++ branches/trac327/src/lib/xfr/fd_share.cc Wed Nov 10 10:44:42 2010
@@ -93,7 +93,7 @@
if (recvmsg(sock, &msghdr, 0) < 0) {
free(msghdr.msg_control);
- return (-1);
+ return (XFR_FD_RECEIVE_FAIL);
}
const struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msghdr);
int fd = -1;
Modified: branches/trac327/src/lib/xfr/fd_share.h
==============================================================================
--- branches/trac327/src/lib/xfr/fd_share.h (original)
+++ branches/trac327/src/lib/xfr/fd_share.h Wed Nov 10 10:44:42 2010
@@ -20,12 +20,16 @@
namespace isc {
namespace xfr {
+/// Failed to receive xfr socket descriptor "fd" on unix domain socket 'sock'
+const int XFR_FD_RECEIVE_FAIL = -2;
+
// Receive socket descriptor on unix domain socket 'sock'.
// Returned value is the socket descriptor received.
+// Returned XFR_FD_RECEIVE_FAIL if failed to receive xfr socket descriptor
// Errors are indicated by a return value of -1.
int recv_fd(const int sock);
-// Send socket descriptor "fd" to server over unix domain socket 'sock',
+// Send socket descriptor "fd" to server over unix domain socket 'sock',
// the connection from socket 'sock' to unix domain server should be established first.
// Errors are indicated by a return value of -1.
int send_fd(const int sock, const int fd);
@@ -35,6 +39,6 @@
#endif
-// Local Variables:
+// Local Variables:
// mode: c++
-// End:
+// End:
Modified: branches/trac327/src/lib/xfr/fdshare_python.cc
==============================================================================
--- branches/trac327/src/lib/xfr/fdshare_python.cc (original)
+++ branches/trac327/src/lib/xfr/fdshare_python.cc Wed Nov 10 10:44:42 2010
@@ -22,8 +22,9 @@
#include <xfr/fd_share.h>
+
static PyObject*
-fdshare_recv_fd(PyObject *self UNUSED_PARAM, PyObject *args) {
+fdshare_recv_fd(PyObject*, PyObject* args) {
int sock, fd;
if (!PyArg_ParseTuple(args, "i", &sock)) {
return (NULL);
@@ -33,7 +34,7 @@
}
static PyObject*
-fdshare_send_fd(PyObject *self UNUSED_PARAM, PyObject *args) {
+fdshare_send_fd(PyObject*, PyObject* args) {
int sock, fd, result;
if (!PyArg_ParseTuple(args, "ii", &sock, &fd)) {
return (NULL);
@@ -63,8 +64,20 @@
PyMODINIT_FUNC
PyInit_libxfr_python(void) {
- PyObject *mod = PyModule_Create(&bind10_fdshare_python);
+ PyObject* mod = PyModule_Create(&bind10_fdshare_python);
if (mod == NULL) {
+ return (NULL);
+ }
+
+ PyObject* XFR_FD_RECEIVE_FAIL = Py_BuildValue("i", isc::xfr::XFR_FD_RECEIVE_FAIL);
+ if (XFR_FD_RECEIVE_FAIL == NULL) {
+ Py_XDECREF(mod);
+ return (NULL);
+ }
+ int ret = PyModule_AddObject(mod, "XFR_FD_RECEIVE_FAIL", XFR_FD_RECEIVE_FAIL);
+ if (-1 == ret) {
+ Py_XDECREF(XFR_FD_RECEIVE_FAIL);
+ Py_XDECREF(mod);
return (NULL);
}
Modified: branches/trac327/src/lib/xfr/python_xfr.cc
==============================================================================
--- branches/trac327/src/lib/xfr/python_xfr.cc (original)
+++ branches/trac327/src/lib/xfr/python_xfr.cc Wed Nov 10 10:44:42 2010
@@ -28,8 +28,7 @@
using namespace isc::xfr;
using namespace boost::python;
-BOOST_PYTHON_MODULE(bind10_xfr)
-{
+BOOST_PYTHON_MODULE(bind10_xfr) {
def("recv_fd", &recv_fd);
def("send_fd", &send_fd);
}
Modified: branches/trac327/src/lib/xfr/xfrout_client.cc
==============================================================================
--- branches/trac327/src/lib/xfr/xfrout_client.cc (original)
+++ branches/trac327/src/lib/xfr/xfrout_client.cc Wed Nov 10 10:44:42 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