BIND 10 trac1605, updated. ba1bfc79c7079e9c0886d542229c917d305695d9 Merge branch 'master' into trac1605
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Mar 2 10:19:40 UTC 2012
The branch, trac1605 has been updated
via ba1bfc79c7079e9c0886d542229c917d305695d9 (commit)
via 70778ebed8f5d0af186460600facc563865bafe8 (commit)
via ef1eba02e4cf550e48e7318702cff6d67c1ec82e (commit)
via ee3e3d95c2554eed560ae6fea8f24864d0f32074 (commit)
via d2e2cb97e821844dc430ef1e47d13d618c06d9fb (commit)
via ea85b4abd01332057c8a8a50e729baf444baaaca (commit)
via d0111f488addd8cf0f4a7217ce09a91e68cc04cc (commit)
via 03f679c989087d9d4a5e403bf37b2c99ad7c5ecd (commit)
via dd519159e091b7cc977b47692a45800157ed65ea (commit)
via 103b3ba8ad4891afa8f808fd9b1187983737a0b6 (commit)
via fbe90b8b726e59ec1cddd5338850c7f744340759 (commit)
via 9cabc799f2bf9a3579dae7f1f5d5467c8bb1aa40 (commit)
via 75ff883128aa4a2e4bd003342a2d84c216418e00 (commit)
via 3e173f46ee0d807f752ffb88d908c7ca601d0c3a (commit)
via 548aac884cccb2c18420f3a14d1736a904c096c6 (commit)
via e85922d37b1f4b43db76b41286268af4d8649288 (commit)
via c0a44c70c4a2e0dce3792bbb7f9ca15938128633 (commit)
via 5900df9c41a9ab0837cd25667cf6a371bd7e850f (commit)
via dbfaad4a2ce1f682267373b323a293e365bc4cc0 (commit)
via fbc79ee7d2f1a79f6388939beccaaf50dde0865e (commit)
via e5d53f4bb27024759f8712af254998c9dfa48f7a (commit)
via 11b5709d5a2e18ed0f83c291ec684a46d94609ff (commit)
via 055622f347c9e5beb43a5145c82a4f4a54e89d4b (commit)
via a9d6dd7cab00acd5379309d94ecb8b088ca3d295 (commit)
via a756c801315d320a855f312da4cad370e52371e3 (commit)
via e202628c6950839aaa6d318ea7a08b4f596499c0 (commit)
via 7b92c815b458b3fb4011fede59b787391bec7058 (commit)
via a7f978695cb84f9be3dd4ca4ff819c85d4477746 (commit)
via 4724623b5fd7748dac9fd291e6661ab94780fbb6 (commit)
via 36601beb98e8f746156ec430cc54ee9f03db2fe7 (commit)
via c257c2e0301a0605bd038e52e4df72734ccd92dc (commit)
via 62c19c0fdfd14b00dc515852731211f951c75201 (commit)
via 39b898c33b05f9936f9c822dfd0f90bfa2089369 (commit)
via 2d0b7b1cbf42fd7a92e09b8b3d37752829ce65b3 (commit)
via 045edb53054c1e4acd985430f6b21b605348e959 (commit)
via c983a484207a8af30fbe90dcf2b2b4078ae8ff09 (commit)
via 1c1308a191d8e151abb28acbb22db033764acb67 (commit)
via 107995cf3a709e71baab30a82eafa6d7850750fc (commit)
via abb524e9809b09307c95c82a09d0d57bea652401 (commit)
via 6ebbb5d27d5a52d5f5e5caf89d3514a5135f07c7 (commit)
via 24347dec2bc47e3112a2b8103a8570ffc4a8ade5 (commit)
via b98523c1260637cb33436964dc18e9763622a242 (commit)
via 3b53272a6f77fa03e34f298ec06ec31de7cd32e1 (commit)
via c9f943875b76aba6204609dcd70eac4a5fb60b4e (commit)
via b6c08e3ac581afd21e033808bdcf7c96f83f0ef4 (commit)
via c2d13346d9c16ba018a4f154c6862c3f9b208a82 (commit)
via c8fe7f2e869938bee1b3283c55c99f9487b6995b (commit)
via b5ae5d8fe31c721fe63f6cfa7ef880cf27ffbb06 (commit)
via bdb2771f51482995116460fb6594ba69b13e725e (commit)
via 8684a411d7718a71ad9fb616f56b26436c4f03e5 (commit)
via 555c57669226bca31e961412fde174f04db876ab (commit)
via 04f9d8ebe54788a4f4f3aa7be7d50347a26565c0 (commit)
via 90e30a79b4fdfe52a70fbc72f9f84a8dd1968506 (commit)
via bb52e879ee7b68c162b5ad36648b9f2c0fc18f19 (commit)
via d125d7da8b990b238993f59353e8a11832785706 (commit)
via 3b8892835a95f7b17f93f5f3ca36c14da1a82363 (commit)
via ff013364643f9bfa736b2d23fec39ac35872d6ad (commit)
via c5ba45e293726f7642f6e081de16bc3b2daff98b (commit)
via 280742f34c2471024aebdf2736edf5570f1f3da2 (commit)
via 79e99b7285b93325862f80746d3a4d1b5938ca4d (commit)
via 5a7953933a49a0ddd4ee1feaddc908cd2285522d (commit)
via 064dd51b725493270dec9f1cd2c2b7164135ee6b (commit)
via d2b5da0a8146343bd6f72f3a145fc90be7888d18 (commit)
via 56b495e4bd8aeffed8642bfb6bb4802ba39a6277 (commit)
via 429c88cfe0483e0c67f4625481995c2510485792 (commit)
via ffd2c98603eb6db553d4cf18d2fd7ac29a62080f (commit)
via 16b39f3c2422a324963b67e136b07619209f869e (commit)
via d0fc36b1522db78541bbcc560f5f05cbefd4c5bc (commit)
via 5ba4c6e1f349f890200322b2e2d2ff0e5b179944 (commit)
via fceb2a853bf88760d5d5dec2a3e6f169799415ea (commit)
via 30d7686cb6e2fa64866c983e0cfb7b8fabedc7a2 (commit)
via 04aa12f01ec871e625fdb8ee1a07c387ab0a8f2a (commit)
via 4d472746171f67ac492234ef46a3bba43f55d5de (commit)
via cf00216570a36d2e3e688b197deea781bfbe7d8d (commit)
via e4b2c2633ebb3859286e9a4c19e97e17bcac41b3 (commit)
via 54c6617096e184520c918d308ccb31eb422046ec (commit)
via 883ef5b0d7466d080916f98af4ea6a94258ca655 (commit)
via 82bb5bc1cd3385d1bd0362c10308afb04a0e6914 (commit)
via b995540a1bd00fab2ca883c965edc954080be84c (commit)
via 38edb7e80589f08524b2753a7f29f1b6570ef4d6 (commit)
via 6f771b28eea25c693fe93a0e2379af924464a562 (commit)
via 389ceb4af859b59d18db14ef25a2bd3c2dd3ddd7 (commit)
via d18c04987a47c89aa3038d2bb0e99aa40b2f4e51 (commit)
via dad96d1c2aac267f2a11b9bdb7c83ce33c1a3f34 (commit)
via dbdf5296c3e98beb234ea1a161b004bed5e17a8a (commit)
via 8f5187d167219ac263ef940eb33923ef8a86e87b (commit)
via 6b3f5f252791b1c4b92589deaa3810e5e1eb867f (commit)
via a72ef46cca91d1718b2830e9d827040e6742d643 (commit)
via a11e3b2165821e9ca039196b12d70025845a5d22 (commit)
via b0d241f85f89f1d352f9b7a521b24d80107ffc20 (commit)
via fcbe40140a5e21ecf3ff078206afe1d68e945462 (commit)
via 07dd87ca1a14058c926497ec1c6ac61ffd3a41f2 (commit)
via 4085d32d3df744aaa7fe333032f978edbfc293c3 (commit)
via 462e2807bed92a21e8e2c070e49bab118323de6b (commit)
via 89f1ae8c2f2bb8829ae249414e9d8464b74b54be (commit)
via a9d3e3d62464b76c467c5cd8c0c229a75b5df5fc (commit)
via fb9060e5dccc2bd43ede4da3e0fe0733aa9cc6fa (commit)
via 464cada643779ceff4b3886aa5ccfec6605e2e92 (commit)
via 73b4d32109e8103c50f73dcd0c171930c3d9b322 (commit)
via cb1ca47492ba2c493f88a45725f91d1b53251023 (commit)
via 9d56a4097505b05e6a8e69ebb967a30416e39b41 (commit)
via 324be1acbdb7d432f4204d9cd6ed28e71a4fe7cf (commit)
via 6ca1f0da6b1e7dc488e5ff57b9ef041f4322ab67 (commit)
via 766508d03d1304dc4d66b814a7a21d160b3404c2 (commit)
via a4789bb27d209a54652bc2d7c6bf0992613c18df (commit)
via bc4fc1865977c94d4ad6eddf0cf96a7881a71536 (commit)
via f43af5ae2a1a904d1fa091d227f6d5cb1c580fa3 (commit)
via 5339fd0dc7b0a00f2e80754e7a1aed146440cff9 (commit)
via ccc2fb769ced7cef416b55d9074591022b8a673b (commit)
via 69360a12e78e7567f88dcd3079c9a56be534ea7d (commit)
via 38fdfa7720fd8e4c07aeb6aad4b7ac492d364b88 (commit)
via 71898b1a575fdefa01c657290b99ce7ba4693054 (commit)
via 920106980b5a66212397f5f699f2aac9e6d69cbc (commit)
via c430386cb0a163ffabc477d864635b4a21f2ef59 (commit)
via 900180e27ecac721a7ea7a5c3cff62230082a391 (commit)
via 6ec73d5de3e72a8d6adbb7e3bc353b68584b344f (commit)
via d6d42bcdfcc80b450b89937ffd5ba39b071b3f37 (commit)
via 0c0161c6e555e2c8b33b3291043727bc07324dc2 (commit)
via 6dc12fe4b4f751a8692bb2f577d178de458cbe31 (commit)
via c8f1422e69ad8cce8538c4f25a92ff225b4c2bb8 (commit)
via ce39e53bff7967573672e7172ec9d18b8bac4bab (commit)
via d1f64edacac52f7016b36381d93bec0275dde2cb (commit)
via f6d6f8d947ffe15b7aa0d1fe73adea1a1963f774 (commit)
via d7dc63b8a899e4e4c1be30e6f24ad113e02c6582 (commit)
via bd0a50e9b37f2e8c0030e905ef1889729df3ad5c (commit)
via 51146871aa0303636eff16193b66f61c80b9b7f8 (commit)
via 2ec4a397f113081c96807b3138549bd4bf1e2edf (commit)
via 5b301ea5a3aa71a5f82f0924713a7360c5f32f35 (commit)
via d121f511463ae2c469ec5ddeac1eb1ad60ca4cd9 (commit)
via 18eda2228413b1bd5764ad23dd5ab45a2d9c1809 (commit)
via eed7f24a8ee8ac1647a2998e38ce4766e48adb72 (commit)
via 19ba70c7cc3da462c70e8c4f74b321b8daad0100 (commit)
via ecd7dbe0f231c04d19eba3cd02ff513a23a9003a (commit)
via f472a687b70982f906bcc96900fdbc3ee8d36ff6 (commit)
via aa0318899f62fc3069572bb18bc6dd071bb8448d (commit)
via 5758984e174f25954af41dcf07979e2dfca12763 (commit)
via 5f4eb187db9895ceb2297711b6eef6fdcc520625 (commit)
via 4fea1ab53d06b5deaa87def247818f67839a9c9e (commit)
via 719a5941f529e8139cc2cf970d8903adf0741043 (commit)
via 6ab057e9726a30b87909a09026c797e99cd935d7 (commit)
via 0e8c2c9e572204db1b0586d6da94891168fd3a48 (commit)
via ac91cd885b563c71193cca2a33d6d11aa4a25927 (commit)
via 73506bcbd64a043f7e66c193a15b2d09a0a47bf0 (commit)
via f8cecc0e0625c40be6a44f24b8bcd0420e19946b (commit)
via c540444d6220133977db22de4c0adc116afd24a6 (commit)
via 66d14dd2dff194e69a12db0c89176c399ac5ce0b (commit)
via 30f55bf6510a4463d511a90c0b7deaeb046f80f2 (commit)
via 38742cb1561683410ab0f61388dbccd57e9f0f3c (commit)
via 451fd576615b47baa616d49ccaccedfae5595a76 (commit)
via a265a99016e8fe7943e1b6e8d4f2a69c0b5fb391 (commit)
via 6129c3537cc81af4561269d5652321ac2250ab93 (commit)
via 097a376ed65be53dbfe4cd1f2f46df288fb9d6ae (commit)
via a0f1ca23cd394e0d94845ecc08c35e56bf313b01 (commit)
via e494212d02fa6efcb437f966708992de8b02cb74 (commit)
from 9e89c7638a259fd103316f2b7f9be539b2cf3dce (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit ba1bfc79c7079e9c0886d542229c917d305695d9
Merge: 9e89c7638a259fd103316f2b7f9be539b2cf3dce 70778ebed8f5d0af186460600facc563865bafe8
Author: Stephen Morris <stephen at isc.org>
Date: Fri Mar 2 10:05:13 2012 +0000
Merge branch 'master' into trac1605
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 89 +++++-
configure.ac | 69 +++--
doc/guide/bind10-guide.html | 124 ++++----
doc/guide/bind10-guide.txt | 58 +++--
doc/guide/bind10-guide.xml | 78 +++--
doc/guide/bind10-messages.html | 150 +++++++---
doc/guide/bind10-messages.xml | 269 +++++++++++++----
ext/asio/asio/detail/impl/kqueue_reactor.ipp | 2 +
ext/asio/asio/detail/impl/socket_ops.ipp | 36 ++--
src/bin/auth/auth_srv.cc | 12 +-
src/bin/auth/b10-auth.8 | 18 +-
src/bin/auth/b10-auth.xml | 19 +-
src/bin/auth/query.cc | 170 +++++------
src/bin/auth/query.h | 56 ++++
src/bin/auth/tests/auth_srv_unittest.cc | 3 +-
src/bin/auth/tests/query_unittest.cc | 8 +-
src/bin/bind10/bind10.8 | 52 ++--
src/bin/bind10/bind10.xml | 75 +++--
src/bin/bind10/bind10_src.py.in | 2 +-
src/bin/cmdctl/b10-cmdctl.8 | 33 ++-
src/bin/cmdctl/b10-cmdctl.xml | 50 +++-
src/bin/ddns/b10-ddns.8 | 12 +-
src/bin/ddns/b10-ddns.xml | 13 +-
src/bin/dhcp4/Makefile.am | 2 +-
src/bin/dhcp6/Makefile.am | 2 +-
src/bin/host/host.cc | 5 +-
src/bin/resolver/b10-resolver.8 | 10 +-
src/bin/resolver/b10-resolver.xml | 11 +-
src/bin/resolver/resolver.cc | 7 +-
src/bin/sockcreator/main.cc | 2 +-
src/bin/sockcreator/sockcreator.cc | 67 ++++-
src/bin/sockcreator/sockcreator.h | 21 +-
src/bin/sockcreator/tests/Makefile.am | 5 +-
src/bin/sockcreator/tests/sockcreator_tests.cc | 81 ++++-
src/bin/stats/b10-stats-httpd.8 | 23 +-
src/bin/stats/b10-stats-httpd.xml | 17 +-
src/bin/stats/b10-stats.8 | 38 ++--
src/bin/stats/b10-stats.xml | 38 ++-
src/bin/xfrout/b10-xfrout.8 | 15 +-
src/bin/xfrout/b10-xfrout.xml | 55 +---
src/bin/xfrout/tests/xfrout_test.py.in | 50 +++-
src/bin/xfrout/xfrout.py.in | 22 +--
src/bin/xfrout/xfrout.spec.pre.in | 42 ---
src/bin/zonemgr/b10-zonemgr.8 | 10 +-
src/bin/zonemgr/b10-zonemgr.xml | 11 +-
src/cppcheck-suppress.lst | 21 +-
src/lib/asiodns/Makefile.am | 1 +
src/lib/asiodns/dns_server.h | 16 -
src/lib/asiodns/io_fetch.cc | 7 +-
src/lib/asiodns/sync_udp_server.cc | 215 +++++++++++++
src/lib/asiodns/sync_udp_server.h | 161 ++++++++++
src/lib/asiodns/tcp_server.h | 3 -
src/lib/asiodns/tests/dns_server_unittest.cc | 119 +++++---
src/lib/asiodns/tests/io_fetch_unittest.cc | 27 +-
src/lib/asiodns/udp_server.cc | 5 -
src/lib/asiodns/udp_server.h | 10 -
src/lib/bench/benchmark_util.cc | 9 +-
src/lib/config/module_spec.cc | 1 -
src/lib/datasrc/Makefile.am | 6 +-
src/lib/datasrc/datasrc_config.h.pre.in | 2 +-
src/lib/datasrc/datasrc_messages.mes | 2 +-
src/lib/datasrc/memory_datasrc.cc | 52 ++--
src/lib/datasrc/sqlite3_datasrc.cc | 8 +
src/lib/datasrc/static_datasrc.cc | 1 +
src/lib/datasrc/tests/datasrc_unittest.cc | 3 +-
src/lib/datasrc/tests/memory_datasrc_unittest.cc | 58 +++-
src/lib/datasrc/tests/static_unittest.cc | 1 +
src/lib/dhcp/iface_mgr.cc | 4 +-
src/lib/dns/benchmarks/rdatarender_bench.cc | 3 +-
src/lib/dns/masterload.cc | 33 ++-
src/lib/dns/messagerenderer.cc | 40 ++-
src/lib/dns/messagerenderer.h | 94 ++++--
src/lib/dns/python/message_python.cc | 3 +-
src/lib/dns/python/messagerenderer_python.cc | 6 +-
src/lib/dns/rdatafields.cc | 6 +-
src/lib/dns/tests/edns_unittest.cc | 4 +-
src/lib/dns/tests/masterload_unittest.cc | 98 ++++++
src/lib/dns/tests/message_unittest.cc | 11 +-
src/lib/dns/tests/messagerenderer_unittest.cc | 86 ++++--
src/lib/dns/tests/name_unittest.cc | 13 +-
src/lib/dns/tests/question_unittest.cc | 6 +-
src/lib/dns/tests/rdata_afsdb_unittest.cc | 2 +-
src/lib/dns/tests/rdata_cname_unittest.cc | 4 +-
src/lib/dns/tests/rdata_dname_unittest.cc | 4 +-
src/lib/dns/tests/rdata_dnskey_unittest.cc | 4 +-
src/lib/dns/tests/rdata_ds_like_unittest.cc | 4 +-
src/lib/dns/tests/rdata_hinfo_unittest.cc | 5 +-
src/lib/dns/tests/rdata_in_a_unittest.cc | 2 +-
src/lib/dns/tests/rdata_in_aaaa_unittest.cc | 2 +-
src/lib/dns/tests/rdata_minfo_unittest.cc | 8 +-
src/lib/dns/tests/rdata_mx_unittest.cc | 6 +-
src/lib/dns/tests/rdata_naptr_unittest.cc | 5 +-
src/lib/dns/tests/rdata_ns_unittest.cc | 4 +-
.../dns/tests/rdata_nsec3param_like_unittest.cc | 2 +-
src/lib/dns/tests/rdata_nsec3param_unittest.cc | 4 +-
src/lib/dns/tests/rdata_nsec_unittest.cc | 4 +-
src/lib/dns/tests/rdata_nsecbitmap_unittest.cc | 2 +-
src/lib/dns/tests/rdata_ptr_unittest.cc | 4 +-
src/lib/dns/tests/rdata_rp_unittest.cc | 2 +-
src/lib/dns/tests/rdata_soa_unittest.cc | 4 +-
src/lib/dns/tests/rdata_srv_unittest.cc | 4 +-
src/lib/dns/tests/rdata_unittest.cc | 5 +-
src/lib/dns/tests/rdatafields_unittest.cc | 5 +-
src/lib/dns/tests/rrclass_unittest.cc | 4 +-
src/lib/dns/tests/rrset_unittest.cc | 6 +-
src/lib/dns/tests/rrttl_unittest.cc | 8 +-
src/lib/dns/tests/rrtype_unittest.cc | 4 +-
src/lib/dns/tests/tsig_unittest.cc | 3 +-
src/lib/dns/tests/tsigrecord_unittest.cc | 2 +-
src/lib/nsas/glue_hints.cc | 4 +-
src/lib/nsas/hash_table.h | 2 +-
src/lib/nsas/tests/nameserver_entry_unittest.cc | 4 +-
src/lib/nsas/zone_entry.cc | 2 +-
src/lib/python/isc/Makefile.am | 2 +-
src/lib/python/isc/config/ccsession.py | 93 +++++--
src/lib/python/isc/config/tests/ccsession_test.py | 323 ++++++++++++++++----
src/lib/python/isc/log/Makefile.am | 9 -
src/lib/python/isc/log_messages/Makefile.am | 2 +
.../isc/log_messages/server_common_messages.py | 1 +
src/lib/python/isc/server_common/Makefile.am | 24 ++
.../isc/{bind10 => server_common}/__init__.py | 0
.../isc/server_common/server_common_messages.mes | 36 +++
.../isc/{xfrin => server_common}/tests/Makefile.am | 2 +-
.../isc/server_common/tests/tsig_keyring_test.py | 193 ++++++++++++
src/lib/python/isc/server_common/tsig_keyring.py | 121 ++++++++
.../resolve/tests/recursive_query_unittest_2.cc | 17 +-
.../resolve/tests/recursive_query_unittest_3.cc | 17 +-
src/lib/testutils/srv_test.cc | 2 -
src/lib/testutils/srv_test.h | 1 -
.../testutils/testdata/rfc5155-example.zone.signed | 4 +-
src/lib/util/io/fd_share.cc | 17 +-
.../multi_instance/multi_auth.config.orig | 1 +
.../lettuce/configurations/nsec3/nsec3_auth.config | 1 +
.../nsec3}/rfc5155-example.zone.signed | 0
tests/lettuce/features/multi_instance.feature | 35 +++
tests/lettuce/features/nsec3_auth.feature | 302 ++++++++++++++++++
tests/lettuce/features/terrain/bind10_control.py | 92 ++++++
tests/lettuce/features/terrain/querying.py | 77 ++++-
tests/lettuce/features/terrain/terrain.py | 8 +-
.../system/bindctl/nsx1/b10-config.db.template.in | 3 -
tests/system/glue/nsx1/b10-config.db.in | 3 -
tests/tools/badpacket/scan.cc | 3 +-
142 files changed, 3465 insertions(+), 1116 deletions(-)
create mode 100644 src/lib/asiodns/sync_udp_server.cc
create mode 100644 src/lib/asiodns/sync_udp_server.h
create mode 100644 src/lib/python/isc/log_messages/server_common_messages.py
create mode 100644 src/lib/python/isc/server_common/Makefile.am
copy src/lib/python/isc/{bind10 => server_common}/__init__.py (100%)
create mode 100644 src/lib/python/isc/server_common/server_common_messages.mes
copy src/lib/python/isc/{xfrin => server_common}/tests/Makefile.am (97%)
create mode 100644 src/lib/python/isc/server_common/tests/tsig_keyring_test.py
create mode 100644 src/lib/python/isc/server_common/tsig_keyring.py
create mode 100644 tests/lettuce/configurations/multi_instance/multi_auth.config.orig
create mode 100644 tests/lettuce/configurations/nsec3/nsec3_auth.config
copy {src/lib/testutils/testdata => tests/lettuce/configurations/nsec3}/rfc5155-example.zone.signed (100%)
create mode 100644 tests/lettuce/features/multi_instance.feature
create mode 100644 tests/lettuce/features/nsec3_auth.feature
-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index 4a13d9d..e48d86b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,69 @@
-382. [func] jelte
+391. [bug]* vorner
+ The long time unused configuration options of Xfrout "log_name",
+ "log_file", "log_severity", "log_version" and "log_max_bytes" were
+ removed, as they had no effect (Xfrout uses the global logging framework).
+ However, if you have them set, you need to remove them from the
+ configuration file or the configuration will be rejected.
+ (Trac #1090, git ef1eba02e4cf550e48e7318702cff6d67c1ec82e)
+
+bind10-devel-20120301 released on March 1, 2012
+
+390. [bug] vorner
+ The UDP IPv6 packets are now correctly fragmented for maximum
+ guaranteed MTU, so they won't get lost because being too large
+ for some hop.
+ (Trac #1534, git ff013364643f9bfa736b2d23fec39ac35872d6ad)
+
+389. [func]* vorner
+ Xfrout now uses the global TSIG keyring, instead of its own. This
+ means the keys need to be set only once (in tsig_keys/keys).
+ However, the old configuration of Xfrout/tsig_keys need to be
+ removed for Xfrout to work.
+ (Trac #1643, git 5a7953933a49a0ddd4ee1feaddc908cd2285522d)
+
+388. [func] jreed
+ Use prefix "sockcreator-" for the private temporary directory
+ used for b10-sockcreator communication.
+ (git b98523c1260637cb33436964dc18e9763622a242)
+
+387. [build] muks
+ Accept a --without-werror configure switch so that some builders can
+ disable the use of -Werror in CFLAGS when building.
+ (Trac #1671, git 8684a411d7718a71ad9fb616f56b26436c4f03e5)
+
+386. [bug] jelte
+ Upon initial sqlite3 database creation, the 'diffs' table is now
+ always created. This already happened most of the time, but there
+ are a few cases where it was skipped, resulting in potential errors
+ in xfrout later.
+ (Trac #1717, git 30d7686cb6e2fa64866c983e0cfb7b8fabedc7a2)
+
+385. [bug] jinmei
+ libdns++: masterLoad() didn't accept comments placed at the end of
+ an RR. Due to this the in-memory data source cannot load a master
+ file for a signed zone even if it's preprocessed with BIND 9's
+ named-compilezone.
+ Note: this fix is considered temporary and still only accepts some
+ limited form of such comments. The main purpose is to allow the
+ in-memory data source to load any signed or unsigned zone files as
+ long as they are at least normalized with named-compilezone.
+ (Trac #1667, git 6f771b28eea25c693fe93a0e2379af924464a562)
+
+384. [func] jinmei, jelte, vorner, haikuo, kevin
+ b10-auth now supports NSEC3-signed zones in the in-memory data
+ source.
+ (Trac #1580, #1581, #1582, #1583, #1584, #1585, #1587, and
+ other related changes to the in-memory data source)
+
+383. [build] jinmei
+ Fixed build failure on MacOS 10.7 (Lion) due to the use of
+ IPV6_PKTINFO; the OS requires a special definition to make it
+ visible to the compiler.
+ (Trac #1633, git 19ba70c7cc3da462c70e8c4f74b321b8daad0100)
+
+382. [func] jelte
b10-auth now also experimentally supports statistics counters of
- the rcode reponses it sends. The counters can be shown as
+ the rcode responses it sends. The counters can be shown as
rcode.<code name>, where code name is the lowercase textual
representation of the rcode (e.g. "noerror", "formerr", etc.).
Same note applies as for opcodes, see changelog entry 364.
@@ -50,11 +113,11 @@
(Trac #1570, git 2858b2098a10a8cc2d34bf87463ace0629d3670e)
375. [func] jelte
- Modules now inform the system when they are stopping. As a result, they
- are removed from the 'active modules' list in bindctl, which can then
- inform the user directly when it tries to send them a command or
- configuration update. Previously this would result in a 'not
- responding' error instead of 'not running'.
+ Modules now inform the system when they are stopping. As a result,
+ they are removed from the 'active modules' list in bindctl, which
+ can then inform the user directly when it tries to send them a
+ command or configuration update. Previously this would result
+ in a 'not responding' error instead of 'not running'.
(Trac #640, git 17e78fa1bb1227340aa9815e91ed5c50d174425d)
374. [func]* stephen
@@ -90,10 +153,11 @@
(Trac #1575, git 2c421b58e810028b303d328e4e2f5b74ea124839)
369. [func] vorner
- The SocketRequestor provides more information about what error happened
- when it throws, by using subclasses of the original exception. This way
- a user not interested in the difference can still use the original
- exception, while it can be recognized if necessary.
+ The SocketRequestor provides more information about what error
+ happened when it throws, by using subclasses of the original
+ exception. This way a user not interested in the difference can
+ still use the original exception, while it can be recognized if
+ necessary.
(Trac #1542, git 2080e0316a339fa3cadea00e10b1ec4bc322ada0)
368. [func]* jinmei
@@ -151,7 +215,8 @@ bind10-devel-20120119 released on January 19, 2012
configuration. If your b10-config.db contains "setuid" for
Boss.components, you'll need to remove that entry by hand before
starting BIND 10.
- (Trac #1508-#1510, git edc5b3c12eb45437361484c843794416ad86bb00)
+ (Trac #1508, #1509, #1510,
+ git edc5b3c12eb45437361484c843794416ad86bb00)
361. [func] vorner,jelte,jinmei
The socket creator is now used to provide sockets. It means you can
diff --git a/configure.ac b/configure.ac
index de79551..af8c2fe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5,6 +5,7 @@ AC_PREREQ([2.59])
AC_INIT(bind10-devel, 20120127, bind10-dev at isc.org)
AC_CONFIG_SRCDIR(README)
AM_INIT_AUTOMAKE
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])dnl be backward compatible
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
@@ -108,6 +109,10 @@ case "$host" in
LDFLAGS="$LDFLAGS -z now"
;;
*-apple-darwin*)
+ # Starting with OSX 10.7 (Lion) we must choose which IPv6 API to use
+ # (RFC2292 or RFC3542).
+ CPPFLAGS="$CPPFLAGS -D__APPLE_USE_RFC_3542"
+
# libtool doesn't work perfectly with Darwin: libtool embeds the
# final install path in dynamic libraries and our loadable python
# modules always refer to that path even if it's loaded within the
@@ -270,7 +275,7 @@ AC_DEFUN([BIND10_CXX_TRY_FLAG], [
bind10_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $1"
- AC_LINK_IFELSE([int main(void){ return 0;} ],
+ AC_LINK_IFELSE([int main(void){ return 0;}],
[bind10_cxx_flag=yes], [bind10_cxx_flag=no])
CXXFLAGS="$bind10_save_CXXFLAGS"
@@ -283,8 +288,6 @@ AC_DEFUN([BIND10_CXX_TRY_FLAG], [
AC_MSG_RESULT([$bind10_cxx_flag])
])
-werror_ok=0
-
# SunStudio compiler requires special compiler options for boost
# (http://blogs.sun.com/sga/entry/boost_mini_howto)
if test "$SUNCXX" = "yes"; then
@@ -292,7 +295,7 @@ CXXFLAGS="$CXXFLAGS -library=stlport4 -features=tmplife -features=tmplrefstatic"
MULTITHREADING_FLAG="-mt"
fi
-BIND10_CXX_TRY_FLAG(-Wno-missing-field-initializers,
+BIND10_CXX_TRY_FLAG([-Wno-missing-field-initializers],
[WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG="-Wno-missing-field-initializers"])
AC_SUBST(WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG)
@@ -310,19 +313,34 @@ case "$host" in
;;
esac
+# Don't use -Werror if configured not to
+AC_ARG_WITH(werror,
+ AC_HELP_STRING([--with-werror], [Compile using -Werror (default=yes)]),
+ [
+ case "${withval}" in
+ yes) with_werror=1 ;;
+ no) with_werror=0 ;;
+ *) AC_MSG_ERROR(bad value ${withval} for --with-werror) ;;
+ esac],
+ [with_werror=1])
+
+werror_ok=0
+
# 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
# translation unit. For these versions we have to disable -Werror.
-CXXFLAGS_SAVED="$CXXFLAGS"
-CXXFLAGS="$CXXFLAGS $B10_CXXFLAGS -Werror"
-AC_MSG_CHECKING(for in-TU anonymous namespace breakage)
-AC_TRY_COMPILE([namespace { class Foo {}; }
-namespace isc {class Bar {Foo foo_;};} ],,
+if test $with_werror = 1; then
+ CXXFLAGS_SAVED="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS $B10_CXXFLAGS -Werror"
+ AC_MSG_CHECKING(for in-TU anonymous namespace breakage)
+ AC_TRY_COMPILE([namespace { class Foo {}; }
+ namespace isc {class Bar {Foo foo_;};} ],,
[AC_MSG_RESULT(no)
werror_ok=1
B10_CXXFLAGS="$B10_CXXFLAGS -Werror"],
[AC_MSG_RESULT(yes)])
-CXXFLAGS="$CXXFLAGS_SAVED"
+ CXXFLAGS="$CXXFLAGS_SAVED"
+fi
# Python 3.2 has an unused parameter in one of its headers. This
# has been reported, but not fixed as of yet, so we check if we need
@@ -517,21 +535,22 @@ else
AC_PATH_PROG([BOTAN_CONFIG], [botan-config])
fi
fi
-
-BOTAN_LIBS=`${BOTAN_CONFIG} --libs`
-BOTAN_INCLUDES=`${BOTAN_CONFIG} --cflags`
-
-# We expect botan-config --libs to contain -L<path_to_libbotan>, but
-# this is not always the case. As a heuristics workaround we add
-# -L`botan-config --prefix/lib` in this case (if not present already).
-# Same for BOTAN_INCLUDES (but using include instead of lib) below.
-if [ $BOTAN_CONFIG --prefix >/dev/null 2>&1 ] ; then
- echo ${BOTAN_LIBS} | grep -- -L > /dev/null || \
- BOTAN_LIBS="-L`${BOTAN_CONFIG} --prefix`/lib ${BOTAN_LIBS}"
- echo ${BOTAN_INCLUDES} | grep -- -I > /dev/null || \
- BOTAN_INCLUDES="-I`${BOTAN_CONFIG} --prefix`/include ${BOTAN_INCLUDES}"
+if test "x${BOTAN_CONFIG}" != "x"
+then
+ BOTAN_LIBS=`${BOTAN_CONFIG} --libs`
+ BOTAN_INCLUDES=`${BOTAN_CONFIG} --cflags`
+
+ # We expect botan-config --libs to contain -L<path_to_libbotan>, but
+ # this is not always the case. As a heuristics workaround we add
+ # -L`botan-config --prefix/lib` in this case (if not present already).
+ # Same for BOTAN_INCLUDES (but using include instead of lib) below.
+ if [ ${BOTAN_CONFIG} --prefix >/dev/null 2>&1 ] ; then
+ echo ${BOTAN_LIBS} | grep -- -L > /dev/null || \
+ BOTAN_LIBS="-L`${BOTAN_CONFIG} --prefix`/lib ${BOTAN_LIBS}"
+ echo ${BOTAN_INCLUDES} | grep -- -I > /dev/null || \
+ BOTAN_INCLUDES="-I`${BOTAN_CONFIG} --prefix`/include ${BOTAN_INCLUDES}"
+ fi
fi
-
# botan-config script (and the way we call pkg-config) returns -L and -l
# as one string, but we need them in separate values
BOTAN_LDFLAGS=
@@ -1001,6 +1020,8 @@ AC_CONFIG_FILES([Makefile
src/lib/python/isc/bind10/tests/Makefile
src/lib/python/isc/xfrin/Makefile
src/lib/python/isc/xfrin/tests/Makefile
+ src/lib/python/isc/server_common/Makefile
+ src/lib/python/isc/server_common/tests/Makefile
src/lib/config/Makefile
src/lib/config/tests/Makefile
src/lib/config/tests/testdata/Makefile
diff --git a/doc/guide/bind10-guide.html b/doc/guide/bind10-guide.html
index 4ae31f5..9a76d5a 100644
--- a/doc/guide/bind10-guide.html
+++ b/doc/guide/bind10-guide.html
@@ -1,4 +1,4 @@
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>BIND 10 Guide</title><link rel="stylesheet" type="text/css" href="./bind10-guide.css"><meta name="generator" content="DocBook XSL Stylesheets V1.76.1"><meta name="description" content="BIND 10 is a framework that features Domain Name System (DNS) suite and Dynamic Host Configuration Protocol (DHCP) servers managed by Internet Systems Consortium (ISC). It includes DNS libraries, modular components for controlling authoritative and recursive DNS servers, and experimental DHCPv4 and DHCPv6 servers. This is the reference guide for BIND 10 version 20120127. The most up-to-date version of this document (in PDF, HTML, and plain text formats), 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="idm148
92896"></a>BIND 10 Guide</h1></div><div><h2 class="subtitle">Administrator Reference for BIND 10</h2></div><div><p class="releaseinfo">This is the reference guide for BIND 10 version
+<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="BIND 10 is a framework that features Domain Name System (DNS) suite and Dynamic Host Configuration Protocol (DHCP) servers managed by Internet Systems Consortium (ISC). It includes DNS libraries, modular components for controlling authoritative and recursive DNS servers, and experimental DHCPv4 and DHCPv6 servers. This is the reference guide for BIND 10 version 20120127. The most up-to-date version of this document (in PDF, HTML, and plain text formats), 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="id1168
229451102"></a>BIND 10 Guide</h1></div><div><h2 class="subtitle">Administrator Reference for BIND 10</h2></div><div><p class="releaseinfo">This is the reference guide for BIND 10 version
20120127.</p></div><div><p class="copyright">Copyright © 2010-2012 Internet Systems Consortium, Inc.</p></div><div><div class="abstract" title="Abstract"><p class="title"><b>Abstract</b></p><p>BIND 10 is a framework that features Domain Name System
(DNS) suite and Dynamic Host Configuration Protocol (DHCP)
servers managed by Internet Systems Consortium (ISC). It
@@ -10,9 +10,9 @@
The most up-to-date version of this document (in PDF, HTML,
and plain text formats), 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="preface"><a href="#idp61424">Preface</a></span></dt><dd><dl><dt><span class="section"><a href="#acknowledgements">1. Acknowledgements</a></span></dt></dl></dd><dt><span class="chapter"><a href="#intro">1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="#idp64344">1.1. Supported Platforms</a></span></dt><dt><span class="section"><a href="#required-software">1.2. Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">1.3. Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">1.4. 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="#build-requirements">2.1. Building Requirements</a></span></dt><dt><span class="section"><a href="#quickstart">2.2. Quick
start</a></span></dt><dt><span class="section"><a href="#install">2.3. Installation from source</a></span></dt><dd><dl><dt><span class="section"><a href="#idp113000">2.3.1. Download Tar File</a></span></dt><dt><span class="section"><a href="#idp114472">2.3.2. Retrieve from Git</a></span></dt><dt><span class="section"><a href="#idp119504">2.3.3. Configure before the build</a></span></dt><dt><span class="section"><a href="#idp126792">2.3.4. Build</a></span></dt><dt><span class="section"><a href="#idp127848">2.3.5. Install</a></span></dt><dt><span class="section"><a href="#idp129504">2.3.6. 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">3.1. Starting BIND 10</a></span></dt><dt><span class="section"><a href="#bind10.config">3.2. Configuration of started processes</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">6.1. Configuration specification 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="#idp200360">8.1. Server Configurations</a></span></dt><dt><span class="section"><a href="#idp205096">8.2. Data Source Backends</a></span></dt><dt><span class="section"><a href="#idp207592">8.3. Loading Master Zones Files</a></span></dt></dl></dd><dt><span class="chapter"><a href="#xfrin">9. Incoming Zone Transfers</a></span></dt><dd><dl><dt><span class="section"><a href="#idp217864">
9.1. Configuration for Incoming Zone Transfers</a></span></dt><dt><span class="section"><a href="#idp220904">9.2. Enabling IXFR</a></span></dt><dt><span class="section"><a href="#zonemgr">9.3. Secondary Manager</a></span></dt><dt><span class="section"><a href="#idp11976">9.4. Trigger an Incoming Zone Transfer Manually</a></span></dt></dl></dd><dt><span class="chapter"><a href="#xfrout">10. Outbound Zone Transfers</a></span></dt><dt><span class="chapter"><a href="#resolverserver">11. Recursive Name Server</a></span></dt><dd><dl><dt><span class="section"><a href="#idp259896">11.1. Access Control</a></span></dt><dt><span class="section"><a href="#idp269088">11.2. Forwarding</a></span></dt></dl></dd><dt><span class="chapter"><a href="#dhcp4">12. DHCPv4 Server</a></span></dt><dd><dl><dt><span class="section"><a href="#dhcp4-usage">12.1. DHCPv4 Server Usage</a></span></dt><dt><span class="section"><a href="#dhcp4-config">12.2. DHCPv4 Server Configuration</a></span></dt><dt><span c
lass="section"><a href="#dhcp4-std">12.3. Supported standards</a></span></dt><dt><span class="section"><a href="#dhcp4-limit">12.4. DHCPv4 Server Limitations</a></span></dt></dl></dd><dt><span class="chapter"><a href="#dhcp6">13. DHCPv6 Server</a></span></dt><dd><dl><dt><span class="section"><a href="#dhcp6-usage">13.1. DHCPv6 Server Usage</a></span></dt><dt><span class="section"><a href="#dhcp6-config">13.2. DHCPv6 Server Configuration</a></span></dt><dt><span class="section"><a href="#dhcp6-std">13.3. Supported DHCPv6 Standards</a></span></dt><dt><span class="section"><a href="#dhcp6-limit">13.4. DHCPv6 Server Limitations</a></span></dt></dl></dd><dt><span class="chapter"><a href="#libdhcp">14. libdhcp++ library</a></span></dt><dd><dl><dt><span class="section"><a href="#iface-detect">14.1. Interface detection</a></span></dt><dt><span class="section"><a href="#packet-handling">14.2. DHCPv4/DHCPv6 packet handling</a></span></dt></dl></dd><dt><span class="chapter"><a href="#s
tatistics">15. Statistics</a></span></dt><dt><span class="chapter"><a href="#logging">16. Logging</a></span></dt><dd><dl><dt><span class="section"><a href="#idp327280">16.1. Logging configuration</a></span></dt><dd><dl><dt><span class="section"><a href="#idp328272">16.1.1. Loggers</a></span></dt><dt><span class="section"><a href="#idp349480">16.1.2. Output Options</a></span></dt><dt><span class="section"><a href="#idp362088">16.1.3. Example session</a></span></dt></dl></dd><dt><span class="section"><a href="#idp379592">16.2. Logging Message Format</a></span></dt></dl></dd></dl></div><div class="list-of-tables"><p><b>List of Tables</b></p><dl><dt>3.1. <a href="#idp150584"></a></dt></dl></div><div class="preface" title="Preface"><div class="titlepage"><div><div><h2 class="title"><a name="idp61424"></a>Preface</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#acknowledgements">1. Acknowledgements</a></span></dt></dl></
div><div class="section" title="1. Acknowledgements"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="acknowledgements"></a>1. Acknowledgements</h2></div></div></div><p>ISC would like to acknowledge generous support for
+ </p></div></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="preface"><a href="#id1168229451188">Preface</a></span></dt><dd><dl><dt><span class="section"><a href="#acknowledgements">1. Acknowledgements</a></span></dt></dl></dd><dt><span class="chapter"><a href="#intro">1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229451269">1.1. Supported Platforms</a></span></dt><dt><span class="section"><a href="#required-software">1.2. Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">1.3. Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">1.4. 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="#build-requirements">2.1. Building Requirements</a></span></dt><dt><span class="section"><a href="#quickstar
t">2.2. Quick start</a></span></dt><dt><span class="section"><a href="#install">2.3. Installation from source</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229436809">2.3.1. Download Tar File</a></span></dt><dt><span class="section"><a href="#id1168229436828">2.3.2. Retrieve from Git</a></span></dt><dt><span class="section"><a href="#id1168229436889">2.3.3. Configure before the build</a></span></dt><dt><span class="section"><a href="#id1168229436986">2.3.4. Build</a></span></dt><dt><span class="section"><a href="#id1168229437002">2.3.5. Install</a></span></dt><dt><span class="section"><a href="#id1168229437026">2.3.6. 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">3.1. Starting BIND 10</a></span></dt><dt><span class="section"><a href="#bind10.config">3.2. Configurati
on of started processes</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">6.1. Configuration specification 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="#id1168229437990">8.1. Server Configurations</a></span></dt><dt><span class="section"><a href="#id1168229438055">8.2. Data Source Backends</a></span></dt><dt><span class="section"><a href="#id1168229438085">8.3. Loading Master Zones Files</a></span></dt></dl></dd><dt><span class="chapter"><a href="#xfrin">9. Incoming Zone Transfers</a
></span></dt><dd><dl><dt><span class="section"><a href="#id1168229438216">9.1. Configuration for Incoming Zone Transfers</a></span></dt><dt><span class="section"><a href="#id1168229438254">9.2. Enabling IXFR</a></span></dt><dt><span class="section"><a href="#zonemgr">9.3. Secondary Manager</a></span></dt><dt><span class="section"><a href="#id1168229438369">9.4. Trigger an Incoming Zone Transfer Manually</a></span></dt></dl></dd><dt><span class="chapter"><a href="#xfrout">10. Outbound Zone Transfers</a></span></dt><dt><span class="chapter"><a href="#resolverserver">11. Recursive Name Server</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229438715">11.1. Access Control</a></span></dt><dt><span class="section"><a href="#id1168229438900">11.2. Forwarding</a></span></dt></dl></dd><dt><span class="chapter"><a href="#dhcp4">12. DHCPv4 Server</a></span></dt><dd><dl><dt><span class="section"><a href="#dhcp4-usage">12.1. DHCPv4 Server Usage</a></span></dt><dt><span c
lass="section"><a href="#dhcp4-config">12.2. DHCPv4 Server Configuration</a></span></dt><dt><span class="section"><a href="#dhcp4-std">12.3. Supported standards</a></span></dt><dt><span class="section"><a href="#dhcp4-limit">12.4. DHCPv4 Server Limitations</a></span></dt></dl></dd><dt><span class="chapter"><a href="#dhcp6">13. DHCPv6 Server</a></span></dt><dd><dl><dt><span class="section"><a href="#dhcp6-usage">13.1. DHCPv6 Server Usage</a></span></dt><dt><span class="section"><a href="#dhcp6-config">13.2. DHCPv6 Server Configuration</a></span></dt><dt><span class="section"><a href="#dhcp6-std">13.3. Supported DHCPv6 Standards</a></span></dt><dt><span class="section"><a href="#dhcp6-limit">13.4. DHCPv6 Server Limitations</a></span></dt></dl></dd><dt><span class="chapter"><a href="#libdhcp">14. libdhcp++ library</a></span></dt><dd><dl><dt><span class="section"><a href="#iface-detect">14.1. Interface detection</a></span></dt><dt><span class="section"><a href="#packet-handling"
>14.2. DHCPv4/DHCPv6 packet handling</a></span></dt></dl></dd><dt><span class="chapter"><a href="#statistics">15. Statistics</a></span></dt><dt><span class="chapter"><a href="#logging">16. Logging</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229440014">16.1. Logging configuration</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229440025">16.1.1. Loggers</a></span></dt><dt><span class="section"><a href="#id1168229440268">16.1.2. Output Options</a></span></dt><dt><span class="section"><a href="#id1168229440509">16.1.3. Example session</a></span></dt></dl></dd><dt><span class="section"><a href="#id1168229440720">16.2. Logging Message Format</a></span></dt></dl></dd></dl></div><div class="list-of-tables"><p><b>List of Tables</b></p><dl><dt>3.1. <a href="#id1168229437291"></a></dt></dl></div><div class="preface" title="Preface"><div class="titlepage"><div><div><h2 class="title"><a name="id1168229451188"></a>Preface</h2></div></div></div><div c
lass="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#acknowledgements">1. Acknowledgements</a></span></dt></dl></div><div class="section" title="1. Acknowledgements"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="acknowledgements"></a>1. Acknowledgements</h2></div></div></div><p>ISC would like to acknowledge generous support for
BIND 10 development of DHCPv4 and DHCPv6 components provided
- by <a class="ulink" href="http://www.comcast.com/" target="_top">Comcast</a>.</p></div></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="#idp64344">1.1. Supported Platforms</a></span></dt><dt><span class="section"><a href="#required-software">1.2. Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">1.3. Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">1.4. Managing BIND 10</a></span></dt></dl></div><p>
+ by <a class="ulink" href="http://www.comcast.com/" target="_top">Comcast</a>.</p></div></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="#id1168229451269">1.1. Supported Platforms</a></span></dt><dt><span class="section"><a href="#required-software">1.2. Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">1.3. Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">1.4. 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
@@ -23,7 +23,7 @@
</p><p>
This guide covers the experimental prototype of
BIND 10 version 20120127.
- </p><div class="section" title="1.1. Supported Platforms"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="idp64344"></a>1.1. Supported Platforms</h2></div></div></div><p>
+ </p><div class="section" title="1.1. Supported Platforms"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229451269"></a>1.1. Supported Platforms</h2></div></div></div><p>
BIND 10 builds have been tested on Debian GNU/Linux 5 and unstable,
Ubuntu 9.10, NetBSD 5, Solaris 10, FreeBSD 7 and 8, CentOS
Linux 5.3, and MacOS 10.6.
@@ -78,11 +78,6 @@
</p><p>
</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
- <span class="command"><strong>b10-msgq</strong></span> —
- Message bus daemon.
- This process coordinates communication between all of the other
- BIND 10 processes.
- </li><li class="listitem">
<span class="command"><strong>b10-auth</strong></span> —
Authoritative DNS server.
This process serves DNS requests.
@@ -95,15 +90,29 @@
Command and control service.
This process allows external control of the BIND 10 system.
</li><li class="listitem">
+ <span class="command"><strong>b10-msgq</strong></span> —
+ Message bus daemon.
+ This process coordinates communication between all of the other
+ BIND 10 processes.
+ </li><li class="listitem">
<span class="command"><strong>b10-resolver</strong></span> —
Recursive name server.
This process handles incoming queries.
</li><li class="listitem">
+ <span class="command"><strong>b10-sockcreator</strong></span> —
+ Socket creator daemon.
+ This process creates sockets used by
+ network-listening BIND 10 processes.
+ </li><li class="listitem">
<span class="command"><strong>b10-stats</strong></span> —
Statistics collection daemon.
This process collects and reports statistics data.
</li><li class="listitem">
+ <span class="command"><strong>b10-stats-httpd</strong></span> —
+ HTTP server for statistics reporting.
+ This process reports statistics data in XML format over HTTP.
+ </li><li class="listitem">
<span class="command"><strong>b10-xfrin</strong></span> —
Incoming zone transfer service.
This process is used to transfer a new copy
@@ -129,8 +138,9 @@
</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<span class="command"><strong>bindctl</strong></span> —
interactive administration interface.
- This is a command-line tool which allows an administrator
- to control BIND 10.
+ This is a low-level command-line tool which allows
+ a developer or an experienced administrator to control
+ BIND 10.
</li><li class="listitem">
<span class="command"><strong>b10-loadzone</strong></span> —
zone file loader.
@@ -152,7 +162,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="#build-requirements">2.1. Building Requirements</a></span></dt><dt><span class="section"><a href="#quickstart">2.2. Quick start</a></span></dt><dt><span class="section"><a href="#install">2.3. Installation from source</a></span></dt><dd><dl><dt><span class="section"><a href="#idp113000">2.3.1. Download Tar File</a></span></dt><dt><span class="section"><a href="#idp114472">2.3.2. Retrieve from Git</a></span></dt><dt><span class="section"><a href="#idp119504">2.3.3. Configure before the build</a></span></dt><dt><span class="section"><a href="#idp126792">2.3.4. Build</a></span></dt><dt><span class="section"><a href="#idp127848">2.3.5. Install</a></span></dt><dt><span class="section"><a href="#idp129504">2
.3.6. Install Hierarchy</a></span></dt></dl></dd></dl></div><div class="section" title="2.1. Building Requirements"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="build-requirements"></a>2.1. Building Requirements</h2></div></div></div><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="#build-requirements">2.1. Building Requirements</a></span></dt><dt><span class="section"><a href="#quickstart">2.2. Quick start</a></span></dt><dt><span class="section"><a href="#install">2.3. Installation from source</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229436809">2.3.1. Download Tar File</a></span></dt><dt><span class="section"><a href="#id1168229436828">2.3.2. Retrieve from Git</a></span></dt><dt><span class="section"><a href="#id1168229436889">2.3.3. Configure before the build</a></span></dt><dt><span class="section"><a href="#id1168229436986">2.3.4. Build</a></span></dt><dt><span class="section"><a href="#id1168229437002">2.3.5. Install</a></span></dt><dt><span class="s
ection"><a href="#id1168229437026">2.3.6. Install Hierarchy</a></span></dt></dl></dd></dl></div><div class="section" title="2.1. Building Requirements"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="build-requirements"></a>2.1. Building Requirements</h2></div></div></div><p>
In addition to the run-time requirements, building BIND 10
from source code requires various development include headers.
</p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
@@ -214,14 +224,14 @@
the Git 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="2.3.1. Download Tar File"><div class="titlepage"><div><div><h3 class="title"><a name="idp113000"></a>2.3.1. Download Tar File</h3></div></div></div><p>
+ </p><div class="section" title="2.3.1. Download Tar File"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229436809"></a>2.3.1. 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="2.3.2. Retrieve from Git"><div class="titlepage"><div><div><h3 class="title"><a name="idp114472"></a>2.3.2. Retrieve from Git</h3></div></div></div><p>
+ </p></div><div class="section" title="2.3.2. Retrieve from Git"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229436828"></a>2.3.2. Retrieve from Git</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.
@@ -255,7 +265,7 @@
<span class="command"><strong>autoheader</strong></span>,
<span class="command"><strong>automake</strong></span>,
and related commands.
- </p></div><div class="section" title="2.3.3. Configure before the build"><div class="titlepage"><div><div><h3 class="title"><a name="idp119504"></a>2.3.3. Configure before the build</h3></div></div></div><p>
+ </p></div><div class="section" title="2.3.3. Configure before the build"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229436889"></a>2.3.3. 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:
@@ -286,16 +296,16 @@
</p><p>
If the configure fails, it may be due to missing or old
dependencies.
- </p></div><div class="section" title="2.3.4. Build"><div class="titlepage"><div><div><h3 class="title"><a name="idp126792"></a>2.3.4. Build</h3></div></div></div><p>
+ </p></div><div class="section" title="2.3.4. Build"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229436986"></a>2.3.4. 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="2.3.5. Install"><div class="titlepage"><div><div><h3 class="title"><a name="idp127848"></a>2.3.5. Install</h3></div></div></div><p>
+ </p></div><div class="section" title="2.3.5. Install"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229437002"></a>2.3.5. 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="2.3.6. Install Hierarchy"><div class="titlepage"><div><div><h3 class="title"><a name="idp129504"></a>2.3.6. 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="2.3.6. Install Hierarchy"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229437026"></a>2.3.6. 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> —
@@ -349,9 +359,11 @@
</p><p>
In its default configuration, 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-cmdctl</strong></span> for administration tools to
+ communicate with the system,
+ <span class="command"><strong>b10-auth</strong></span> for authoritative DNS service,
<span class="command"><strong>b10-stats</strong></span> for statistics collection,
+ <span class="command"><strong>b10-stats-httpd</strong></span> for statistics reporting,
<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.
@@ -395,7 +407,7 @@
during startup or shutdown. Unless specified, the component is started
in usual way. This is the list of components that need to be started
in a special way, with the value of special used for them:
- </p><div class="table"><a name="idp150584"></a><p class="title"><b>Table 3.1. </b></p><div class="table-contents"><table border="1"><colgroup><col align="left" class="component"><col align="left" class="special"><col align="left" class="description"></colgroup><thead><tr><th align="left">Component</th><th align="left">Special</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left">b10-auth</td><td align="left">auth</td><td align="left">Authoritative server</td></tr><tr><td align="left">b10-resolver</td><td align="left">resolver</td><td align="left">The resolver</td></tr><tr><td align="left">b10-cmdctl</td><td align="left">cmdctl</td><td align="left">The command control (remote control interface)</td></tr></tbody></table></div></div><p><br class="table-break">
+ </p><div class="table"><a name="id1168229437291"></a><p class="title"><b>Table 3.1. </b></p><div class="table-contents"><table border="1"><colgroup><col align="left"><col align="left"><col align="left"></colgroup><thead><tr><th align="left">Component</th><th align="left">Special</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left">b10-auth</td><td align="left">auth</td><td align="left">Authoritative server</td></tr><tr><td align="left">b10-resolver</td><td align="left">resolver</td><td align="left">The resolver</td></tr><tr><td align="left">b10-cmdctl</td><td align="left">cmdctl</td><td align="left">The command control (remote control interface)</td></tr></tbody></table></div></div><p><br class="table-break">
</p><p>
The kind specifies how a failure of the component should
be handled. If it is set to <span class="quote">“<span class="quote">dispensable</span>”</span>
@@ -623,12 +635,12 @@ shutdown
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="#idp200360">8.1. Server Configurations</a></span></dt><dt><span class="section"><a href="#idp205096">8.2. Data Source Backends</a></span></dt><dt><span class="section"><a href="#idp207592">8.3. 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="#id1168229437990">8.1. Server Configurations</a></span></dt><dt><span class="section"><a href="#id1168229438055">8.2. Data Source Backends</a></span></dt><dt><span class="section"><a href="#id1168229438085">8.3. 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
process.
- </p><div class="section" title="8.1. Server Configurations"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="idp200360"></a>8.1. Server Configurations</h2></div></div></div><p>
+ </p><div class="section" title="8.1. Server Configurations"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229437990"></a>8.1. 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>.
@@ -648,7 +660,7 @@ This may be a temporary setting until then.
</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="8.2. Data Source Backends"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="idp205096"></a>8.2. 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="8.2. Data Source Backends"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229438055"></a>8.2. 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>
supports a SQLite3 data source backend and in-memory data source
backend.
@@ -662,7 +674,7 @@ This may be a temporary setting until then.
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="8.3. Loading Master Zones Files"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="idp207592"></a>8.3. Loading Master Zones Files</h2></div></div></div><p>
+ </p></div><div class="section" title="8.3. Loading Master Zones Files"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229438085"></a>8.3. 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.
@@ -691,7 +703,7 @@ This may be a temporary setting until then.
If you reload a zone already existing in the database,
all records from that prior zone disappear and a whole new set
appears.
- </p></div></div><div class="chapter" title="Chapter 9. Incoming Zone Transfers"><div class="titlepage"><div><div><h2 class="title"><a name="xfrin"></a>Chapter 9. Incoming Zone Transfers</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#idp217864">9.1. Configuration for Incoming Zone Transfers</a></span></dt><dt><span class="section"><a href="#idp220904">9.2. Enabling IXFR</a></span></dt><dt><span class="section"><a href="#zonemgr">9.3. Secondary Manager</a></span></dt><dt><span class="section"><a href="#idp11976">9.4. Trigger an Incoming Zone Transfer Manually</a></span></dt></dl></div><p>
+ </p></div></div><div class="chapter" title="Chapter 9. Incoming Zone Transfers"><div class="titlepage"><div><div><h2 class="title"><a name="xfrin"></a>Chapter 9. Incoming Zone Transfers</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168229438216">9.1. Configuration for Incoming Zone Transfers</a></span></dt><dt><span class="section"><a href="#id1168229438254">9.2. Enabling IXFR</a></span></dt><dt><span class="section"><a href="#zonemgr">9.3. Secondary Manager</a></span></dt><dt><span class="section"><a href="#id1168229438369">9.4. Trigger an Incoming Zone Transfer Manually</a></span></dt></dl></div><p>
Incoming zones are transferred using the <span class="command"><strong>b10-xfrin</strong></span>
process which is started by <span class="command"><strong>bind10</strong></span>.
When received, the zone is stored in the corresponding BIND 10
@@ -709,7 +721,7 @@ This may be a temporary setting until then.
In the current development release of BIND 10, incoming zone
transfers are only available for SQLite3-based data sources,
that is, they don't work for an in-memory data source.
- </p></div><div class="section" title="9.1. Configuration for Incoming Zone Transfers"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="idp217864"></a>9.1. Configuration for Incoming Zone Transfers</h2></div></div></div><p>
+ </p></div><div class="section" title="9.1. Configuration for Incoming Zone Transfers"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229438216"></a>9.1. Configuration for Incoming Zone Transfers</h2></div></div></div><p>
In practice, you need to specify a list of secondary zones to
enable incoming zone transfers for these zones (you can still
trigger a zone transfer manually, without a prior configuration
@@ -725,7 +737,7 @@ This may be a temporary setting until then.
> <strong class="userinput"><code>config commit</code></strong></pre><p>
(We assume there has been no zone configuration before).
- </p></div><div class="section" title="9.2. Enabling IXFR"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="idp220904"></a>9.2. Enabling IXFR</h2></div></div></div><p>
+ </p></div><div class="section" title="9.2. Enabling IXFR"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229438254"></a>9.2. Enabling IXFR</h2></div></div></div><p>
As noted above, <span class="command"><strong>b10-xfrin</strong></span> uses AXFR for
zone transfers by default. To enable IXFR for zone transfers
for a particular zone, set the <strong class="userinput"><code>use_ixfr</code></strong>
@@ -777,7 +789,7 @@ This may be a temporary setting until then.
(i.e. no SOA record for it), <span class="command"><strong>b10-zonemgr</strong></span>
will automatically tell <span class="command"><strong>b10-xfrin</strong></span>
to transfer the zone in.
- </p></div><div class="section" title="9.4. Trigger an Incoming Zone Transfer Manually"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="idp11976"></a>9.4. Trigger an Incoming Zone Transfer Manually</h2></div></div></div><p>
+ </p></div><div class="section" title="9.4. Trigger an Incoming Zone Transfer Manually"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229438369"></a>9.4. Trigger an Incoming Zone Transfer Manually</h2></div></div></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.
For example, at the <span class="command"><strong>bindctl</strong></span> prompt run:
@@ -815,26 +827,18 @@ Xfrout/transfer_acl[0] {"action": "ACCEPT"} any (default)</pre><p>
for <code class="option">transfer_acl</code> were divided for
readability. In the actual input it must be in a single line.
</p></div><p>
- If you want to require TSIG in access control, a separate TSIG
- "key ring" must be configured specifically
- for <span class="command"><strong>b10-xfrout</strong></span> as well as a system wide
- key ring, both containing a consistent set of keys.
+ If you want to require TSIG in access control, a system wide TSIG
+ "key ring" must be configured.
For example, to change the previous example to allowing requests
from 192.0.2.1 signed by a TSIG with a key name of
"key.example", you'll need to do this:
</p><pre class="screen">> <strong class="userinput"><code>config set tsig_keys/keys ["key.example:<base64-key>"]</code></strong>
-> <strong class="userinput"><code>config set Xfrout/tsig_keys/keys ["key.example:<base64-key>"]</code></strong>
> <strong class="userinput"><code>config set Xfrout/zone_config[0]/transfer_acl [{"action": "ACCEPT", "from": "192.0.2.1", "key": "key.example"}]</code></strong>
-> <strong class="userinput"><code>config commit</code></strong></pre><p>
- The first line of configuration defines a system wide key ring.
- This is necessary because the <span class="command"><strong>b10-auth</strong></span> server
- also checks TSIGs and it uses the system wide configuration.
- </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
- In a future version, <span class="command"><strong>b10-xfrout</strong></span> will also
- use the system wide TSIG configuration.
+> <strong class="userinput"><code>config commit</code></strong></pre><p>Both Xfrout and Auth will use the system wide keyring to check
+ TSIGs in the incomming messages and to sign responses.</p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
The way to specify zone specific configuration (ACLs, etc) is
- likely to be changed, too.
- </p></div></div><div class="chapter" title="Chapter 11. Recursive Name Server"><div class="titlepage"><div><div><h2 class="title"><a name="resolverserver"></a>Chapter 11. Recursive Name Server</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#idp259896">11.1. Access Control</a></span></dt><dt><span class="section"><a href="#idp269088">11.2. Forwarding</a></span></dt></dl></div><p>
+ likely to be changed.
+ </p></div></div><div class="chapter" title="Chapter 11. Recursive Name Server"><div class="titlepage"><div><div><h2 class="title"><a name="resolverserver"></a>Chapter 11. Recursive Name Server</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168229438715">11.1. Access Control</a></span></dt><dt><span class="section"><a href="#id1168229438900">11.2. Forwarding</a></span></dt></dl></div><p>
The <span class="command"><strong>b10-resolver</strong></span> process is started by
<span class="command"><strong>bind10</strong></span>.
@@ -873,7 +877,7 @@ Xfrout/transfer_acl[0] {"action": "ACCEPT"} any (default)</pre><p>
</pre><p>
</p><p>(Replace the <span class="quote">“<span class="quote"><em class="replaceable"><code>2</code></em></span>”</span>
as needed; run <span class="quote">“<span class="quote"><strong class="userinput"><code>config show
- Resolver/listen_on</code></strong></span>”</span> if needed.)</p><div class="section" title="11.1. Access Control"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="idp259896"></a>11.1. Access Control</h2></div></div></div><p>
+ Resolver/listen_on</code></strong></span>”</span> if needed.)</p><div class="section" title="11.1. Access Control"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229438715"></a>11.1. Access Control</h2></div></div></div><p>
By default, the <span class="command"><strong>b10-resolver</strong></span> daemon only accepts
DNS queries from the localhost (127.0.0.1 and ::1).
The <code class="option">Resolver/query_acl</code> configuration may
@@ -906,7 +910,7 @@ Xfrout/transfer_acl[0] {"action": "ACCEPT"} any (default)</pre><p>
</pre><p>(Replace the <span class="quote">“<span class="quote"><em class="replaceable"><code>2</code></em></span>”</span>
as needed; run <span class="quote">“<span class="quote"><strong class="userinput"><code>config show
Resolver/query_acl</code></strong></span>”</span> if needed.)</p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>This prototype access control configuration
- syntax may be changed.</p></div></div><div class="section" title="11.2. Forwarding"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="idp269088"></a>11.2. Forwarding</h2></div></div></div><p>
+ syntax may be changed.</p></div></div><div class="section" title="11.2. Forwarding"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229438900"></a>11.2. Forwarding</h2></div></div></div><p>
To enable forwarding, the upstream address and port must be
configured to forward queries to, such as:
@@ -1218,7 +1222,7 @@ eth0 fe80::21e:8cff:fe9b:7349
}
}
</pre><p>
- </p></div><div class="chapter" title="Chapter 16. Logging"><div class="titlepage"><div><div><h2 class="title"><a name="logging"></a>Chapter 16. Logging</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#idp327280">16.1. Logging configuration</a></span></dt><dd><dl><dt><span class="section"><a href="#idp328272">16.1.1. Loggers</a></span></dt><dt><span class="section"><a href="#idp349480">16.1.2. Output Options</a></span></dt><dt><span class="section"><a href="#idp362088">16.1.3. Example session</a></span></dt></dl></dd><dt><span class="section"><a href="#idp379592">16.2. Logging Message Format</a></span></dt></dl></div><div class="section" title="16.1. Logging configuration"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="idp327280"></a>16.1. Logging configuration</h2></div></div></div><p>
+ </p></div><div class="chapter" title="Chapter 16. Logging"><div class="titlepage"><div><div><h2 class="title"><a name="logging"></a>Chapter 16. Logging</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168229440014">16.1. Logging configuration</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229440025">16.1.1. Loggers</a></span></dt><dt><span class="section"><a href="#id1168229440268">16.1.2. Output Options</a></span></dt><dt><span class="section"><a href="#id1168229440509">16.1.3. Example session</a></span></dt></dl></dd><dt><span class="section"><a href="#id1168229440720">16.2. Logging Message Format</a></span></dt></dl></div><div class="section" title="16.1. Logging configuration"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229440014"></a>16.1. Logging configuration</h2></div></div></div><p>
The logging system in BIND 10 is configured through the
Logging module. All BIND 10 modules will look at the
@@ -1227,7 +1231,7 @@ eth0 fe80::21e:8cff:fe9b:7349
- </p><div class="section" title="16.1.1. Loggers"><div class="titlepage"><div><div><h3 class="title"><a name="idp328272"></a>16.1.1. Loggers</h3></div></div></div><p>
+ </p><div class="section" title="16.1.1. Loggers"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229440025"></a>16.1.1. Loggers</h3></div></div></div><p>
Within BIND 10, a message is logged through a component
called a "logger". Different parts of BIND 10 log messages
@@ -1248,7 +1252,7 @@ eth0 fe80::21e:8cff:fe9b:7349
(what to log), and the <code class="option">output_options</code>
(where to log).
- </p><div class="section" title="16.1.1.1. name (string)"><div class="titlepage"><div><div><h4 class="title"><a name="idp330520"></a>16.1.1.1. name (string)</h4></div></div></div><p>
+ </p><div class="section" title="16.1.1.1. name (string)"><div class="titlepage"><div><div><h4 class="title"><a name="id1168229440051"></a>16.1.1.1. name (string)</h4></div></div></div><p>
Each logger in the system has a name, the name being that
of the component using it to log messages. For instance,
if you want to configure logging for the resolver module,
@@ -1321,7 +1325,7 @@ eth0 fe80::21e:8cff:fe9b:7349
<span class="quote">“<span class="quote">Auth.cache</span>”</span> logger will appear in the output
with a logger name of <span class="quote">“<span class="quote">b10-auth.cache</span>”</span>).
- </p></div><div class="section" title="16.1.1.2. severity (string)"><div class="titlepage"><div><div><h4 class="title"><a name="idp340304"></a>16.1.1.2. severity (string)</h4></div></div></div><p>
+ </p></div><div class="section" title="16.1.1.2. severity (string)"><div class="titlepage"><div><div><h4 class="title"><a name="id1168229440150"></a>16.1.1.2. severity (string)</h4></div></div></div><p>
This specifies the category of messages logged.
Each message is logged with an associated severity which
@@ -1337,7 +1341,7 @@ eth0 fe80::21e:8cff:fe9b:7349
- </p></div><div class="section" title="16.1.1.3. output_options (list)"><div class="titlepage"><div><div><h4 class="title"><a name="idp344096"></a>16.1.1.3. output_options (list)</h4></div></div></div><p>
+ </p></div><div class="section" title="16.1.1.3. output_options (list)"><div class="titlepage"><div><div><h4 class="title"><a name="id1168229440201"></a>16.1.1.3. output_options (list)</h4></div></div></div><p>
Each logger can have zero or more
<code class="option">output_options</code>. These specify where log
@@ -1347,7 +1351,7 @@ eth0 fe80::21e:8cff:fe9b:7349
The other options for a logger are:
- </p></div><div class="section" title="16.1.1.4. debuglevel (integer)"><div class="titlepage"><div><div><h4 class="title"><a name="idp345320"></a>16.1.1.4. debuglevel (integer)</h4></div></div></div><p>
+ </p></div><div class="section" title="16.1.1.4. debuglevel (integer)"><div class="titlepage"><div><div><h4 class="title"><a name="id1168229440217"></a>16.1.1.4. debuglevel (integer)</h4></div></div></div><p>
When a logger's severity is set to DEBUG, this value
specifies what debug messages should be printed. It ranges
@@ -1356,7 +1360,7 @@ eth0 fe80::21e:8cff:fe9b:7349
If severity for the logger is not DEBUG, this value is ignored.
- </p></div><div class="section" title="16.1.1.5. additive (true or false)"><div class="titlepage"><div><div><h4 class="title"><a name="idp346760"></a>16.1.1.5. additive (true or false)</h4></div></div></div><p>
+ </p></div><div class="section" title="16.1.1.5. additive (true or false)"><div class="titlepage"><div><div><h4 class="title"><a name="id1168229440232"></a>16.1.1.5. additive (true or false)</h4></div></div></div><p>
If this is true, the <code class="option">output_options</code> from
the parent will be used. For example, if there are two
@@ -1370,18 +1374,18 @@ eth0 fe80::21e:8cff:fe9b:7349
- </p></div></div><div class="section" title="16.1.2. Output Options"><div class="titlepage"><div><div><h3 class="title"><a name="idp349480"></a>16.1.2. Output Options</h3></div></div></div><p>
+ </p></div></div><div class="section" title="16.1.2. Output Options"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229440268"></a>16.1.2. Output Options</h3></div></div></div><p>
The main settings for an output option are the
<code class="option">destination</code> and a value called
<code class="option">output</code>, the meaning of which depends on
the destination that is set.
- </p><div class="section" title="16.1.2.1. destination (string)"><div class="titlepage"><div><div><h4 class="title"><a name="idp350616"></a>16.1.2.1. destination (string)</h4></div></div></div><p>
+ </p><div class="section" title="16.1.2.1. destination (string)"><div class="titlepage"><div><div><h4 class="title"><a name="id1168229440283"></a>16.1.2.1. destination (string)</h4></div></div></div><p>
The destination is the type of output. It can be one of:
- </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> console </li><li class="listitem"> file </li><li class="listitem"> syslog </li></ul></div></div><div class="section" title="16.1.2.2. output (string)"><div class="titlepage"><div><div><h4 class="title"><a name="idp352704"></a>16.1.2.2. output (string)</h4></div></div></div><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> console </li><li class="listitem"> file </li><li class="listitem"> syslog </li></ul></div></div><div class="section" title="16.1.2.2. output (string)"><div class="titlepage"><div><div><h4 class="title"><a name="id1168229440385"></a>16.1.2.2. output (string)</h4></div></div></div><p>
Depending on what is set as the output destination, this
value is interpreted as follows:
@@ -1403,12 +1407,12 @@ eth0 fe80::21e:8cff:fe9b:7349
The other options for <code class="option">output_options</code> are:
- </p><div class="section" title="16.1.2.2.1. flush (true of false)"><div class="titlepage"><div><div><h5 class="title"><a name="idp358664"></a>16.1.2.2.1. flush (true of false)</h5></div></div></div><p>
+ </p><div class="section" title="16.1.2.2.1. flush (true of false)"><div class="titlepage"><div><div><h5 class="title"><a name="id1168229440469"></a>16.1.2.2.1. flush (true of false)</h5></div></div></div><p>
Flush buffers after each log message. Doing this will
reduce performance but will ensure that if the program
terminates abnormally, all messages up to the point of
termination are output.
- </p></div><div class="section" title="16.1.2.2.2. maxsize (integer)"><div class="titlepage"><div><div><h5 class="title"><a name="idp359528"></a>16.1.2.2.2. maxsize (integer)</h5></div></div></div><p>
+ </p></div><div class="section" title="16.1.2.2.2. maxsize (integer)"><div class="titlepage"><div><div><h5 class="title"><a name="id1168229440478"></a>16.1.2.2.2. maxsize (integer)</h5></div></div></div><p>
Only relevant when destination is file, this is maximum
file size of output files in bytes. When the maximum
size is reached, the file is renamed and a new file opened.
@@ -1417,11 +1421,11 @@ eth0 fe80::21e:8cff:fe9b:7349
etc.)
</p><p>
If this is 0, no maximum file size is used.
- </p></div><div class="section" title="16.1.2.2.3. maxver (integer)"><div class="titlepage"><div><div><h5 class="title"><a name="idp360776"></a>16.1.2.2.3. maxver (integer)</h5></div></div></div><p>
+ </p></div><div class="section" title="16.1.2.2.3. maxver (integer)"><div class="titlepage"><div><div><h5 class="title"><a name="id1168229440491"></a>16.1.2.2.3. maxver (integer)</h5></div></div></div><p>
Maximum number of old log files to keep around when
rolling the output file. Only relevant when
<code class="option">destination</code> is <span class="quote">“<span class="quote">file</span>”</span>.
- </p></div></div></div><div class="section" title="16.1.3. Example session"><div class="titlepage"><div><div><h3 class="title"><a name="idp362088"></a>16.1.3. Example session</h3></div></div></div><p>
+ </p></div></div></div><div class="section" title="16.1.3. Example session"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229440509"></a>16.1.3. Example session</h3></div></div></div><p>
In this example we want to set the global logging to
write to the file <code class="filename">/var/log/my_bind10.log</code>,
@@ -1582,7 +1586,7 @@ Logging/loggers[0]/output_options[0]/maxver 8 integer (modified)
And every module will now be using the values from the
logger named <span class="quote">“<span class="quote">*</span>”</span>.
- </p></div></div><div class="section" title="16.2. Logging Message Format"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="idp379592"></a>16.2. Logging Message Format</h2></div></div></div><p>
+ </p></div></div><div class="section" title="16.2. Logging Message Format"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229440720"></a>16.2. Logging Message Format</h2></div></div></div><p>
Each message written by BIND 10 to the configured logging
destinations comprises a number of components that identify
the origin of the message and, if the message indicates
diff --git a/doc/guide/bind10-guide.txt b/doc/guide/bind10-guide.txt
index 7ec35e6..aad5c04 100644
--- a/doc/guide/bind10-guide.txt
+++ b/doc/guide/bind10-guide.txt
@@ -221,18 +221,22 @@ Chapter 1. Introduction
processes as needed. The processes started by the bind10 command have
names starting with "b10-", including:
- o b10-msgq -- Message bus daemon. This process coordinates communication
- between all of the other BIND 10 processes.
o b10-auth -- Authoritative DNS server. This process serves DNS
requests.
o b10-cfgmgr -- Configuration manager. This process maintains all of the
configuration for BIND 10.
o b10-cmdctl -- Command and control service. This process allows
external control of the BIND 10 system.
+ o b10-msgq -- Message bus daemon. This process coordinates communication
+ between all of the other BIND 10 processes.
o b10-resolver -- Recursive name server. This process handles incoming
queries.
+ o b10-sockcreator -- Socket creator daemon. This process creates sockets
+ used by network-listening BIND 10 processes.
o b10-stats -- Statistics collection daemon. This process collects and
reports statistics data.
+ o b10-stats-httpd -- HTTP server for statistics reporting. This process
+ reports statistics data in XML format over HTTP.
o b10-xfrin -- Incoming zone transfer service. This process is used to
transfer a new copy of a zone into BIND 10, when acting as a secondary
server.
@@ -249,8 +253,9 @@ Chapter 1. Introduction
Once BIND 10 is running, a few commands are used to interact directly with
the system:
- o bindctl -- interactive administration interface. This is a
- command-line tool which allows an administrator to control BIND 10.
+ o bindctl -- interactive administration interface. This is a low-level
+ command-line tool which allows a developer or an experienced
+ administrator to control BIND 10.
o b10-loadzone -- zone file loader. This tool will load standard
masterfile-format zone files into BIND 10.
o b10-cmdctl-usermgr -- user access control. This tool allows an
@@ -491,10 +496,11 @@ Chapter 3. Starting BIND10 with bind10
b10-sockcreator will allocate sockets for the rest of the system.
In its default configuration, the bind10 master process will also start up
- b10-cmdctl for admins to communicate with the system, b10-auth for
- authoritative DNS service, b10-stats for statistics collection, b10-xfrin
- for inbound DNS zone transfers, b10-xfrout for outbound DNS zone
- transfers, and b10-zonemgr for secondary service.
+ b10-cmdctl for administration tools to communicate with the system,
+ b10-auth for authoritative DNS service, b10-stats for statistics
+ collection, b10-stats-httpd for statistics reporting, b10-xfrin for
+ inbound DNS zone transfers, b10-xfrout for outbound DNS zone transfers,
+ and b10-zonemgr for secondary service.
3.1. Starting BIND 10
@@ -600,6 +606,22 @@ Chapter 3. Starting BIND10 with bind10
In short, you should think twice before disabling something here.
+ It is possible to start some components multiple times (currently b10-auth
+ and b10-resolzer). You might want to do that to gain more performance
+ (each one uses only single core). Just put multiple entries under
+ different names, like this, with the same config:
+
+ > config add Boss/components b10-resolver-2
+ > config set Boss/components/b10-resolver-2/special resolver
+ > config set Boss/components/b10-resolver-2/kind needed
+ > config commit
+
+ However, this is work in progress and the support is not yet complete. For
+ example, each resolver will have its own cache, each authoritative server
+ will keep its own copy of in-memory data and there could be problems with
+ locking the sqlite database, if used. The configuration might be changed
+ to something more convenient in future.
+
Chapter 4. Command channel
The BIND 10 components use the b10-msgq message routing daemon to
@@ -939,26 +961,22 @@ Chapter 10. Outbound Zone Transfers
In the above example the lines for transfer_acl were divided for
readability. In the actual input it must be in a single line.
- If you want to require TSIG in access control, a separate TSIG "key ring"
- must be configured specifically for b10-xfrout as well as a system wide
- key ring, both containing a consistent set of keys. For example, to change
- the previous example to allowing requests from 192.0.2.1 signed by a TSIG
- with a key name of "key.example", you'll need to do this:
+ If you want to require TSIG in access control, a system wide TSIG "key
+ ring" must be configured. For example, to change the previous example to
+ allowing requests from 192.0.2.1 signed by a TSIG with a key name of
+ "key.example", you'll need to do this:
> config set tsig_keys/keys ["key.example:<base64-key>"]
- > config set Xfrout/tsig_keys/keys ["key.example:<base64-key>"]
> config set Xfrout/zone_config[0]/transfer_acl [{"action": "ACCEPT", "from": "192.0.2.1", "key": "key.example"}]
> config commit
- The first line of configuration defines a system wide key ring. This is
- necessary because the b10-auth server also checks TSIGs and it uses the
- system wide configuration.
+ Both Xfrout and Auth will use the system wide keyring to check TSIGs in
+ the incomming messages and to sign responses.
Note
- In a future version, b10-xfrout will also use the system wide TSIG
- configuration. The way to specify zone specific configuration (ACLs, etc)
- is likely to be changed, too.
+ The way to specify zone specific configuration (ACLs, etc) is likely to be
+ changed.
Chapter 11. Recursive Name Server
diff --git a/doc/guide/bind10-guide.xml b/doc/guide/bind10-guide.xml
index eafbbd8..6b95c3e 100644
--- a/doc/guide/bind10-guide.xml
+++ b/doc/guide/bind10-guide.xml
@@ -172,15 +172,6 @@
<listitem>
<simpara>
- <command>b10-msgq</command> —
- Message bus daemon.
- This process coordinates communication between all of the other
- BIND 10 processes.
- </simpara>
- </listitem>
-
- <listitem>
- <simpara>
<command>b10-auth</command> —
Authoritative DNS server.
This process serves DNS requests.
@@ -205,6 +196,15 @@
<listitem>
<simpara>
+ <command>b10-msgq</command> —
+ Message bus daemon.
+ This process coordinates communication between all of the other
+ BIND 10 processes.
+ </simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>
<command>b10-resolver</command> —
Recursive name server.
This process handles incoming queries.
@@ -214,6 +214,15 @@
<listitem>
<simpara>
+ <command>b10-sockcreator</command> —
+ Socket creator daemon.
+ This process creates sockets used by
+ network-listening BIND 10 processes.
+ </simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>
<command>b10-stats</command> —
Statistics collection daemon.
This process collects and reports statistics data.
@@ -222,6 +231,14 @@
<listitem>
<simpara>
+ <command>b10-stats-httpd</command> —
+ HTTP server for statistics reporting.
+ This process reports statistics data in XML format over HTTP.
+ </simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>
<command>b10-xfrin</command> —
Incoming zone transfer service.
This process is used to transfer a new copy
@@ -269,8 +286,9 @@
<simpara>
<command>bindctl</command> —
interactive administration interface.
- This is a command-line tool which allows an administrator
- to control BIND 10.
+ This is a low-level command-line tool which allows
+ a developer or an experienced administrator to control
+ BIND 10.
</simpara>
</listitem>
<listitem>
@@ -751,9 +769,11 @@ as a dependency earlier -->
<para>
In its default configuration, 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-cmdctl</command> for administration tools to
+ communicate with the system,
+ <command>b10-auth</command> for authoritative DNS service,
<command>b10-stats</command> for statistics collection,
+ <command>b10-stats-httpd</command> for statistics reporting,
<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.
@@ -889,7 +909,7 @@ address, but the usual ones don't." mean? -->
This system allows you to start the same component multiple times
(by including it in the configuration with different names, but the
same process setting). However, the rest of the system doesn't expect
- such situation, so it would probably not do what you want. Such
+ such a situation, so it would probably not do what you want. Such
support is yet to be implemented.
</para>
</note>
@@ -901,10 +921,10 @@ address, but the usual ones don't." mean? -->
<command>b10-cmdctl</command>, but then you couldn't
change it back the usual way, as it would require it to
be running (you would have to find and edit the configuration
- directly). Also, some modules might have dependencies
- -- <command>b10-stats-httpd</command> need
+ directly). Also, some modules might have dependencies:
+ <command>b10-stats-httpd</command> needs
<command>b10-stats</command>, <command>b10-xfrout</command>
- needs the <command>b10-auth</command> to be running, etc.
+ needs <command>b10-auth</command> to be running, etc.
<!-- TODO: should we define dependencies? -->
@@ -999,7 +1019,7 @@ Unix domain sockets
<!-- TODO -->
<note>
<para>
- The development prototype release only provides the
+ The development prototype release only provides
<command>bindctl</command> as a user interface to
<command>b10-cmdctl</command>.
Upcoming releases will provide another interactive command-line
@@ -1190,7 +1210,7 @@ or accounts database -->
The port can be set by using the <option>--port</option> command line option.
The address to listen on can be set using the <option>--address</option> command
line argument.
- Each HTTPS connection is stateless and timesout in 1200 seconds
+ Each HTTPS connection is stateless and times out in 1200 seconds
by default. This can be
redefined by using the <option>--idle-timeout</option> command line argument.
</para>
@@ -1629,31 +1649,23 @@ Xfrout/transfer_acl[0] {"action": "ACCEPT"} any (default)</screen>
</simpara></note>
<para>
- If you want to require TSIG in access control, a separate TSIG
- "key ring" must be configured specifically
- for <command>b10-xfrout</command> as well as a system wide
- key ring, both containing a consistent set of keys.
+ If you want to require TSIG in access control, a system wide TSIG
+ "key ring" must be configured.
For example, to change the previous example to allowing requests
from 192.0.2.1 signed by a TSIG with a key name of
"key.example", you'll need to do this:
</para>
<screen>> <userinput>config set tsig_keys/keys ["key.example:<base64-key>"]</userinput>
-> <userinput>config set Xfrout/tsig_keys/keys ["key.example:<base64-key>"]</userinput>
> <userinput>config set Xfrout/zone_config[0]/transfer_acl [{"action": "ACCEPT", "from": "192.0.2.1", "key": "key.example"}]</userinput>
> <userinput>config commit</userinput></screen>
- <para>
- The first line of configuration defines a system wide key ring.
- This is necessary because the <command>b10-auth</command> server
- also checks TSIGs and it uses the system wide configuration.
- </para>
+ <para>Both Xfrout and Auth will use the system wide keyring to check
+ TSIGs in the incomming messages and to sign responses.</para>
<note><simpara>
- In a future version, <command>b10-xfrout</command> will also
- use the system wide TSIG configuration.
The way to specify zone specific configuration (ACLs, etc) is
- likely to be changed, too.
+ likely to be changed.
</simpara></note>
<!--
@@ -2359,7 +2371,7 @@ eth0 fe80::21e:8cff:fe9b:7349
In the Logging module, you can specify the configuration
for zero or more loggers; any that are not specified will
- take appropriate default values..
+ take appropriate default values.
</para>
diff --git a/doc/guide/bind10-messages.html b/doc/guide/bind10-messages.html
index b82b485..d3bcb7c 100644
--- a/doc/guide/bind10-messages.html
+++ b/doc/guide/bind10-messages.html
@@ -1,10 +1,10 @@
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>BIND 10 Messages Manual</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="BIND 10 is a Domain Name System (DNS) suite managed by Internet Systems Consortium (ISC). It includes DNS libraries and modular components for controlling authoritative and recursive DNS servers. This is the messages manual for BIND 10 version 20111129. 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 Messages Manual"><div class="titlepage"><div><div><h1 class="title"><a name="id1168229451102"></a>BIND 10 Messages Manual</h1></div><div><p class="releaseinfo">This is the messages manual for BIND 10 version
- 20111129.</p></div><div><p class="copyright">Copyright © 2011-2012 Internet Systems Consortium, Inc.</p></div><div><div class="abstract" title="Abstract"><p class="title"><b>Abstract</b></p><p>BIND 10 is a Domain Name System (DNS) suite managed by
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>BIND 10 Messages Manual</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="BIND 10 is a Domain Name System (DNS) suite managed by Internet Systems Consortium (ISC). It includes DNS libraries and modular components for controlling authoritative and recursive DNS servers. This is the messages manual for BIND 10 version 20120127. 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 Messages Manual"><div class="titlepage"><div><div><h1 class="title"><a name="id1168229451102"></a>BIND 10 Messages Manual</h1></div><div><p class="releaseinfo">This is the messages manual for BIND 10 version
+ 20120127.</p></div><div><p class="copyright">Copyright © 2011-2012 Internet Systems Consortium, Inc.</p></div><div><div class="abstract" title="Abstract"><p class="title"><b>Abstract</b></p><p>BIND 10 is a Domain Name System (DNS) suite managed by
Internet Systems Consortium (ISC). It includes DNS libraries
and modular components for controlling authoritative and
recursive DNS servers.
</p><p>
- This is the messages manual for BIND 10 version 20111129.
+ This is the messages manual for BIND 10 version 20120127.
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>.
@@ -215,6 +215,9 @@ reason for the failure is included in the message.
</p></dd><dt><a name="AUTH_SERVER_STARTED"></a><span class="term">AUTH_SERVER_STARTED server started</span></dt><dd><p>
Initialization of the authoritative server has completed successfully
and it is entering the main loop, waiting for queries to arrive.
+</p></dd><dt><a name="AUTH_SHUTDOWN"></a><span class="term">AUTH_SHUTDOWN asked to stop, doing so</span></dt><dd><p>
+This is a debug message indicating the server was asked to shut down and it is
+complying to the request.
</p></dd><dt><a name="AUTH_SQLITE3"></a><span class="term">AUTH_SQLITE3 nothing to do for loading sqlite3</span></dt><dd><p>
This is a debug message indicating that the authoritative server has
found that the data source it is loading is an SQLite3 data source,
@@ -754,6 +757,16 @@ but will not send back an answer.
</p><p>
The most likely cause of this error is a programming error. Please raise
a bug report.
+</p></dd><dt><a name="CONFIG_CCSESSION_STOPPING"></a><span class="term">CONFIG_CCSESSION_STOPPING error sending stopping message: %1</span></dt><dd><p>
+There was a problem when sending a message signaling that the module using
+this CCSession is stopping. This message is sent so that the rest of the
+system is aware that the module is no longer running. Apart from logging
+this message, the error itself is ignored, and the ModuleCCSession is
+still stopped. The specific exception message is printed.
+</p></dd><dt><a name="CONFIG_CCSESSION_STOPPING_UNKNOWN"></a><span class="term">CONFIG_CCSESSION_STOPPING_UNKNOWN unknown error sending stopping message</span></dt><dd><p>
+Similar to CONFIG_CCSESSION_STOPPING, but in this case the exception that
+is seen is not a standard exception, and further information is unknown.
+This is a bug.
</p></dd><dt><a name="CONFIG_GET_FAIL"></a><span class="term">CONFIG_GET_FAIL error getting configuration from cfgmgr: %1</span></dt><dd><p>
The configuration manager returned an error when this module requested
the configuration. The full error message answer from the configuration
@@ -806,6 +819,18 @@ manager.
</p></dd><dt><a name="CONFIG_OPEN_FAIL"></a><span class="term">CONFIG_OPEN_FAIL error opening %1: %2</span></dt><dd><p>
There was an error opening the given file. The reason for the failure
is included in the message.
+</p></dd><dt><a name="CONFIG_SESSION_STOPPING_FAILED"></a><span class="term">CONFIG_SESSION_STOPPING_FAILED error sending stopping message: %1</span></dt><dd><p>
+There was a problem when sending a message signaling that the module using
+this CCSession is stopping. This message is sent so that the rest of the
+system is aware that the module is no longer running. Apart from logging
+this message, the error itself is ignored, and the ModuleCCSession is
+still stopped. The specific exception message is printed.
+</p></dd><dt><a name="DATASRC_BAD_NSEC3_NAME"></a><span class="term">DATASRC_BAD_NSEC3_NAME NSEC3 record has a bad owner name '%1'</span></dt><dd><p>
+The software refuses to load NSEC3 records into a wildcard domain or
+the owner name has two or more labels below the zone origin.
+It isn't explicitly forbidden, but no sane zone wouldn have such names
+for NSEC3. BIND 9 also refuses NSEC3 at wildcard, so this behavior is
+compatible with BIND 9.
</p></dd><dt><a name="DATASRC_CACHE_CREATE"></a><span class="term">DATASRC_CACHE_CREATE creating the hotspot cache</span></dt><dd><p>
This is a debug message issued during startup when the hotspot cache
is created.
@@ -935,24 +960,13 @@ name/type/class in the data source.
Debug information. A set of updates to a zone has been successfully
committed to the corresponding database backend. The zone name,
its class and the database name are printed.
-</p></dd><dt><a name="DATASRC_DATABASE_UPDATER_COMMIT%20(1)"></a><span class="term">DATASRC_DATABASE_UPDATER_COMMIT (1) updates committed for '%1/%2' on %3</span></dt><dd><p>
-Debug information. A set of updates to a zone has been successfully
-committed to the corresponding database backend. The zone name,
-its class and the database name are printed.
</p></dd><dt><a name="DATASRC_DATABASE_UPDATER_CREATED"></a><span class="term">DATASRC_DATABASE_UPDATER_CREATED zone updater created for '%1/%2' on %3</span></dt><dd><p>
Debug information. A zone updater object is created to make updates to
the shown zone on the shown backend database.
-</p></dd><dt><a name="DATASRC_DATABASE_UPDATER_CREATED%20(1)"></a><span class="term">DATASRC_DATABASE_UPDATER_CREATED (1) zone updater created for '%1/%2' on %3</span></dt><dd><p>
-Debug information. A zone updater object is created to make updates to
-the shown zone on the shown backend database.
</p></dd><dt><a name="DATASRC_DATABASE_UPDATER_DESTROYED"></a><span class="term">DATASRC_DATABASE_UPDATER_DESTROYED zone updater destroyed for '%1/%2' on %3</span></dt><dd><p>
Debug information. A zone updater object is destroyed, either successfully
or after failure of, making updates to the shown zone on the shown backend
database.
-</p></dd><dt><a name="DATASRC_DATABASE_UPDATER_DESTROYED%20(1)"></a><span class="term">DATASRC_DATABASE_UPDATER_DESTROYED (1) zone updater destroyed for '%1/%2' on %3</span></dt><dd><p>
-Debug information. A zone updater object is destroyed, either successfully
-or after failure of, making updates to the shown zone on the shown backend
-database.
</p></dd><dt><a name="DATASRC_DATABASE_UPDATER_ROLLBACK"></a><span class="term">DATASRC_DATABASE_UPDATER_ROLLBACK zone updates roll-backed for '%1/%2' on %3</span></dt><dd><p>
A zone updater is being destroyed without committing the changes.
This would typically mean the update attempt was aborted due to some
@@ -960,13 +974,6 @@ error, but may also be a bug of the application that forgets committing
the changes. The intermediate changes made through the updater won't
be applied to the underlying database. The zone name, its class, and
the underlying database name are shown in the log message.
-</p></dd><dt><a name="DATASRC_DATABASE_UPDATER_ROLLBACK%20(1)"></a><span class="term">DATASRC_DATABASE_UPDATER_ROLLBACK (1) zone updates roll-backed for '%1/%2' on %3</span></dt><dd><p>
-A zone updater is being destroyed without committing the changes.
-This would typically mean the update attempt was aborted due to some
-error, but may also be a bug of the application that forgets committing
-the changes. The intermediate changes made through the updater won't
-be applied to the underlying database. The zone name, its class, and
-the underlying database name are shown in the log message.
</p></dd><dt><a name="DATASRC_DATABASE_UPDATER_ROLLBACKFAIL"></a><span class="term">DATASRC_DATABASE_UPDATER_ROLLBACKFAIL failed to roll back zone updates for '%1/%2' on %3: %4</span></dt><dd><p>
A zone updater is being destroyed without committing the changes to
the database, and attempts to rollback incomplete updates, but it
@@ -979,18 +986,6 @@ examine the underlying data source to see what exactly happens and
whether the data is still valid. The zone name, its class, and the
underlying database name as well as the error message thrown from the
database module are shown in the log message.
-</p></dd><dt><a name="DATASRC_DATABASE_UPDATER_ROLLBACKFAIL%20(1)"></a><span class="term">DATASRC_DATABASE_UPDATER_ROLLBACKFAIL (1) failed to roll back zone updates for '%1/%2' on %3: %4</span></dt><dd><p>
-A zone updater is being destroyed without committing the changes to
-the database, and attempts to rollback incomplete updates, but it
-unexpectedly fails. The higher level implementation does not expect
-it to fail, so this means either a serious operational error in the
-underlying data source (such as a system failure of a database) or
-software bug in the underlying data source implementation. In either
-case if this message is logged the administrator should carefully
-examine the underlying data source to see what exactly happens and
-whether the data is still valid. The zone name, its class, and the
-underlying database name as well as the error message thrown from the
-database module are shown in the log message.
</p></dd><dt><a name="DATASRC_DATABASE_WILDCARD_ANY"></a><span class="term">DATASRC_DATABASE_WILDCARD_ANY search in datasource %1 resulted in wildcard match type ANY on %2</span></dt><dd><p>
The database doesn't contain directly matching name. When searching
for a wildcard match, a wildcard record matching the name of the query
@@ -1080,6 +1075,26 @@ this zone is not authoritative for the requested domain, but a delegation
should be followed. The requested domain is an apex of some zone.
</p></dd><dt><a name="DATASRC_MEM_FIND"></a><span class="term">DATASRC_MEM_FIND find '%1/%2'</span></dt><dd><p>
Debug information. A search for the requested RRset is being started.
+</p></dd><dt><a name="DATASRC_MEM_FINDNSEC3"></a><span class="term">DATASRC_MEM_FINDNSEC3 finding NSEC3 for %1, mode %2</span></dt><dd><p>
+Debug information. A search in an in-memory data source for NSEC3 that
+matches or covers the given name is being started.
+</p></dd><dt><a name="DATASRC_MEM_FINDNSEC3_COVER"></a><span class="term">DATASRC_MEM_FINDNSEC3_COVER found a covering NSEC3 for %1: %2</span></dt><dd><p>
+Debug information. An NSEC3 that covers the given name is found and
+being returned. The found NSEC3 RRset is also displayed.
+</p></dd><dt><a name="DATASRC_MEM_FINDNSEC3_MATCH"></a><span class="term">DATASRC_MEM_FINDNSEC3_MATCH found a matching NSEC3 for %1 at label count %2: %3</span></dt><dd><p>
+Debug information. An NSEC3 that matches (a possibly superdomain of)
+the given name is found and being returned. When the shown label
+count is smaller than that of the given name, the matching NSEC3 is
+for a superdomain of the given name (see DATASRC_MEM_FINDNSEC3_TRYHASH).
+The found NSEC3 RRset is also displayed.
+</p></dd><dt><a name="DATASRC_MEM_FINDNSEC3_TRYHASH"></a><span class="term">DATASRC_MEM_FINDNSEC3_TRYHASH looking for NSEC3 for %1 at label count %2 (hash %3)</span></dt><dd><p>
+Debug information. In an attempt of finding an NSEC3 for the give name,
+(a possibly superdomain of) the name is hashed and searched for in the
+NSEC3 name space. When the shown label count is smaller than that of the
+shown name, the search tries the superdomain name that share the shown
+(higher) label count of the shown name (e.g., for
+www.example.com. with shown label count of 3, example.com. is being
+tried).
</p></dd><dt><a name="DATASRC_MEM_FIND_ZONE"></a><span class="term">DATASRC_MEM_FIND_ZONE looking for zone '%1'</span></dt><dd><p>
Debug information. A zone object for this zone is being searched for in the
in-memory data source.
@@ -1087,6 +1102,13 @@ in-memory data source.
Debug information. The content of master file is being loaded into the memory.
</p></dd><dt><a name="DATASRC_MEM_NOT_FOUND"></a><span class="term">DATASRC_MEM_NOT_FOUND requested domain '%1' not found</span></dt><dd><p>
Debug information. The requested domain does not exist.
+</p></dd><dt><a name="DATASRC_MEM_NO_NSEC3PARAM"></a><span class="term">DATASRC_MEM_NO_NSEC3PARAM NSEC3PARAM is missing for NSEC3-signed zone %1/%2</span></dt><dd><p>
+The in-memory data source has loaded a zone signed with NSEC3 RRs,
+but it doesn't have a NSEC3PARAM RR at the zone origin. It's likely that
+the zone is somehow broken, but this RR is not necessarily needed for
+handling lookups with NSEC3 in this data source, so it accepts the given
+content of the zone. Nevertheless the administrator should look into
+the integrity of the zone data.
</p></dd><dt><a name="DATASRC_MEM_NS_ENCOUNTERED"></a><span class="term">DATASRC_MEM_NS_ENCOUNTERED encountered a NS</span></dt><dd><p>
Debug information. While searching for the requested domain, a NS was
encountered on the way (a delegation). This may lead to stop of the search.
@@ -1107,10 +1129,12 @@ Some resource types are singletons -- only one is allowed in a domain
(for example CNAME or SOA). This indicates a problem with provided data.
</p></dd><dt><a name="DATASRC_MEM_SUCCESS"></a><span class="term">DATASRC_MEM_SUCCESS query for '%1/%2' successful</span></dt><dd><p>
Debug information. The requested record was found.
-</p></dd><dt><a name="DATASRC_MEM_SUPER_STOP"></a><span class="term">DATASRC_MEM_SUPER_STOP stopped at superdomain '%1', domain '%2' is empty</span></dt><dd><p>
-Debug information. The search stopped at a superdomain of the requested
-domain. The domain is an empty nonterminal, therefore it is treated as NXRRSET
-case (eg. the domain exists, but it doesn't have the requested record type).
+</p></dd><dt><a name="DATASRC_MEM_SUPER_STOP"></a><span class="term">DATASRC_MEM_SUPER_STOP stopped as '%1' is superdomain of a zone node, meaning it's empty</span></dt><dd><p>
+Debug information. The search stopped because the requested domain was
+detected to be a superdomain of some existing node of zone (while there
+was no exact match). This means that the domain is an empty nonterminal,
+therefore it is treated as NXRRSET case (eg. the domain exists, but it
+doesn't have the requested record type).
</p></dd><dt><a name="DATASRC_MEM_SWAP"></a><span class="term">DATASRC_MEM_SWAP swapping contents of two zone representations ('%1' and '%2')</span></dt><dd><p>
Debug information. The contents of two in-memory zones are being exchanged.
This is usual practice to do some manipulation in exception-safe manner -- the
@@ -1247,7 +1271,7 @@ to prove the nonexistence.
The underlying data source failed to answer the query for referral information.
1 means some error, 2 is not implemented. The data source should have logged
the specific error already.
-</p></dd><dt><a name="DATASRC_QUERY_RRSIG"></a><span class="term">DATASRC_QUERY_RRSIG unable to answer RRSIG query</span></dt><dd><p>
+</p></dd><dt><a name="DATASRC_QUERY_RRSIG"></a><span class="term">DATASRC_QUERY_RRSIG unable to answer RRSIG query for %1</span></dt><dd><p>
The server is unable to answer a direct query for RRSIG type, but was asked
to do so.
</p></dd><dt><a name="DATASRC_QUERY_SIMPLE_FAIL"></a><span class="term">DATASRC_QUERY_SIMPLE_FAIL the underlying data source failed with %1</span></dt><dd><p>
@@ -1365,6 +1389,11 @@ data source.
</p></dd><dt><a name="DATASRC_UNEXPECTED_QUERY_STATE"></a><span class="term">DATASRC_UNEXPECTED_QUERY_STATE unexpected query state</span></dt><dd><p>
This indicates a programming error. An internal task of unknown type was
generated.
+</p></dd><dt><a name="DDNS_ACCEPT_FAILURE"></a><span class="term">DDNS_ACCEPT_FAILURE error accepting a connection: %1</span></dt><dd><p>
+There was a low-level error when we tried to accept an incoming connection
+(probably coming from b10-auth). We continue serving on whatever other
+connections we already have, but this connection is dropped. The reason
+is logged.
</p></dd><dt><a name="DDNS_CC_SESSION_ERROR"></a><span class="term">DDNS_CC_SESSION_ERROR error reading from cc channel: %1</span></dt><dd><p>
There was a problem reading from the command and control channel. The
most likely cause is that the msgq process is not running.
@@ -1375,18 +1404,33 @@ configuration manager b10-cfgmgr is not running.
</p></dd><dt><a name="DDNS_CONFIG_ERROR"></a><span class="term">DDNS_CONFIG_ERROR error found in configuration data: %1</span></dt><dd><p>
The ddns process encountered an error when installing the configuration at
startup time. Details of the error are included in the log message.
+</p></dd><dt><a name="DDNS_DROP_CONN"></a><span class="term">DDNS_DROP_CONN dropping connection on file descriptor %1 because of error %2</span></dt><dd><p>
+There was an error on a connection with the b10-auth server (or whatever
+connects to the ddns daemon). This might be OK, for example when the
+authoritative server shuts down, the connection would get closed. It also
+can mean the system is busy and can't keep up or that the other side got
+confused and sent bad data.
</p></dd><dt><a name="DDNS_MODULECC_SESSION_ERROR"></a><span class="term">DDNS_MODULECC_SESSION_ERROR error encountered by configuration/command module: %1</span></dt><dd><p>
There was a problem in the lower level module handling configuration and
control commands. This could happen for various reasons, but the most likely
cause is that the configuration database contains a syntax error and ddns
failed to start at initialization. A detailed error message from the module
will also be displayed.
+</p></dd><dt><a name="DDNS_NEW_CONN"></a><span class="term">DDNS_NEW_CONN new connection on file descriptor %1 from %2</span></dt><dd><p>
+Debug message. We received a connection and we are going to start handling
+requests from it. The file descriptor number and the address where the request
+comes from is logged. The connection is over a unix domain socket and is likely
+coming from a b10-auth process.
</p></dd><dt><a name="DDNS_RECEIVED_SHUTDOWN_COMMAND"></a><span class="term">DDNS_RECEIVED_SHUTDOWN_COMMAND shutdown command received</span></dt><dd><p>
The ddns process received a shutdown command from the command channel
and will now shut down.
</p></dd><dt><a name="DDNS_RUNNING"></a><span class="term">DDNS_RUNNING ddns server is running and listening for updates</span></dt><dd><p>
The ddns process has successfully started and is now ready to receive commands
and updates.
+</p></dd><dt><a name="DDNS_SESSION"></a><span class="term">DDNS_SESSION session arrived on file descriptor %1</span></dt><dd><p>
+A debug message, informing there's some activity on the given file descriptor.
+It will be either a request or the file descriptor will be closed. See
+following log messages to see what of it.
</p></dd><dt><a name="DDNS_SHUTDOWN"></a><span class="term">DDNS_SHUTDOWN ddns server shutting down</span></dt><dd><p>
The ddns process is shutting down. It will no longer listen for new commands
or updates. Any command or update that is being addressed at this moment will
@@ -1659,6 +1703,17 @@ an answer with a different given type and class.
</p><p>
This message indicates an internal error in the NSAS. Please raise a
bug report.
+</p></dd><dt><a name="PYSERVER_COMMON_TSIG_KEYRING_DEINIT"></a><span class="term">PYSERVER_COMMON_TSIG_KEYRING_DEINIT Deinitializing global TSIG keyring</span></dt><dd><p>
+A debug message noting that the global TSIG keyring is being removed from
+memory. Most programs don't do that, they just exit, which is OK.
+</p></dd><dt><a name="PYSERVER_COMMON_TSIG_KEYRING_INIT"></a><span class="term">PYSERVER_COMMON_TSIG_KEYRING_INIT Initializing global TSIG keyring</span></dt><dd><p>
+A debug message noting the TSIG keyring storage is being prepared. It should
+appear at most once in the lifetime of a program. The keyring still needs
+to be loaded from configuration.
+</p></dd><dt><a name="PYSERVER_COMMON_TSIG_KEYRING_UPDATE"></a><span class="term">PYSERVER_COMMON_TSIG_KEYRING_UPDATE Updating global TSIG keyring</span></dt><dd><p>
+A debug message. The TSIG keyring is being (re)loaded from configuration.
+This happens at startup or when the configuration changes. The old keyring
+is removed and new one created with all the keys.
</p></dd><dt><a name="RESLIB_ANSWER"></a><span class="term">RESLIB_ANSWER answer received in response to query for <%1></span></dt><dd><p>
A debug message reporting that an answer has been received to an upstream
query for the specified question. Previous debug messages will have
@@ -2009,6 +2064,9 @@ resolver. It is output during startup and may appear multiple times,
once for each root server address.
</p></dd><dt><a name="RESOLVER_SHUTDOWN"></a><span class="term">RESOLVER_SHUTDOWN resolver shutdown complete</span></dt><dd><p>
This informational message is output when the resolver has shut down.
+</p></dd><dt><a name="RESOLVER_SHUTDOWN%20(1)"></a><span class="term">RESOLVER_SHUTDOWN (1) asked to shut down, doing so</span></dt><dd><p>
+A debug message noting that the server was asked to terminate and is
+complying to the request.
</p></dd><dt><a name="RESOLVER_STARTED"></a><span class="term">RESOLVER_STARTED resolver started</span></dt><dd><p>
This informational message is output by the resolver when all initialization
has been completed and it is entering its main loop.
@@ -2022,7 +2080,7 @@ has been ignored.
This is debug message output when the resolver received a message with an
unsupported opcode (it can only process QUERY opcodes). It will return
a message to the sender with the RCODE set to NOTIMP.
-</p></dd><dt><a name="SOCKETREQUESTOR_CREATED"></a><span class="term">SOCKETREQUESTOR_CREATED Socket requestor created</span></dt><dd><p>
+</p></dd><dt><a name="SOCKETREQUESTOR_CREATED"></a><span class="term">SOCKETREQUESTOR_CREATED Socket requestor created for application %1</span></dt><dd><p>
Debug message. A socket requesor (client of the socket creator) is created
for the corresponding application. Normally this should happen at most
one time throughout the lifetime of the application.
@@ -2074,6 +2132,16 @@ Debug message. This lists one address and port value of the set of
addresses we are going to listen on (eg. there will be one log message
per pair). This appears only after SRVCOMM_SET_LISTEN, but might
be hidden, as it has higher debug level.
+</p></dd><dt><a name="SRVCOMM_EXCEPTION_ALLOC"></a><span class="term">SRVCOMM_EXCEPTION_ALLOC exception when allocating a socket: %1</span></dt><dd><p>
+The process tried to allocate a socket using the socket creator, but an error
+occurred. But it is not one of the errors we are sure are "safe". In this case
+it is unclear if the unsuccessful communication left the process and the bind10
+process in inconsistent state, so the process is going to abort to prevent
+further problems in that area.
+</p><p>
+This is probably a bug in the code, but it could be caused by other unusual
+conditions (like insufficient memory, deleted socket file used for
+communication).
</p></dd><dt><a name="SRVCOMM_KEYS_DEINIT"></a><span class="term">SRVCOMM_KEYS_DEINIT deinitializing TSIG keyring</span></dt><dd><p>
Debug message indicating that the server is deinitializing the TSIG keyring.
</p></dd><dt><a name="SRVCOMM_KEYS_INIT"></a><span class="term">SRVCOMM_KEYS_INIT initializing TSIG keyring</span></dt><dd><p>
@@ -2088,6 +2156,10 @@ specification is outside the valid range of 0 to 65535.
</p></dd><dt><a name="SRVCOMM_SET_LISTEN"></a><span class="term">SRVCOMM_SET_LISTEN setting addresses to listen to</span></dt><dd><p>
Debug message, noting that the server is about to start listening on a
different set of IP addresses and ports than before.
+</p></dd><dt><a name="SRVCOMM_UNKNOWN_EXCEPTION_ALLOC"></a><span class="term">SRVCOMM_UNKNOWN_EXCEPTION_ALLOC unknown exception when allocating a socket</span></dt><dd><p>
+The situation is the same as in the SRVCOMM_EXCEPTION_ALLOC case, but further
+details about the error are unknown, because it was signaled by throwing
+something not being an exception. This is definitely a bug.
</p></dd><dt><a name="STATHTTPD_BAD_OPTION_VALUE"></a><span class="term">STATHTTPD_BAD_OPTION_VALUE bad command line argument: %1</span></dt><dd><p>
The stats-httpd module was called with a bad command-line argument
and will not start.
diff --git a/doc/guide/bind10-messages.xml b/doc/guide/bind10-messages.xml
index c085cb1..fecefd0 100644
--- a/doc/guide/bind10-messages.xml
+++ b/doc/guide/bind10-messages.xml
@@ -467,6 +467,14 @@ and it is entering the main loop, waiting for queries to arrive.
</para></listitem>
</varlistentry>
+<varlistentry id="AUTH_SHUTDOWN">
+<term>AUTH_SHUTDOWN asked to stop, doing so</term>
+<listitem><para>
+This is a debug message indicating the server was asked to shut down and it is
+complying to the request.
+</para></listitem>
+</varlistentry>
+
<varlistentry id="AUTH_SQLITE3">
<term>AUTH_SQLITE3 nothing to do for loading sqlite3</term>
<listitem><para>
@@ -1766,6 +1774,26 @@ a bug report.
</para></listitem>
</varlistentry>
+<varlistentry id="CONFIG_CCSESSION_STOPPING">
+<term>CONFIG_CCSESSION_STOPPING error sending stopping message: %1</term>
+<listitem><para>
+There was a problem when sending a message signaling that the module using
+this CCSession is stopping. This message is sent so that the rest of the
+system is aware that the module is no longer running. Apart from logging
+this message, the error itself is ignored, and the ModuleCCSession is
+still stopped. The specific exception message is printed.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="CONFIG_CCSESSION_STOPPING_UNKNOWN">
+<term>CONFIG_CCSESSION_STOPPING_UNKNOWN unknown error sending stopping message</term>
+<listitem><para>
+Similar to CONFIG_CCSESSION_STOPPING, but in this case the exception that
+is seen is not a standard exception, and further information is unknown.
+This is a bug.
+</para></listitem>
+</varlistentry>
+
<varlistentry id="CONFIG_GET_FAIL">
<term>CONFIG_GET_FAIL error getting configuration from cfgmgr: %1</term>
<listitem><para>
@@ -1873,6 +1901,28 @@ is included in the message.
</para></listitem>
</varlistentry>
+<varlistentry id="CONFIG_SESSION_STOPPING_FAILED">
+<term>CONFIG_SESSION_STOPPING_FAILED error sending stopping message: %1</term>
+<listitem><para>
+There was a problem when sending a message signaling that the module using
+this CCSession is stopping. This message is sent so that the rest of the
+system is aware that the module is no longer running. Apart from logging
+this message, the error itself is ignored, and the ModuleCCSession is
+still stopped. The specific exception message is printed.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="DATASRC_BAD_NSEC3_NAME">
+<term>DATASRC_BAD_NSEC3_NAME NSEC3 record has a bad owner name '%1'</term>
+<listitem><para>
+The software refuses to load NSEC3 records into a wildcard domain or
+the owner name has two or more labels below the zone origin.
+It isn't explicitly forbidden, but no sane zone wouldn have such names
+for NSEC3. BIND 9 also refuses NSEC3 at wildcard, so this behavior is
+compatible with BIND 9.
+</para></listitem>
+</varlistentry>
+
<varlistentry id="DATASRC_CACHE_CREATE">
<term>DATASRC_CACHE_CREATE creating the hotspot cache</term>
<listitem><para>
@@ -2177,15 +2227,6 @@ its class and the database name are printed.
</para></listitem>
</varlistentry>
-<varlistentry id="DATASRC_DATABASE_UPDATER_COMMIT (1)">
-<term>DATASRC_DATABASE_UPDATER_COMMIT (1) updates committed for '%1/%2' on %3</term>
-<listitem><para>
-Debug information. A set of updates to a zone has been successfully
-committed to the corresponding database backend. The zone name,
-its class and the database name are printed.
-</para></listitem>
-</varlistentry>
-
<varlistentry id="DATASRC_DATABASE_UPDATER_CREATED">
<term>DATASRC_DATABASE_UPDATER_CREATED zone updater created for '%1/%2' on %3</term>
<listitem><para>
@@ -2194,14 +2235,6 @@ the shown zone on the shown backend database.
</para></listitem>
</varlistentry>
-<varlistentry id="DATASRC_DATABASE_UPDATER_CREATED (1)">
-<term>DATASRC_DATABASE_UPDATER_CREATED (1) zone updater created for '%1/%2' on %3</term>
-<listitem><para>
-Debug information. A zone updater object is created to make updates to
-the shown zone on the shown backend database.
-</para></listitem>
-</varlistentry>
-
<varlistentry id="DATASRC_DATABASE_UPDATER_DESTROYED">
<term>DATASRC_DATABASE_UPDATER_DESTROYED zone updater destroyed for '%1/%2' on %3</term>
<listitem><para>
@@ -2211,15 +2244,6 @@ database.
</para></listitem>
</varlistentry>
-<varlistentry id="DATASRC_DATABASE_UPDATER_DESTROYED (1)">
-<term>DATASRC_DATABASE_UPDATER_DESTROYED (1) zone updater destroyed for '%1/%2' on %3</term>
-<listitem><para>
-Debug information. A zone updater object is destroyed, either successfully
-or after failure of, making updates to the shown zone on the shown backend
-database.
-</para></listitem>
-</varlistentry>
-
<varlistentry id="DATASRC_DATABASE_UPDATER_ROLLBACK">
<term>DATASRC_DATABASE_UPDATER_ROLLBACK zone updates roll-backed for '%1/%2' on %3</term>
<listitem><para>
@@ -2232,18 +2256,6 @@ the underlying database name are shown in the log message.
</para></listitem>
</varlistentry>
-<varlistentry id="DATASRC_DATABASE_UPDATER_ROLLBACK (1)">
-<term>DATASRC_DATABASE_UPDATER_ROLLBACK (1) zone updates roll-backed for '%1/%2' on %3</term>
-<listitem><para>
-A zone updater is being destroyed without committing the changes.
-This would typically mean the update attempt was aborted due to some
-error, but may also be a bug of the application that forgets committing
-the changes. The intermediate changes made through the updater won't
-be applied to the underlying database. The zone name, its class, and
-the underlying database name are shown in the log message.
-</para></listitem>
-</varlistentry>
-
<varlistentry id="DATASRC_DATABASE_UPDATER_ROLLBACKFAIL">
<term>DATASRC_DATABASE_UPDATER_ROLLBACKFAIL failed to roll back zone updates for '%1/%2' on %3: %4</term>
<listitem><para>
@@ -2261,23 +2273,6 @@ database module are shown in the log message.
</para></listitem>
</varlistentry>
-<varlistentry id="DATASRC_DATABASE_UPDATER_ROLLBACKFAIL (1)">
-<term>DATASRC_DATABASE_UPDATER_ROLLBACKFAIL (1) failed to roll back zone updates for '%1/%2' on %3: %4</term>
-<listitem><para>
-A zone updater is being destroyed without committing the changes to
-the database, and attempts to rollback incomplete updates, but it
-unexpectedly fails. The higher level implementation does not expect
-it to fail, so this means either a serious operational error in the
-underlying data source (such as a system failure of a database) or
-software bug in the underlying data source implementation. In either
-case if this message is logged the administrator should carefully
-examine the underlying data source to see what exactly happens and
-whether the data is still valid. The zone name, its class, and the
-underlying database name as well as the error message thrown from the
-database module are shown in the log message.
-</para></listitem>
-</varlistentry>
-
<varlistentry id="DATASRC_DATABASE_WILDCARD_ANY">
<term>DATASRC_DATABASE_WILDCARD_ANY search in datasource %1 resulted in wildcard match type ANY on %2</term>
<listitem><para>
@@ -2497,6 +2492,46 @@ Debug information. A search for the requested RRset is being started.
</para></listitem>
</varlistentry>
+<varlistentry id="DATASRC_MEM_FINDNSEC3">
+<term>DATASRC_MEM_FINDNSEC3 finding NSEC3 for %1, mode %2</term>
+<listitem><para>
+Debug information. A search in an in-memory data source for NSEC3 that
+matches or covers the given name is being started.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="DATASRC_MEM_FINDNSEC3_COVER">
+<term>DATASRC_MEM_FINDNSEC3_COVER found a covering NSEC3 for %1: %2</term>
+<listitem><para>
+Debug information. An NSEC3 that covers the given name is found and
+being returned. The found NSEC3 RRset is also displayed.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="DATASRC_MEM_FINDNSEC3_MATCH">
+<term>DATASRC_MEM_FINDNSEC3_MATCH found a matching NSEC3 for %1 at label count %2: %3</term>
+<listitem><para>
+Debug information. An NSEC3 that matches (a possibly superdomain of)
+the given name is found and being returned. When the shown label
+count is smaller than that of the given name, the matching NSEC3 is
+for a superdomain of the given name (see DATASRC_MEM_FINDNSEC3_TRYHASH).
+The found NSEC3 RRset is also displayed.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="DATASRC_MEM_FINDNSEC3_TRYHASH">
+<term>DATASRC_MEM_FINDNSEC3_TRYHASH looking for NSEC3 for %1 at label count %2 (hash %3)</term>
+<listitem><para>
+Debug information. In an attempt of finding an NSEC3 for the give name,
+(a possibly superdomain of) the name is hashed and searched for in the
+NSEC3 name space. When the shown label count is smaller than that of the
+shown name, the search tries the superdomain name that share the shown
+(higher) label count of the shown name (e.g., for
+www.example.com. with shown label count of 3, example.com. is being
+tried).
+</para></listitem>
+</varlistentry>
+
<varlistentry id="DATASRC_MEM_FIND_ZONE">
<term>DATASRC_MEM_FIND_ZONE looking for zone '%1'</term>
<listitem><para>
@@ -2519,6 +2554,18 @@ Debug information. The requested domain does not exist.
</para></listitem>
</varlistentry>
+<varlistentry id="DATASRC_MEM_NO_NSEC3PARAM">
+<term>DATASRC_MEM_NO_NSEC3PARAM NSEC3PARAM is missing for NSEC3-signed zone %1/%2</term>
+<listitem><para>
+The in-memory data source has loaded a zone signed with NSEC3 RRs,
+but it doesn't have a NSEC3PARAM RR at the zone origin. It's likely that
+the zone is somehow broken, but this RR is not necessarily needed for
+handling lookups with NSEC3 in this data source, so it accepts the given
+content of the zone. Nevertheless the administrator should look into
+the integrity of the zone data.
+</para></listitem>
+</varlistentry>
+
<varlistentry id="DATASRC_MEM_NS_ENCOUNTERED">
<term>DATASRC_MEM_NS_ENCOUNTERED encountered a NS</term>
<listitem><para>
@@ -2570,11 +2617,13 @@ Debug information. The requested record was found.
</varlistentry>
<varlistentry id="DATASRC_MEM_SUPER_STOP">
-<term>DATASRC_MEM_SUPER_STOP stopped at superdomain '%1', domain '%2' is empty</term>
+<term>DATASRC_MEM_SUPER_STOP stopped as '%1' is superdomain of a zone node, meaning it's empty</term>
<listitem><para>
-Debug information. The search stopped at a superdomain of the requested
-domain. The domain is an empty nonterminal, therefore it is treated as NXRRSET
-case (eg. the domain exists, but it doesn't have the requested record type).
+Debug information. The search stopped because the requested domain was
+detected to be a superdomain of some existing node of zone (while there
+was no exact match). This means that the domain is an empty nonterminal,
+therefore it is treated as NXRRSET case (eg. the domain exists, but it
+doesn't have the requested record type).
</para></listitem>
</varlistentry>
@@ -2925,7 +2974,7 @@ the specific error already.
</varlistentry>
<varlistentry id="DATASRC_QUERY_RRSIG">
-<term>DATASRC_QUERY_RRSIG unable to answer RRSIG query</term>
+<term>DATASRC_QUERY_RRSIG unable to answer RRSIG query for %1</term>
<listitem><para>
The server is unable to answer a direct query for RRSIG type, but was asked
to do so.
@@ -3232,6 +3281,16 @@ generated.
</para></listitem>
</varlistentry>
+<varlistentry id="DDNS_ACCEPT_FAILURE">
+<term>DDNS_ACCEPT_FAILURE error accepting a connection: %1</term>
+<listitem><para>
+There was a low-level error when we tried to accept an incoming connection
+(probably coming from b10-auth). We continue serving on whatever other
+connections we already have, but this connection is dropped. The reason
+is logged.
+</para></listitem>
+</varlistentry>
+
<varlistentry id="DDNS_CC_SESSION_ERROR">
<term>DDNS_CC_SESSION_ERROR error reading from cc channel: %1</term>
<listitem><para>
@@ -3257,6 +3316,17 @@ startup time. Details of the error are included in the log message.
</para></listitem>
</varlistentry>
+<varlistentry id="DDNS_DROP_CONN">
+<term>DDNS_DROP_CONN dropping connection on file descriptor %1 because of error %2</term>
+<listitem><para>
+There was an error on a connection with the b10-auth server (or whatever
+connects to the ddns daemon). This might be OK, for example when the
+authoritative server shuts down, the connection would get closed. It also
+can mean the system is busy and can't keep up or that the other side got
+confused and sent bad data.
+</para></listitem>
+</varlistentry>
+
<varlistentry id="DDNS_MODULECC_SESSION_ERROR">
<term>DDNS_MODULECC_SESSION_ERROR error encountered by configuration/command module: %1</term>
<listitem><para>
@@ -3268,6 +3338,16 @@ will also be displayed.
</para></listitem>
</varlistentry>
+<varlistentry id="DDNS_NEW_CONN">
+<term>DDNS_NEW_CONN new connection on file descriptor %1 from %2</term>
+<listitem><para>
+Debug message. We received a connection and we are going to start handling
+requests from it. The file descriptor number and the address where the request
+comes from is logged. The connection is over a unix domain socket and is likely
+coming from a b10-auth process.
+</para></listitem>
+</varlistentry>
+
<varlistentry id="DDNS_RECEIVED_SHUTDOWN_COMMAND">
<term>DDNS_RECEIVED_SHUTDOWN_COMMAND shutdown command received</term>
<listitem><para>
@@ -3284,6 +3364,15 @@ and updates.
</para></listitem>
</varlistentry>
+<varlistentry id="DDNS_SESSION">
+<term>DDNS_SESSION session arrived on file descriptor %1</term>
+<listitem><para>
+A debug message, informing there's some activity on the given file descriptor.
+It will be either a request or the file descriptor will be closed. See
+following log messages to see what of it.
+</para></listitem>
+</varlistentry>
+
<varlistentry id="DDNS_SHUTDOWN">
<term>DDNS_SHUTDOWN ddns server shutting down</term>
<listitem><para>
@@ -3826,6 +3915,32 @@ bug report.
</para></listitem>
</varlistentry>
+<varlistentry id="PYSERVER_COMMON_TSIG_KEYRING_DEINIT">
+<term>PYSERVER_COMMON_TSIG_KEYRING_DEINIT Deinitializing global TSIG keyring</term>
+<listitem><para>
+A debug message noting that the global TSIG keyring is being removed from
+memory. Most programs don't do that, they just exit, which is OK.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="PYSERVER_COMMON_TSIG_KEYRING_INIT">
+<term>PYSERVER_COMMON_TSIG_KEYRING_INIT Initializing global TSIG keyring</term>
+<listitem><para>
+A debug message noting the TSIG keyring storage is being prepared. It should
+appear at most once in the lifetime of a program. The keyring still needs
+to be loaded from configuration.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="PYSERVER_COMMON_TSIG_KEYRING_UPDATE">
+<term>PYSERVER_COMMON_TSIG_KEYRING_UPDATE Updating global TSIG keyring</term>
+<listitem><para>
+A debug message. The TSIG keyring is being (re)loaded from configuration.
+This happens at startup or when the configuration changes. The old keyring
+is removed and new one created with all the keys.
+</para></listitem>
+</varlistentry>
+
<varlistentry id="RESLIB_ANSWER">
<term>RESLIB_ANSWER answer received in response to query for <%1></term>
<listitem><para>
@@ -4571,6 +4686,14 @@ This informational message is output when the resolver has shut down.
</para></listitem>
</varlistentry>
+<varlistentry id="RESOLVER_SHUTDOWN (1)">
+<term>RESOLVER_SHUTDOWN (1) asked to shut down, doing so</term>
+<listitem><para>
+A debug message noting that the server was asked to terminate and is
+complying to the request.
+</para></listitem>
+</varlistentry>
+
<varlistentry id="RESOLVER_STARTED">
<term>RESOLVER_STARTED resolver started</term>
<listitem><para>
@@ -4605,7 +4728,7 @@ a message to the sender with the RCODE set to NOTIMP.
</varlistentry>
<varlistentry id="SOCKETREQUESTOR_CREATED">
-<term>SOCKETREQUESTOR_CREATED Socket requestor created</term>
+<term>SOCKETREQUESTOR_CREATED Socket requestor created for application %1</term>
<listitem><para>
Debug message. A socket requesor (client of the socket creator) is created
for the corresponding application. Normally this should happen at most
@@ -4706,6 +4829,21 @@ be hidden, as it has higher debug level.
</para></listitem>
</varlistentry>
+<varlistentry id="SRVCOMM_EXCEPTION_ALLOC">
+<term>SRVCOMM_EXCEPTION_ALLOC exception when allocating a socket: %1</term>
+<listitem><para>
+The process tried to allocate a socket using the socket creator, but an error
+occurred. But it is not one of the errors we are sure are "safe". In this case
+it is unclear if the unsuccessful communication left the process and the bind10
+process in inconsistent state, so the process is going to abort to prevent
+further problems in that area.
+</para><para>
+This is probably a bug in the code, but it could be caused by other unusual
+conditions (like insufficient memory, deleted socket file used for
+communication).
+</para></listitem>
+</varlistentry>
+
<varlistentry id="SRVCOMM_KEYS_DEINIT">
<term>SRVCOMM_KEYS_DEINIT deinitializing TSIG keyring</term>
<listitem><para>
@@ -4745,6 +4883,15 @@ different set of IP addresses and ports than before.
</para></listitem>
</varlistentry>
+<varlistentry id="SRVCOMM_UNKNOWN_EXCEPTION_ALLOC">
+<term>SRVCOMM_UNKNOWN_EXCEPTION_ALLOC unknown exception when allocating a socket</term>
+<listitem><para>
+The situation is the same as in the SRVCOMM_EXCEPTION_ALLOC case, but further
+details about the error are unknown, because it was signaled by throwing
+something not being an exception. This is definitely a bug.
+</para></listitem>
+</varlistentry>
+
<varlistentry id="STATHTTPD_BAD_OPTION_VALUE">
<term>STATHTTPD_BAD_OPTION_VALUE bad command line argument: %1</term>
<listitem><para>
diff --git a/ext/asio/asio/detail/impl/kqueue_reactor.ipp b/ext/asio/asio/detail/impl/kqueue_reactor.ipp
index 8db77cb..00ebfeb 100644
--- a/ext/asio/asio/detail/impl/kqueue_reactor.ipp
+++ b/ext/asio/asio/detail/impl/kqueue_reactor.ipp
@@ -301,12 +301,14 @@ void kqueue_reactor::run(bool block, op_queue<operation>& ops)
EV_ADD | EV_ONESHOT, EV_OOBAND, 0, descriptor_data);
else
continue;
+ break;
case EVFILT_WRITE:
if (!descriptor_data->op_queue_[write_op].empty())
ASIO_KQUEUE_EV_SET(&event, descriptor, EVFILT_WRITE,
EV_ADD | EV_ONESHOT, 0, 0, descriptor_data);
else
continue;
+ break;
default:
break;
}
diff --git a/ext/asio/asio/detail/impl/socket_ops.ipp b/ext/asio/asio/detail/impl/socket_ops.ipp
index 66006ea..a1b0ec6 100644
--- a/ext/asio/asio/detail/impl/socket_ops.ipp
+++ b/ext/asio/asio/detail/impl/socket_ops.ipp
@@ -282,15 +282,26 @@ int close(socket_type s, state_type& state,
int result = 0;
if (s != invalid_socket)
{
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- if ((state & non_blocking) && (state & user_set_linger))
+ if (destruction && (state & user_set_linger))
{
- ioctl_arg_type arg = 0;
- ::ioctlsocket(s, FIONBIO, &arg);
- state &= ~non_blocking;
+ ::linger opt;
+ opt.l_onoff = 0;
+ opt.l_linger = 0;
+ asio::error_code ignored_ec;
+ socket_ops::setsockopt(s, state, SOL_SOCKET,
+ SO_LINGER, &opt, sizeof(opt), ignored_ec);
}
+
+ clear_last_error();
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ result = error_wrapper(::closesocket(s), ec);
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- if (state & non_blocking)
+ result = error_wrapper(::close(s), ec);
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
+ if (result != 0
+ && (ec == asio::error::would_block
+ || ec == asio::error::try_again))
{
#if defined(__SYMBIAN32__)
int flags = ::fcntl(s, F_GETFL, 0);
@@ -301,18 +312,6 @@ int close(socket_type s, state_type& state,
::ioctl(s, FIONBIO, &arg);
#endif // defined(__SYMBIAN32__)
state &= ~non_blocking;
- }
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-
- if (destruction && (state & user_set_linger))
- {
- ::linger opt;
- opt.l_onoff = 0;
- opt.l_linger = 0;
- asio::error_code ignored_ec;
- socket_ops::setsockopt(s, state, SOL_SOCKET,
- SO_LINGER, &opt, sizeof(opt), ignored_ec);
- }
clear_last_error();
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
@@ -320,6 +319,7 @@ int close(socket_type s, state_type& state,
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
result = error_wrapper(::close(s), ec);
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ }
}
if (result == 0)
diff --git a/src/bin/auth/auth_srv.cc b/src/bin/auth/auth_srv.cc
index 1487e13..b533b8f 100644
--- a/src/bin/auth/auth_srv.cc
+++ b/src/bin/auth/auth_srv.cc
@@ -307,12 +307,14 @@ makeErrorMessage(MessagePtr message, OutputBufferPtr buffer,
for_each(questions.begin(), questions.end(), QuestionInserter(message));
message->setRcode(rcode);
- MessageRenderer renderer(*buffer);
+ MessageRenderer renderer;
+ renderer.setBuffer(buffer.get());
if (tsig_context.get() != NULL) {
message->toWire(renderer, *tsig_context);
} else {
message->toWire(renderer);
}
+ renderer.setBuffer(NULL);
LOG_DEBUG(auth_logger, DBG_AUTH_MESSAGES, AUTH_SEND_ERROR_RESPONSE)
.arg(renderer.getLength()).arg(*message);
}
@@ -554,7 +556,8 @@ AuthSrvImpl::processNormalQuery(const IOMessage& io_message, MessagePtr message,
return (true);
}
- MessageRenderer renderer(*buffer);
+ MessageRenderer renderer;
+ renderer.setBuffer(buffer.get());
const bool udp_buffer =
(io_message.getSocket().getProtocol() == IPPROTO_UDP);
renderer.setLengthLimit(udp_buffer ? remote_bufsize : 65535);
@@ -563,6 +566,7 @@ AuthSrvImpl::processNormalQuery(const IOMessage& io_message, MessagePtr message,
} else {
message->toWire(renderer);
}
+ renderer.setBuffer(NULL);
LOG_DEBUG(auth_logger, DBG_AUTH_MESSAGES, AUTH_SEND_NORMAL_RESPONSE)
.arg(renderer.getLength()).arg(message->toText());
@@ -683,12 +687,14 @@ AuthSrvImpl::processNotify(const IOMessage& io_message, MessagePtr message,
message->setHeaderFlag(Message::HEADERFLAG_AA);
message->setRcode(Rcode::NOERROR());
- MessageRenderer renderer(*buffer);
+ MessageRenderer renderer;
+ renderer.setBuffer(buffer.get());
if (tsig_context.get() != NULL) {
message->toWire(renderer, *tsig_context);
} else {
message->toWire(renderer);
}
+ renderer.setBuffer(NULL);
return (true);
}
diff --git a/src/bin/auth/b10-auth.8 b/src/bin/auth/b10-auth.8
index 56b1732..14ba2ae 100644
--- a/src/bin/auth/b10-auth.8
+++ b/src/bin/auth/b10-auth.8
@@ -2,12 +2,12 @@
.\" Title: b10-auth
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: December 28, 2011
+.\" Date: March 1, 2012
.\" Manual: BIND10
.\" Source: BIND10
.\" Language: English
.\"
-.TH "B10\-AUTH" "8" "December 28, 2011" "BIND10" "BIND10"
+.TH "B10\-AUTH" "8" "March 1, 2012" "BIND10" "BIND10"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -154,21 +154,25 @@ immediately\&.
\fBshutdown\fR
exits
-\fBb10\-auth\fR\&. (Note that the BIND 10 boss process will restart this service\&.)
+\fBb10\-auth\fR\&. This has an optional
+\fIpid\fR
+argument to select the process ID to stop\&. (Note that the BIND 10 boss process may restart this service if configured\&.)
.SH "STATISTICS DATA"
.PP
The statistics data collected by the
\fBb10\-stats\fR
-daemon include:
+daemon for
+\(lqAuth\(rq
+include:
.PP
-auth\&.queries\&.tcp
+queries\&.tcp
.RS 4
Total count of queries received by the
\fBb10\-auth\fR
server over TCP since startup\&.
.RE
.PP
-auth\&.queries\&.udp
+queries\&.udp
.RS 4
Total count of queries received by the
\fBb10\-auth\fR
@@ -198,5 +202,5 @@ The
daemon was first coded in October 2009\&.
.SH "COPYRIGHT"
.br
-Copyright \(co 2010 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2010-2012 Internet Systems Consortium, Inc. ("ISC")
.br
diff --git a/src/bin/auth/b10-auth.xml b/src/bin/auth/b10-auth.xml
index 947c316..7575217 100644
--- a/src/bin/auth/b10-auth.xml
+++ b/src/bin/auth/b10-auth.xml
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "—">]>
<!--
- - Copyright (C) 2010-2011 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2010-2012 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
@@ -20,7 +20,7 @@
<refentry>
<refentryinfo>
- <date>December 28, 2011</date>
+ <date>March 1, 2012</date>
</refentryinfo>
<refmeta>
@@ -36,7 +36,7 @@
<docinfo>
<copyright>
- <year>2010</year>
+ <year>2010-2012</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
</docinfo>
@@ -188,7 +188,10 @@
<para>
<command>shutdown</command> exits <command>b10-auth</command>.
- (Note that the BIND 10 boss process will restart this service.)
+ This has an optional <varname>pid</varname> argument to
+ select the process ID to stop.
+ (Note that the BIND 10 boss process may restart this service
+ if configured.)
</para>
</refsect1>
@@ -198,20 +201,20 @@
<para>
The statistics data collected by the <command>b10-stats</command>
- daemon include:
+ daemon for <quote>Auth</quote> include:
</para>
<variablelist>
<varlistentry>
- <term>auth.queries.tcp</term>
+ <term>queries.tcp</term>
<listitem><simpara>Total count of queries received by the
<command>b10-auth</command> server over TCP since startup.
</simpara></listitem>
</varlistentry>
<varlistentry>
- <term>auth.queries.udp</term>
+ <term>queries.udp</term>
<listitem><simpara>Total count of queries received by the
<command>b10-auth</command> server over UDP since startup.
</simpara></listitem>
@@ -219,6 +222,8 @@
</variablelist>
+<!-- TODO: missing stats docs. See ticket #1721 -->
+
</refsect1>
<refsect1>
diff --git a/src/bin/auth/query.cc b/src/bin/auth/query.cc
index 73681e4..3474430 100644
--- a/src/bin/auth/query.cc
+++ b/src/bin/auth/query.cc
@@ -167,38 +167,65 @@ Query::addNXDOMAINProofByNSEC(ZoneFinder& finder, ConstRRsetPtr nsec) {
}
}
+uint8_t
+Query::addClosestEncloserProof(ZoneFinder& finder, const Name& name,
+ bool exact_ok, bool add_closest)
+{
+ const ZoneFinder::FindNSEC3Result result = finder.findNSEC3(name, true);
+
+ // Validity check (see the method description). Note that a completely
+ // broken findNSEC3 implementation could even return NULL RRset in
+ // closest_proof. We don't explicitly check such case; addRRset() will
+ // throw an exception, and it will be converted to SERVFAIL at the caller.
+ if (!exact_ok && !result.next_proof) {
+ isc_throw(BadNSEC3, "Matching NSEC3 found for a non existent name: "
+ << qname_);
+ }
+
+ if (add_closest) {
+ response_.addRRset(Message::SECTION_AUTHORITY,
+ boost::const_pointer_cast<AbstractRRset>(
+ result.closest_proof),
+ dnssec_);
+ }
+ if (result.next_proof) {
+ response_.addRRset(Message::SECTION_AUTHORITY,
+ boost::const_pointer_cast<AbstractRRset>(
+ result.next_proof),
+ dnssec_);
+ }
+ return (result.closest_labels);
+}
+
void
-Query::addNXDOMAINProofByNSEC3(ZoneFinder& finder) {
- // Firstly get the NSEC3 proves for Closest Encloser Proof
- // See section 7.2.1 of RFC 5155.
- // Since this is a Name Error case both closest and next proofs should
- // be available (see addNXRRsetProof).
- const ZoneFinder::FindNSEC3Result fresult1 = finder.findNSEC3(qname_,
- true);
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(
- fresult1.closest_proof),
- dnssec_);
+Query::addNSEC3ForName(ZoneFinder& finder, const Name& name, bool match) {
+ const ZoneFinder::FindNSEC3Result result = finder.findNSEC3(name, false);
+
+ // See the comment for addClosestEncloserProof(). We don't check a
+ // totally bogus case where closest_proof is NULL here.
+ if (match != result.matched) {
+ isc_throw(BadNSEC3, "Unexpected "
+ << (result.matched ? "matching" : "covering")
+ << " NSEC3 found for " << name);
+ }
response_.addRRset(Message::SECTION_AUTHORITY,
boost::const_pointer_cast<AbstractRRset>(
- fresult1.next_proof),
+ result.closest_proof),
dnssec_);
+}
+
+void
+Query::addNXDOMAINProofByNSEC3(ZoneFinder& finder) {
+ // Firstly get the NSEC3 proves for Closest Encloser Proof
+ // See Section 7.2.1 of RFC 5155.
+ const uint8_t closest_labels =
+ addClosestEncloserProof(finder, qname_, false);
// Next, construct the wildcard name at the closest encloser, i.e.,
// '*' followed by the closest encloser, and add NSEC3 for it.
const Name wildname(Name("*").concatenate(
- qname_.split(qname_.getLabelCount() -
- fresult1.closest_labels)));
- const ZoneFinder::FindNSEC3Result fresult2 =
- finder.findNSEC3(wildname, false);
- if (fresult2.matched) {
- isc_throw(BadNSEC3, "Matching NSEC3 found for nonexistent domain "
- << wildname);
- }
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(
- fresult2.closest_proof),
- dnssec_);
+ qname_.split(qname_.getLabelCount() - closest_labels)));
+ addNSEC3ForName(finder, wildname, false);
}
void
@@ -224,20 +251,13 @@ Query::addWildcardProof(ZoneFinder& finder,
fresult.rrset),
dnssec_);
} else if (db_result.isNSEC3Signed()) {
- // Case for RFC5155 Section 7.2.6.
+ // Case for RFC 5155 Section 7.2.6.
//
// Note that the closest encloser must be the immediate ancestor
- // of the matching wildcard, so NSEC3 for its next closer is what
- // we are expected to provided per the RFC (if this assumption isn't
- // met the zone is broken anyway).
- const ZoneFinder::FindNSEC3Result NSEC3Result(
- finder.findNSEC3(qname_, true));
- // Note that at this point next_proof must not be NULL unless it's
- // a run time collision (or zone/findNSEC3() is broken). The
- // unexpected case will be caught in addRRset() and result in SERVFAIL.
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(
- NSEC3Result.next_proof), dnssec_);
+ // of the matching wildcard, so NSEC3 for its next closer (and only
+ // that NSEC3) is what we are expected to provided per the RFC (if
+ // this assumption isn't met the zone is broken anyway).
+ addClosestEncloserProof(finder, qname_, false, false);
}
}
@@ -279,23 +299,8 @@ Query::addDS(ZoneFinder& finder, const Name& dname) {
addNXRRsetProof(finder, ds_result);
} else if (ds_result.code == ZoneFinder::NXRRSET &&
ds_result.isNSEC3Signed()) {
- // Add no DS proof with NSEC3 as specified in RFC5155 Section 7.2.7.
- // Depending on whether the zone is optout or not, findNSEC3() may
- // return non-NULL or NULL next_proof (respectively). The Opt-Out flag
- // must be set or cleared accordingly, but we don't check that
- // in this level (as long as the zone signed validly and findNSEC3()
- // is valid, the condition should be met; otherwise we'd let the
- // validator detect the error).
- const ZoneFinder::FindNSEC3Result nsec3_result =
- finder.findNSEC3(dname, true);
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(
- nsec3_result.closest_proof), dnssec_);
- if (nsec3_result.next_proof) {
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(
- nsec3_result.next_proof), dnssec_);
- }
+ // Add no DS proof with NSEC3 as specified in RFC 5155 Section 7.2.7.
+ addClosestEncloserProof(finder, dname, true);
} else {
// Any other case should be an error
isc_throw(BadDS, "Unexpected result for DS lookup for delegation");
@@ -315,57 +320,22 @@ Query::addNXRRsetProof(ZoneFinder& finder,
addWildcardNXRRSETProof(finder, db_result.rrset);
}
} else if (db_result.isNSEC3Signed() && !db_result.isWildcard()) {
- // Handling depends on whether query type is DS or not
- // (see RFC5155, 7.2.3 and 7.2.4): If qtype == DS, do
- // recursive search (and add next_proof, if necessary),
- // otherwise, do non-recursive search
- const bool qtype_ds = (qtype_ == RRType::DS());
- ZoneFinder::FindNSEC3Result result(finder.findNSEC3(qname_, qtype_ds));
- if (result.matched) {
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(
- result.closest_proof), dnssec_);
- // For qtype == DS, next_proof could be set
- // (We could check for opt-out here, but that's really the
- // responsibility of the datasource)
- if (qtype_ds && result.next_proof != ConstRRsetPtr()) {
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(
- result.next_proof), dnssec_);
- }
+ if (qtype_ == RRType::DS()) {
+ // RFC 5155, Section 7.2.4. Add either NSEC3 for the qname or
+ // closest (provable) encloser proof in case of optout.
+ addClosestEncloserProof(finder, qname_, true);
} else {
- isc_throw(BadNSEC3, "No matching NSEC3 found for existing domain "
- << qname_);
+ // RFC 5155, Section 7.2.3. Just add NSEC3 for the qname.
+ addNSEC3ForName(finder, qname_, true);
}
} else if (db_result.isNSEC3Signed() && db_result.isWildcard()) {
- // Case for RFC5155 Section 7.2.5
- const ZoneFinder::FindNSEC3Result result(finder.findNSEC3(qname_,
- true));
- // We know there's no exact match for the qname, so findNSEC3() should
- // return both closest and next proofs. If the latter is NULL, it
- // means a run time collision (or the zone is broken in other way).
- // In that case addRRset() will throw, and it will be converted to
- // SERVFAIL.
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(
- result.closest_proof), dnssec_);
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(
- result.next_proof), dnssec_);
-
- // Construct the matched wildcard name and add NSEC3 for it.
+ // Case for RFC 5155 Section 7.2.5: add closest encloser proof for the
+ // qname, construct the matched wildcard name and add NSEC3 for it.
+ const uint8_t closest_labels =
+ addClosestEncloserProof(finder, qname_, false);
const Name wname = Name("*").concatenate(
- qname_.split(qname_.getLabelCount() - result.closest_labels));
- const ZoneFinder::FindNSEC3Result wresult(finder.findNSEC3(wname,
- false));
- if (wresult.matched) {
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(
- wresult.closest_proof), dnssec_);
- } else {
- isc_throw(BadNSEC3, "No matching NSEC3 found for existing domain "
- << wname);
- }
+ qname_.split(qname_.getLabelCount() - closest_labels));
+ addNSEC3ForName(finder, wname, true);
}
}
diff --git a/src/bin/auth/query.h b/src/bin/auth/query.h
index b6e6f05..e8d3ba8 100644
--- a/src/bin/auth/query.h
+++ b/src/bin/auth/query.h
@@ -204,6 +204,62 @@ private:
/// within this method.
bool processDSAtChild();
+ /// \brief Add NSEC3 to the response for a closest encloser proof for a
+ /// given name.
+ ///
+ /// This method calls \c findNSEC3() of the given zone finder for the
+ /// given name in the recursive mode, and adds the returned NSEC3(s) to
+ /// the authority section of the response message associated with the
+ /// \c Query object.
+ ///
+ /// It returns the number of labels of the closest encloser (returned via
+ /// the \c findNSEC3() call) in case the caller needs to use that value
+ /// for subsequent processing, i.e, constructing the best possible wildcard
+ /// name that (would) match the query name.
+ ///
+ /// Unless \c exact_ok is true, \c name is expected to be non existent,
+ /// in which case findNSEC3() in the recursive mode must return both
+ /// closest and next proofs. If the latter is NULL, it means a run time
+ /// collision (or the zone is broken in other way), and this method throws
+ /// a BadNSEC3 exception.
+ ///
+ /// If \c exact_ok is true, this method takes into account the case
+ /// where the name exists and may or may not be at a zone cut to an
+ /// optout zone. In this case, depending on whether the zone is optout
+ /// or not, findNSEC3() may return non-NULL or NULL next_proof
+ /// (respectively). This method adds the next proof if and only if
+ /// findNSEC3() returns non NULL value for it. The Opt-Out flag
+ /// must be set or cleared accordingly, but this method doesn't check that
+ /// in this level (as long as the zone is signed validly and findNSEC3()
+ /// for the data source is implemented as documented, the condition
+ /// should be met; otherwise we'd let the validator detect the error).
+ ///
+ /// By default this method always adds the closest proof.
+ /// If \c add_closest is false, it only adds the next proof to the message.
+ /// This correspond to the case of "wildcard answer responses" as described
+ /// in Section 7.2.6 of RFC5155.
+ uint8_t addClosestEncloserProof(isc::datasrc::ZoneFinder& finder,
+ const isc::dns::Name& name, bool exact_ok,
+ bool add_closest = true);
+
+ /// \brief Add matching or covering NSEC3 to the response for a give name.
+ ///
+ /// This method calls \c findNSEC3() of the given zone finder for the
+ /// given name in the non recursive mode, and adds the returned NSEC3 to
+ /// the authority section of the response message associated with the
+ /// \c Query object.
+ ///
+ /// Depending on the caller's context, the returned NSEC3 is one and
+ /// only one of matching or covering NSEC3. If \c match is true the
+ /// returned NSEC3 must be a matching one; otherwise it must be a covering
+ /// one. If this assumption isn't met this method throws a BadNSEC3
+ /// exception (if it must be a matching NSEC3 but is not, it means a broken
+ /// zone, maybe with incorrect optout NSEC3s; if it must be a covering
+ /// NSEC3 but is not, it means a run time collision; or the \c findNSEC3()
+ /// implementation is broken for both cases.)
+ void addNSEC3ForName(isc::datasrc::ZoneFinder& finder,
+ const isc::dns::Name& name, bool match);
+
public:
/// Constructor from query parameters.
///
diff --git a/src/bin/auth/tests/auth_srv_unittest.cc b/src/bin/auth/tests/auth_srv_unittest.cc
index c3905d3..f00efd9 100644
--- a/src/bin/auth/tests/auth_srv_unittest.cc
+++ b/src/bin/auth/tests/auth_srv_unittest.cc
@@ -154,8 +154,7 @@ createBuiltinVersionResponse(const qid_t qid, vector<uint8_t>& data) {
rrset_version_ns->addRdata(generic::NS(version_name));
message.addRRset(Message::SECTION_AUTHORITY, rrset_version_ns);
- OutputBuffer obuffer(0);
- MessageRenderer renderer(obuffer);
+ MessageRenderer renderer;
message.toWire(renderer);
data.clear();
diff --git a/src/bin/auth/tests/query_unittest.cc b/src/bin/auth/tests/query_unittest.cc
index 624db2f..0c413a1 100644
--- a/src/bin/auth/tests/query_unittest.cc
+++ b/src/bin/auth/tests/query_unittest.cc
@@ -1429,7 +1429,7 @@ TEST_F(QueryTest, badWildcardNSEC3) {
EXPECT_THROW(Query(memory_client, Name("www.wild.example.com"),
RRType::A(), response, true).process(),
- isc::InvalidParameter);
+ Query::BadNSEC3);
}
TEST_F(QueryTest, badWildcardProof1) {
@@ -1540,10 +1540,9 @@ TEST_F(QueryTest, wildcardNxrrsetWithNSEC3Collision) {
ConstRRsetPtr());
mock_finder->setNSEC3Result(&nsec3);
- // Message::addRRset() will detect it and throw InvalidParameter.
EXPECT_THROW(Query(memory_client, Name("www1.uwild.example.com"),
RRType::TXT(), response, true).process(),
- isc::InvalidParameter);
+ Query::BadNSEC3);
}
TEST_F(QueryTest, wildcardNxrrsetWithNSEC3Broken) {
@@ -2283,10 +2282,9 @@ TEST_F(QueryTest, nxdomainWithBadNextNSEC3Proof) {
ConstRRsetPtr());
mock_finder->setNSEC3Result(&nsec3);
- // Message::addRRset() will detect it and throw InvalidParameter.
EXPECT_THROW(Query(memory_client, Name("nxdomain.example.com"),
RRType::TXT(), response, true).process(),
- isc::InvalidParameter);
+ Query::BadNSEC3);
}
TEST_F(QueryTest, nxdomainWithBadWildcardNSEC3Proof) {
diff --git a/src/bin/bind10/bind10.8 b/src/bin/bind10/bind10.8
index c2e44e7..11aee7a 100644
--- a/src/bin/bind10/bind10.8
+++ b/src/bin/bind10/bind10.8
@@ -2,12 +2,12 @@
.\" Title: bind10
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: November 23, 2011
+.\" Date: March 1, 2012
.\" Manual: BIND10
.\" Source: BIND10
.\" Language: English
.\"
-.TH "BIND10" "8" "November 23, 2011" "BIND10" "BIND10"
+.TH "BIND10" "8" "March 1, 2012" "BIND10" "BIND10"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -34,9 +34,8 @@ The arguments are as follows:
.PP
\fB\-c\fR \fIconfig\-filename\fR, \fB\-\-config\-file\fR \fIconfig\-filename\fR
.RS 4
-The configuration filename to use\&. Can be either absolute or relative to data path\&. In case it is absolute, value of data path is not considered\&.
-.sp
-Defaults to b10\-config\&.db\&.
+The configuration filename to use\&. Can be either absolute or relative to data path\&. In case it is absolute, value of data path is not considered\&. Defaults to
+b10\-config\&.db\&.
.RE
.PP
\fB\-\-cmdctl\-port\fR \fIport\fR
@@ -50,7 +49,9 @@ for the default\&.)
.PP
\fB\-p\fR \fIdirectory\fR, \fB\-\-data\-path\fR \fIdirectory\fR
.RS 4
-The path where BIND 10 programs look for various data files\&. Currently only b10\-cfgmgr uses it to locate the configuration file, but the usage might be extended for other programs and other types of files\&.
+The path where BIND 10 programs look for various data files\&. Currently only
+\fBb10-cfgmgr\fR(8)
+uses it to locate the configuration file, but the usage might be extended for other programs and other types of files\&.
.RE
.PP
\fB\-m\fR \fIfile\fR, \fB\-\-msgq\-socket\-file\fR \fIfile\fR
@@ -73,7 +74,6 @@ daemon\&.
The username for
\fBbind10\fR
to run as\&.
-
\fBbind10\fR
must be initially ran as the root user to use this option\&. The default is to run as the current user\&.
.RE
@@ -82,7 +82,7 @@ must be initially ran as the root user to use this option\&. The default is to r
.RS 4
If defined, the PID of the
\fBbind10\fR
-is stored in this file\&. This is used for testing purposes\&.
+is stored in this file\&.
.RE
.PP
\fB\-\-pretty\-name \fR\fB\fIname\fR\fR
@@ -103,7 +103,9 @@ and its child processes\&.
.PP
\fB\-w\fR \fIwait_time\fR, \fB\-\-wait\fR \fIwait_time\fR
.RS 4
-Sets the amount of time that BIND 10 will wait for the configuration manager (a key component of BIND 10) to initialize itself before abandoning the start up and terminating with an error\&. The wait_time is specified in seconds and has a default value of 10\&.
+Sets the amount of time that BIND 10 will wait for the configuration manager (a key component of BIND 10) to initialize itself before abandoning the start up and terminating with an error\&. The
+\fIwait_time\fR
+is specified in seconds and has a default value of 10\&.
.RE
.SH "CONFIGURATION AND COMMANDS"
.PP
@@ -145,18 +147,6 @@ to manage under
.IP \(bu 2.3
.\}
-\fI/Boss/components/setuid\fR
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-
\fI/Boss/components/b10\-stats\fR
.RE
.sp
@@ -212,11 +202,11 @@ to manage under
\fBb10\-sockcreator\fR,
\fBb10\-cfgmgr\fR, and
\fBb10\-msgq\fR
-is not configurable\&. It is hardcoded and
+is not configurable\&. They are hardcoded and
\fBbind10\fR
will not run without them\&.)
.PP
-These named sets (listed above) contain the following settings:
+The named sets for components contain the following settings:
.PP
\fIaddress\fR
.RS 4
@@ -258,7 +248,7 @@ will use the component name instead\&.
.PP
\fIspecial\fR
.RS 4
-This defines if the component is started a special way\&.
+This defines if the component is started a special, hardcoded way\&.
.RE
.PP
The
@@ -307,14 +297,22 @@ will exit\&.
.PP
The statistics data collected by the
\fBb10\-stats\fR
-daemon include:
+daemon for
+\(lqBoss\(rq
+include:
.PP
-bind10\&.boot_time
+boot_time
.RS 4
The date and time that the
\fBbind10\fR
process started\&. This is represented in ISO 8601 format\&.
.RE
+.SH "FILES"
+.PP
+sockcreator\-XXXXXX/sockcreator
+\(em the Unix Domain socket located in a temporary file directory for
+\fBb10\-sockcreator\fR
+communication\&.
.SH "SEE ALSO"
.PP
@@ -339,5 +337,5 @@ The
daemon was initially designed by Shane Kerr of ISC\&.
.SH "COPYRIGHT"
.br
-Copyright \(co 2011 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2010-2012 Internet Systems Consortium, Inc. ("ISC")
.br
diff --git a/src/bin/bind10/bind10.xml b/src/bin/bind10/bind10.xml
index 6705760..1f3cb68 100644
--- a/src/bin/bind10/bind10.xml
+++ b/src/bin/bind10/bind10.xml
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "—">]>
<!--
- - Copyright (C) 2010-2011 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2010-2012 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
@@ -20,7 +20,7 @@
<refentry>
<refentryinfo>
- <date>November 23, 2011</date>
+ <date>March 1, 2012</date>
</refentryinfo>
<refmeta>
@@ -36,7 +36,7 @@
<docinfo>
<copyright>
- <year>2011</year>
+ <year>2010-2012</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
</docinfo>
@@ -97,8 +97,8 @@
<listitem>
<para>The configuration filename to use. Can be either absolute or
relative to data path. In case it is absolute, value of data path is
- not considered.</para>
- <para>Defaults to b10-config.db.</para>
+ not considered.
+ Defaults to <filename>b10-config.db</filename>.</para>
</listitem>
</varlistentry>
@@ -123,9 +123,11 @@
</term>
<listitem>
<para>The path where BIND 10 programs look for various data files.
- Currently only b10-cfgmgr uses it to locate the configuration file,
- but the usage might be extended for other programs and other types
- of files.</para>
+ Currently only
+ <citerefentry><refentrytitle>b10-cfgmgr</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ uses it to locate the configuration file, but the usage
+ might be extended for other programs and other types of
+ files.</para>
</listitem>
</varlistentry>
@@ -155,9 +157,9 @@
<varlistentry>
<term><option>-u</option> <replaceable>user</replaceable>, <option>--user</option> <replaceable>name</replaceable></term>
+<!-- TODO: example more detail. -->
<listitem>
<para>The username for <command>bind10</command> to run as.
-<!-- TODO: example more detail. -->
<command>bind10</command> must be initially ran as the
root user to use this option.
The default is to run as the current user.</para>
@@ -169,7 +171,6 @@
<listitem>
<para>If defined, the PID of the <command>bind10</command> is stored
in this file.
- This is used for testing purposes.
</para>
</listitem>
</varlistentry>
@@ -201,11 +202,12 @@ The default is the basename of ARG 0.
<varlistentry>
<term><option>-w</option> <replaceable>wait_time</replaceable>, <option>--wait</option> <replaceable>wait_time</replaceable></term>
<listitem>
- <para>Sets the amount of time that BIND 10 will wait for
- the configuration manager (a key component of BIND 10) to
- initialize itself before abandoning the start up and
- terminating with an error. The wait_time is specified in
- seconds and has a default value of 10.
+ <para>Sets the amount of time that BIND 10 will wait for
+ the configuration manager (a key component of BIND 10)
+ to initialize itself before abandoning the start up and
+ terminating with an error. The
+ <replaceable>wait_time</replaceable> is specified in
+ seconds and has a default value of 10.
</para>
</listitem>
</varlistentry>
@@ -238,10 +240,6 @@ TODO: configuration section
</listitem>
<listitem>
- <para> <varname>/Boss/components/setuid</varname> </para>
- </listitem>
-
- <listitem>
<para> <varname>/Boss/components/b10-stats</varname> </para>
</listitem>
@@ -266,12 +264,12 @@ TODO: configuration section
<para>
(Note that the startup of <command>b10-sockcreator</command>,
<command>b10-cfgmgr</command>, and <command>b10-msgq</command>
- is not configurable. It is hardcoded and <command>bind10</command>
+ is not configurable. They are hardcoded and <command>bind10</command>
will not run without them.)
</para>
<para>
- These named sets (listed above) contain the following settings:
+ The named sets for components contain the following settings:
</para>
<variablelist>
@@ -346,7 +344,7 @@ list
<term> <varname>special</varname> </term>
<listitem>
<para>
- This defines if the component is started a special
+ This defines if the component is started a special, hardcoded
way.
<!--
TODO: document this ... but maybe some of these will be removed
@@ -357,7 +355,6 @@ cfgmgr
cmdctl
msgq
resolver
-setuid
sockcreator
xfrin
-->
@@ -374,6 +371,22 @@ xfrin
</para>
<!-- TODO: let's just let bind10 be known as bind10 and not Boss -->
+<!-- TODO -->
+<!--
+ <para>
+ <command>drop_socket</command>
+ This is an internal command and not exposed to the administrator.
+ </para>
+-->
+
+<!-- TODO -->
+<!--
+ <para>
+ <command>get_socket</command>
+ This is an internal command and not exposed to the administrator.
+ </para>
+-->
+
<para>
<command>getstats</command> tells <command>bind10</command>
to send its statistics data to the <command>b10-stats</command>
@@ -420,13 +433,13 @@ xfrin
<para>
The statistics data collected by the <command>b10-stats</command>
- daemon include:
+ daemon for <quote>Boss</quote> include:
</para>
<variablelist>
<varlistentry>
- <term>bind10.boot_time</term>
+ <term>boot_time</term>
<listitem><para>
The date and time that the <command>bind10</command>
process started.
@@ -438,13 +451,16 @@ xfrin
</refsect1>
-<!--
<refsect1>
<title>FILES</title>
- <para><filename></filename>
+ <para><filename>sockcreator-XXXXXX/sockcreator</filename>
+ —
+ the Unix Domain socket located in a temporary file directory for
+ <command>b10-sockcreator</command>
+<!-- <citerefentry><refentrytitle>b10-sockcreator</refentrytitle><manvolnum>8</manvolnum></citerefentry> -->
+ communication.
</para>
</refsect1>
--->
<refsect1>
<title>SEE ALSO</title>
@@ -476,6 +492,9 @@ xfrin
<citetitle>BIND 10 Guide</citetitle>.
</para>
</refsect1>
+<!-- <citerefentry>
+ <refentrytitle>b10-sockcreator</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>, -->
<refsect1 id='history'><title>HISTORY</title>
<para>The development of <command>bind10</command>
diff --git a/src/bin/bind10/bind10_src.py.in b/src/bin/bind10/bind10_src.py.in
index faf1582..edc1b69 100755
--- a/src/bin/bind10/bind10_src.py.in
+++ b/src/bin/bind10/bind10_src.py.in
@@ -892,7 +892,7 @@ class BoB:
# the need to find the place ourself or bother users. Also, this
# secures the socket on some platforms, as it creates a private
# directory.
- self._tmpdir = tempfile.mkdtemp()
+ self._tmpdir = tempfile.mkdtemp(prefix='sockcreator-')
# Get the name
self._socket_path = os.path.join(self._tmpdir, "sockcreator")
# And bind the socket to the name
diff --git a/src/bin/cmdctl/b10-cmdctl.8 b/src/bin/cmdctl/b10-cmdctl.8
index c8c938b..0b478fe 100644
--- a/src/bin/cmdctl/b10-cmdctl.8
+++ b/src/bin/cmdctl/b10-cmdctl.8
@@ -2,12 +2,12 @@
.\" Title: b10-cmdctl
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: March 9, 2010
+.\" Date: February 28, 2012
.\" Manual: BIND10
.\" Source: BIND10
.\" Language: English
.\"
-.TH "B10\-CMDCTL" "8" "March 9, 2010" "BIND10" "BIND10"
+.TH "B10\-CMDCTL" "8" "February 28, 2012" "BIND10" "BIND10"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -70,6 +70,33 @@ Enable verbose mode\&.
.RS 4
Display the version number and exit\&.
.RE
+.SH "CONFIGURATION AND COMMANDS"
+.PP
+The configurable settings are:
+.PP
+
+\fIaccounts_file\fR
+defines the path to the user accounts database\&. The default is
+/usr/local/etc/bind10\-devel/cmdctl\-accounts\&.csv\&.
+.PP
+
+\fIcert_file\fR
+defines the path to the PEM certificate file\&. The default is
+/usr/local/etc/bind10\-devel/cmdctl\-certfile\&.pem\&.
+.PP
+
+\fIkey_file\fR
+defines the path to the PEM private key file\&. The default is
+/usr/local/etc/bind10\-devel/cmdctl\-keyfile\&.pem\&.
+.PP
+The configuration command is:
+.PP
+
+\fBshutdown\fR
+exits
+\fBb10\-cmdctl\fR\&. This has an optional
+\fIpid\fR
+argument to select the process ID to stop\&. (Note that the BIND 10 boss process may restart this service if configured\&.)
.SH "FILES"
.PP
/usr/local/etc/bind10\-devel/cmdctl\-accounts\&.csv
@@ -93,5 +120,5 @@ The
daemon was initially designed and coded by Zhang Likun of CNNIC\&.
.SH "COPYRIGHT"
.br
-Copyright \(co 2010 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2010-2012 Internet Systems Consortium, Inc. ("ISC")
.br
diff --git a/src/bin/cmdctl/b10-cmdctl.xml b/src/bin/cmdctl/b10-cmdctl.xml
index 06953a4..e01d5a2 100644
--- a/src/bin/cmdctl/b10-cmdctl.xml
+++ b/src/bin/cmdctl/b10-cmdctl.xml
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "—">]>
<!--
- - Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2010-2012 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
@@ -20,7 +20,7 @@
<refentry>
<refentryinfo>
- <date>March 9, 2010</date>
+ <date>February 28, 2012</date>
</refentryinfo>
<refmeta>
@@ -37,7 +37,7 @@
<docinfo>
<copyright>
- <year>2010</year>
+ <year>2010-2012</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
</docinfo>
@@ -138,6 +138,50 @@
</refsect1>
<refsect1>
+ <title>CONFIGURATION AND COMMANDS</title>
+ <para>
+ The configurable settings are:
+ </para>
+
+ <para>
+ <varname>accounts_file</varname> defines the path to the
+ user accounts database.
+ The default is
+ <filename>/usr/local/etc/bind10-devel/cmdctl-accounts.csv</filename>.
+ </para>
+
+ <para>
+ <varname>cert_file</varname> defines the path to the
+ PEM certificate file.
+ The default is
+ <filename>/usr/local/etc/bind10-devel/cmdctl-certfile.pem</filename>.
+ </para>
+
+ <para>
+ <varname>key_file</varname> defines the path to the PEM private key
+ file.
+ The default is
+ <filename>/usr/local/etc/bind10-devel/cmdctl-keyfile.pem</filename>.
+ </para>
+
+<!-- TODO: formating -->
+ <para>
+ The configuration command is:
+ </para>
+
+<!-- NOTE: print_settings is not documented since I think will be removed -->
+
+ <para>
+ <command>shutdown</command> exits <command>b10-cmdctl</command>.
+ This has an optional <varname>pid</varname> argument to
+ select the process ID to stop.
+ (Note that the BIND 10 boss process may restart this service
+ if configured.)
+ </para>
+
+ </refsect1>
+
+ <refsect1>
<title>FILES</title>
<!-- TODO: replace /usr/local -->
<!-- TODO: permissions -->
diff --git a/src/bin/ddns/b10-ddns.8 b/src/bin/ddns/b10-ddns.8
index 67a5059..131b6cc 100644
--- a/src/bin/ddns/b10-ddns.8
+++ b/src/bin/ddns/b10-ddns.8
@@ -2,12 +2,12 @@
.\" Title: b10-ddns
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: December 9, 2011
+.\" Date: February 28, 2012
.\" Manual: BIND10
.\" Source: BIND10
.\" Language: English
.\"
-.TH "B10\-DDNS" "8" "December 9, 2011" "BIND10" "BIND10"
+.TH "B10\-DDNS" "8" "February 28, 2012" "BIND10" "BIND10"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -81,8 +81,10 @@ The module commands are:
.PP
\fBshutdown\fR
-Exits
-\fBb10\-ddns\fR\&. (Note that the BIND 10 boss process will restart this service\&.)
+exits
+\fBb10\-ddns\fR\&. This has an optional
+\fIpid\fR
+argument to select the process ID to stop\&. (Note that the BIND 10 boss process may restart this service if configured\&.)
.SH "SEE ALSO"
.PP
@@ -98,5 +100,5 @@ The
daemon was first implemented in December 2011 for the ISC BIND 10 project\&.
.SH "COPYRIGHT"
.br
-Copyright \(co 2011 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2011-2012 Internet Systems Consortium, Inc. ("ISC")
.br
diff --git a/src/bin/ddns/b10-ddns.xml b/src/bin/ddns/b10-ddns.xml
index b9cd117..15fcb1a 100644
--- a/src/bin/ddns/b10-ddns.xml
+++ b/src/bin/ddns/b10-ddns.xml
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "—">]>
<!--
- - Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2011-2012 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
@@ -20,7 +20,7 @@
<refentry>
<refentryinfo>
- <date>December 9, 2011</date>
+ <date>February 28, 2012</date>
</refentryinfo>
<refmeta>
@@ -36,7 +36,7 @@
<docinfo>
<copyright>
- <year>2011</year>
+ <year>2011-2012</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
</docinfo>
@@ -122,8 +122,11 @@
The module commands are:
</para>
<para>
- <command>shutdown</command> Exits <command>b10-ddns</command>.
- (Note that the BIND 10 boss process will restart this service.)
+ <command>shutdown</command> exits <command>b10-ddns</command>.
+ This has an optional <varname>pid</varname> argument to
+ select the process ID to stop.
+ (Note that the BIND 10 boss process may restart this service
+ if configured.)
</para>
</refsect1>
diff --git a/src/bin/dhcp4/Makefile.am b/src/bin/dhcp4/Makefile.am
index 513ae1c..6c52c05 100644
--- a/src/bin/dhcp4/Makefile.am
+++ b/src/bin/dhcp4/Makefile.am
@@ -15,7 +15,7 @@ pkglibexecdir = $(libexecdir)/@PACKAGE@
CLEANFILES = spec_config.h
man_MANS = b10-dhcp4.8
-EXTRA_DIST = $(man_MANS) dhcp4.spec
+EXTRA_DIST = $(man_MANS) b10-dhcp4.xml dhcp4.spec
if ENABLE_MAN
diff --git a/src/bin/dhcp6/Makefile.am b/src/bin/dhcp6/Makefile.am
index b1b0798..abfffb9 100644
--- a/src/bin/dhcp6/Makefile.am
+++ b/src/bin/dhcp6/Makefile.am
@@ -17,7 +17,7 @@ pkglibexecdir = $(libexecdir)/@PACKAGE@
CLEANFILES = *.gcno *.gcda spec_config.h
man_MANS = b10-dhcp6.8
-EXTRA_DIST = $(man_MANS) dhcp6.spec interfaces.txt
+EXTRA_DIST = $(man_MANS) b10-dhcp6.xml dhcp6.spec interfaces.txt
if ENABLE_MAN
diff --git a/src/bin/host/host.cc b/src/bin/host/host.cc
index f0df0c8..f1bb415 100644
--- a/src/bin/host/host.cc
+++ b/src/bin/host/host.cc
@@ -70,8 +70,7 @@ host_lookup(const char* const name, const char* const dns_class,
RRClass(dns_class),
any ? RRType::ANY() : RRType(type))); // if NULL then:
- OutputBuffer obuffer(512);
- MessageRenderer renderer(obuffer);
+ MessageRenderer renderer;
msg.toWire(renderer);
struct addrinfo hints, *res;
@@ -111,7 +110,7 @@ host_lookup(const char* const name, const char* const dns_class,
gettimeofday(&before_time, NULL);
}
- sendto(s, obuffer.getData(), obuffer.getLength(), 0, res->ai_addr,
+ sendto(s, renderer.getData(), renderer.getLength(), 0, res->ai_addr,
res->ai_addrlen);
struct sockaddr_storage ss;
diff --git a/src/bin/resolver/b10-resolver.8 b/src/bin/resolver/b10-resolver.8
index 7a4cb6d..eed69b8 100644
--- a/src/bin/resolver/b10-resolver.8
+++ b/src/bin/resolver/b10-resolver.8
@@ -2,12 +2,12 @@
.\" Title: b10-resolver
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: December 28, 2011
+.\" Date: February 28, 2012
.\" Manual: BIND10
.\" Source: BIND10
.\" Language: English
.\"
-.TH "B10\-RESOLVER" "8" "December 28, 2011" "BIND10" "BIND10"
+.TH "B10\-RESOLVER" "8" "February 28, 2012" "BIND10" "BIND10"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -118,7 +118,9 @@ The configuration command is:
\fBshutdown\fR
exits
-\fBb10\-resolver\fR\&. (Note that the BIND 10 boss process will restart this service\&.)
+\fBb10\-resolver\fR\&. This has an optional
+\fIpid\fR
+argument to select the process ID to stop\&. (Note that the BIND 10 boss process may restart this service if configured\&.)
.SH "SEE ALSO"
.PP
@@ -134,5 +136,5 @@ The
daemon was first coded in September 2010\&. The initial implementation only provided forwarding\&. Iteration was introduced in January 2011\&. Caching was implemented in February 2011\&. Access control was introduced in June 2011\&.
.SH "COPYRIGHT"
.br
-Copyright \(co 2010 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2010-2012 Internet Systems Consortium, Inc. ("ISC")
.br
diff --git a/src/bin/resolver/b10-resolver.xml b/src/bin/resolver/b10-resolver.xml
index 05472b5..aca8fb2 100644
--- a/src/bin/resolver/b10-resolver.xml
+++ b/src/bin/resolver/b10-resolver.xml
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "—">]>
<!--
- - Copyright (C) 2010-2011 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2010-2012 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
@@ -20,7 +20,7 @@
<refentry>
<refentryinfo>
- <date>December 28, 2011</date>
+ <date>February 28, 2012</date>
</refentryinfo>
<refmeta>
@@ -36,7 +36,7 @@
<docinfo>
<copyright>
- <year>2010</year>
+ <year>2010-2012</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
</docinfo>
@@ -201,7 +201,10 @@ once that is merged you can for instance do 'config add Resolver/forward_address
<para>
<command>shutdown</command> exits <command>b10-resolver</command>.
- (Note that the BIND 10 boss process will restart this service.)
+ This has an optional <varname>pid</varname> argument to
+ select the process ID to stop.
+ (Note that the BIND 10 boss process may restart this service
+ if configured.)
</para>
</refsect1>
diff --git a/src/bin/resolver/resolver.cc b/src/bin/resolver/resolver.cc
index 367c16c..e7f242e 100644
--- a/src/bin/resolver/resolver.cc
+++ b/src/bin/resolver/resolver.cc
@@ -252,7 +252,8 @@ makeErrorMessage(MessagePtr message, MessagePtr answer_message,
}
for_each(questions.begin(), questions.end(), QuestionInserter(message));
message->setRcode(rcode);
- MessageRenderer renderer(*buffer);
+ MessageRenderer renderer;
+ renderer.setBuffer(buffer.get());
message->toWire(renderer);
}
@@ -303,7 +304,8 @@ public:
// Now we can clear the buffer and render the new message into it
buffer->clear();
- MessageRenderer renderer(*buffer);
+ MessageRenderer renderer;
+ renderer.setBuffer(buffer.get());
ConstEDNSPtr edns(query_message->getEDNS());
const bool dnssec_ok = edns && edns->getDNSSECAwareness();
@@ -327,6 +329,7 @@ public:
}
answer_message->toWire(renderer);
+ renderer.setBuffer(NULL);
LOG_DEBUG(resolver_logger, RESOLVER_DBG_DETAIL,
RESOLVER_DNS_MESSAGE_SENT)
diff --git a/src/bin/sockcreator/main.cc b/src/bin/sockcreator/main.cc
index 3e06882..17efd04 100644
--- a/src/bin/sockcreator/main.cc
+++ b/src/bin/sockcreator/main.cc
@@ -24,7 +24,7 @@ main() {
* but ability to bind ports? It would be nice.
*/
try {
- run(STDIN_FILENO, STDOUT_FILENO);
+ run(STDIN_FILENO, STDOUT_FILENO, getSock, isc::util::io::send_fd, close);
} catch (const SocketCreatorError& ec) {
return (ec.getExitCode());
}
diff --git a/src/bin/sockcreator/sockcreator.cc b/src/bin/sockcreator/sockcreator.cc
index 0b1e763..167e3f0 100644
--- a/src/bin/sockcreator/sockcreator.cc
+++ b/src/bin/sockcreator/sockcreator.cc
@@ -18,7 +18,7 @@
#include <util/io/sockaddr_util.h>
#include <cerrno>
-#include <cstring>
+#include <string.h>
#include <unistd.h>
#include <sys/types.h>
@@ -157,7 +157,7 @@ handleRequest(const int input_fd, const int output_fd,
}
// Obtain the socket
- const int result = get_sock(sock_type, addr, addr_len);
+ const int result = get_sock(sock_type, addr, addr_len, close_fun);
if (result >= 0) {
// Got the socket, send it to the client.
writeMessage(output_fd, "S", 1);
@@ -186,6 +186,52 @@ handleRequest(const int input_fd, const int output_fd,
}
}
+// Sets the MTU related flags for IPv6 UDP sockets.
+// It is borrowed from bind-9 lib/isc/unix/socket.c and modified
+// to compile here.
+//
+// The function returns -2 if it fails or the socket file descriptor
+// on success (for convenience, so the result can be just returned).
+int
+mtu(int fd) {
+#ifdef IPV6_USE_MIN_MTU /* RFC 3542, not too common yet*/
+ const int on(1);
+ // use minimum MTU
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, &on, sizeof(on)) < 0) {
+ return (-2);
+ }
+#else // Try the following as fallback
+#ifdef IPV6_MTU
+ // Use minimum MTU on systems that don't have the IPV6_USE_MIN_MTU
+ const int mtu = 1280;
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_MTU, &mtu, sizeof(mtu)) < 0) {
+ return (-2);
+ }
+#endif
+#if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DONT)
+ // Turn off Path MTU discovery on IPv6/UDP sockets.
+ const int action = IPV6_PMTUDISC_DONT;
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &action,
+ sizeof(action)) < 0) {
+
+ return (-2);
+ }
+#endif
+#endif
+ return (fd);
+}
+
+// This one closes the socket if result is negative. Used not to leak socket
+// on error.
+int maybeClose(const int result, const int socket, const close_t close_fun) {
+ if (result < 0) {
+ if (close_fun(socket) == -1) {
+ isc_throw(InternalError, "Error closing socket");
+ }
+ }
+ return (result);
+}
+
} // Anonymous namespace
namespace isc {
@@ -193,7 +239,8 @@ namespace socket_creator {
// Get the socket and bind to it.
int
-getSock(const int type, struct sockaddr* bind_addr, const socklen_t addr_len) {
+getSock(const int type, struct sockaddr* bind_addr, const socklen_t addr_len,
+ const close_t close_fun) {
const int sock = socket(bind_addr->sa_family, type, 0);
if (sock == -1) {
return (-1);
@@ -201,23 +248,27 @@ getSock(const int type, struct sockaddr* bind_addr, const socklen_t addr_len) {
const int on = 1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
// This is part of the binding process, so it's a bind error
- return (-2);
+ return (maybeClose(-2, sock, close_fun));
}
if (bind_addr->sa_family == AF_INET6 &&
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1) {
// This is part of the binding process, so it's a bind error
- return (-2);
+ return (maybeClose(-2, sock, close_fun));
}
if (bind(sock, bind_addr, addr_len) == -1) {
- return (-2);
+ return (maybeClose(-2, sock, close_fun));
+ }
+ if (type == SOCK_DGRAM && bind_addr->sa_family == AF_INET6) {
+ // Set some MTU flags on IPv6 UDP sockets.
+ return (maybeClose(mtu(sock), sock, close_fun));
}
return (sock);
}
// Main run loop.
void
-run(const int input_fd, const int output_fd, const get_sock_t get_sock,
- const send_fd_t send_fd_fun, const close_t close_fun)
+run(const int input_fd, const int output_fd, get_sock_t get_sock,
+ send_fd_t send_fd_fun, close_t close_fun)
{
for (;;) {
char command;
diff --git a/src/bin/sockcreator/sockcreator.h b/src/bin/sockcreator/sockcreator.h
index df2bf8f..e5d4783 100644
--- a/src/bin/sockcreator/sockcreator.h
+++ b/src/bin/sockcreator/sockcreator.h
@@ -73,6 +73,9 @@ public:
};
+// Type of the close() function, so it can be passed as a parameter.
+// Argument is the same as that for close(2).
+typedef int (*close_t)(int);
/// \short Create a socket and bind it.
///
@@ -82,13 +85,16 @@ public:
/// \param type The type of socket to create (SOCK_STREAM, SOCK_DGRAM, etc).
/// \param bind_addr The address to bind.
/// \param addr_len The actual length of bind_addr.
+/// \param close_fun The furction used to close a socket if there's an error
+/// after the creation.
///
/// \return The file descriptor of the newly created socket, if everything
/// goes well. A negative number is returned if an error occurs -
/// -1 if the socket() call fails or -2 if bind() fails. In case of
/// error, errno is set (or left intact from socket() or bind()).
int
-getSock(const int type, struct sockaddr* bind_addr, const socklen_t addr_len);
+getSock(const int type, struct sockaddr* bind_addr, const socklen_t addr_len,
+ const close_t close_fun);
// Define some types for functions used to perform socket-related operations.
// These are typedefed so that alternatives can be passed through to the
@@ -96,16 +102,13 @@ getSock(const int type, struct sockaddr* bind_addr, const socklen_t addr_len);
// Type of the function to get a socket and to pass it as parameter.
// Arguments are those described above for getSock().
-typedef int (*get_sock_t)(const int, struct sockaddr *, const socklen_t);
+typedef int (*get_sock_t)(const int, struct sockaddr *, const socklen_t,
+ const close_t close_fun);
// Type of the send_fd() function, so it can be passed as a parameter.
// Arguments are the same as those of the send_fd() function.
typedef int (*send_fd_t)(const int, const int);
-// Type of the close() function, so it can be passed as a parameter.
-// Argument is the same as that for close(2).
-typedef int (*close_t)(int);
-
/// \brief Infinite loop parsing commands and returning the sockets.
///
@@ -135,10 +138,8 @@ typedef int (*close_t)(int);
/// \exception isc::socket_creator::ProtocolError Unrecognised command received
/// \exception isc::socket_creator::InternalError Other error
void
-run(const int input_fd, const int output_fd,
- const get_sock_t get_sock_fun = getSock,
- const send_fd_t send_fd_fun = isc::util::io::send_fd,
- const close_t close_fun = close);
+run(const int input_fd, const int output_fd, get_sock_t get_sock_fun,
+ send_fd_t send_fd_fun, close_t close_fun);
} // namespace socket_creator
} // NAMESPACE ISC
diff --git a/src/bin/sockcreator/tests/Makefile.am b/src/bin/sockcreator/tests/Makefile.am
index 223e761..ef518b5 100644
--- a/src/bin/sockcreator/tests/Makefile.am
+++ b/src/bin/sockcreator/tests/Makefile.am
@@ -1,7 +1,8 @@
CLEANFILES = *.gcno *.gcda
-AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
-AM_CXXFLAGS = $(B10_CXXFLAGS)
+AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CXXFLAGS = $(B10_CXXFLAGS)
if USE_STATIC_LINK
AM_LDFLAGS = -static
diff --git a/src/bin/sockcreator/tests/sockcreator_tests.cc b/src/bin/sockcreator/tests/sockcreator_tests.cc
index eccc3ed..9604567 100644
--- a/src/bin/sockcreator/tests/sockcreator_tests.cc
+++ b/src/bin/sockcreator/tests/sockcreator_tests.cc
@@ -22,6 +22,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
+#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>
@@ -105,17 +106,47 @@ typedef void (*socket_check_t)(const int);
// The other argument is the socket descriptor number.
// IPv4 check
-void addressFamilySpecificCheck(const sockaddr_in*, const int) {
+void addressFamilySpecificCheck(const sockaddr_in*, const int, const int) {
}
// IPv6 check
-void addressFamilySpecificCheck(const sockaddr_in6*, const int socknum) {
+void addressFamilySpecificCheck(const sockaddr_in6*, const int socknum,
+ const int socket_type)
+{
int options;
socklen_t len = sizeof(options);
- EXPECT_EQ(0, getsockopt(socknum, IPPROTO_IPV6, IPV6_V6ONLY, &options, &len));
+ EXPECT_EQ(0, getsockopt(socknum, IPPROTO_IPV6, IPV6_V6ONLY, &options,
+ &len));
EXPECT_NE(0, options);
+ if (socket_type == SOCK_DGRAM) {
+ // Some more checks for UDP - MTU
+#ifdef IPV6_USE_MIN_MTU /* RFC 3542, not too common yet*/
+ // use minimum MTU
+ EXPECT_EQ(0, getsockopt(socknum, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
+ &options, &len)) << strerror(errno);
+ EXPECT_NE(0, options);
+#else
+ // We do not check for the IPV6_MTU, because while setting works (eg.
+ // the packets are fragmented correctly), the getting does not. If
+ // we try to getsockopt it, an error complaining it can't be accessed
+ // on unconnected socket is returned. If we try to connect it, the
+ // MTU of the interface is returned, not the one we set. So we live
+ // in belief it works because we examined the packet dump.
+#if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DONT)
+ // Turned off Path MTU discovery on IPv6/UDP sockets?
+ EXPECT_EQ(0, getsockopt(socknum, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
+ &options, &len)) << strerror(errno);
+ EXPECT_EQ(IPV6_PMTUDISC_DONT, options);
+#endif
+#endif
+ }
}
+// Just ignore the fd and pretend success. We close invalid fds in the tests.
+int
+closeIgnore(int) {
+ return (0);
+}
// Generic version of the socket test. It creates the socket and checks that
// it is a valid descriptor. The family-specific check functions are called
@@ -133,7 +164,8 @@ void testAnyCreate(int socket_type, socket_check_t socket_check) {
memset(&addr, 0, sizeof(addr));
setAddressFamilyFields(&addr);
sockaddr* addr_ptr = reinterpret_cast<sockaddr*>(&addr);
- const int socket = getSock(socket_type, addr_ptr, sizeof(addr));
+ const int socket = getSock(socket_type, addr_ptr, sizeof(addr),
+ closeIgnore);
ASSERT_GE(socket, 0) << "Couldn't create socket: failed with " <<
"return code " << socket << " and error " << strerror(errno);
@@ -147,7 +179,7 @@ void testAnyCreate(int socket_type, socket_check_t socket_check) {
EXPECT_NE(0, options);
// ...and the address-family specific tests.
- addressFamilySpecificCheck(&addr, socket);
+ addressFamilySpecificCheck(&addr, socket, socket_type);
// Tidy up and exit.
EXPECT_EQ(0, close(socket));
@@ -171,12 +203,40 @@ TEST(get_sock, tcp6_create) {
testAnyCreate<sockaddr_in6>(SOCK_STREAM, tcpCheck);
}
+bool close_called(false);
+
+// You can use it as a close mockup. If you care about checking if it was really
+// called, you can use the close_called variable. But set it to false before the
+// test.
+int closeCall(int socket) {
+ close(socket);
+ close_called = true;
+ return (0);
+}
+
// Ask the get_sock function for some nonsense and test if it is able to report
// an error.
TEST(get_sock, fail_with_nonsense) {
sockaddr addr;
memset(&addr, 0, sizeof(addr));
- ASSERT_LT(getSock(0, &addr, sizeof addr), 0);
+ close_called = false;
+ ASSERT_EQ(-1, getSock(0, &addr, sizeof addr, closeCall));
+ ASSERT_FALSE(close_called); // The "socket" call should have failed already
+}
+
+// Bind should have failed here
+TEST(get_sock, fail_with_bind) {
+ sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = 1;
+ // No host should have this address on the interface, so it should not be
+ // possible to bind it.
+ addr.sin_addr.s_addr = inet_addr("192.0.2.1");
+ close_called = false;
+ ASSERT_EQ(-2, getSock(SOCK_STREAM, reinterpret_cast<sockaddr*>(&addr),
+ sizeof addr, closeCall));
+ ASSERT_TRUE(close_called); // The "socket" call should have failed already
}
// The main run() function in the socket creator takes three functions to
@@ -198,7 +258,8 @@ TEST(get_sock, fail_with_nonsense) {
// -1: The simulated bind() call has failed
// -2: The simulated socket() call has failed
int
-getSockDummy(const int type, struct sockaddr* addr, const socklen_t) {
+getSockDummy(const int type, struct sockaddr* addr, const socklen_t,
+ const close_t) {
int result = 0;
int port = 0;
@@ -253,12 +314,6 @@ send_FdDummy(const int destination, const int what) {
return (status ? 0 : -1);
}
-// Just ignore the fd and pretend success. We close invalid fds in the tests.
-int
-closeIgnore(int) {
- return (0);
-}
-
// Generic test that it works, with various inputs and outputs.
// It uses different functions to create the socket and send it and pass
// data to it and check it returns correct data back, to see if the run()
diff --git a/src/bin/stats/b10-stats-httpd.8 b/src/bin/stats/b10-stats-httpd.8
index 1206e1d..6e53543 100644
--- a/src/bin/stats/b10-stats-httpd.8
+++ b/src/bin/stats/b10-stats-httpd.8
@@ -1,22 +1,13 @@
'\" t
.\" Title: b10-stats-httpd
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" Date: Mar 8, 2011
+.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\" Date: February 28, 2012
.\" Manual: BIND10
.\" Source: BIND10
.\" Language: English
.\"
-.TH "B10\-STATS\-HTTPD" "8" "Mar 8, 2011" "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 '
+.TH "B10\-STATS\-HTTPD" "8" "February 28, 2012" "BIND10" "BIND10"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -110,7 +101,9 @@ with its PID\&.
.RS 4
exits the
\fBb10\-stats\-httpd\fR
-process\&. (Note that the BIND 10 boss process will restart this service\&.)
+process\&. This has an optional
+\fIpid\fR
+argument to select the process ID to stop\&. (Note that the BIND 10 boss process may restart this service if configured\&.)
.RE
.SH "SEE ALSO"
.PP
@@ -125,8 +118,8 @@ BIND 10 Guide\&.
.PP
\fBb10\-stats\-httpd\fR
-was designed and implemented by Naoki Kambe of JPRS in Mar 2011\&.
+was designed and implemented by Naoki Kambe of JPRS in March 2011\&.
.SH "COPYRIGHT"
.br
-Copyright \(co 2011 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2011-2012 Internet Systems Consortium, Inc. ("ISC")
.br
diff --git a/src/bin/stats/b10-stats-httpd.xml b/src/bin/stats/b10-stats-httpd.xml
index c8df9b8..a372244 100644
--- a/src/bin/stats/b10-stats-httpd.xml
+++ b/src/bin/stats/b10-stats-httpd.xml
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "—">]>
<!--
- - Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2011-2012 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
@@ -20,7 +20,7 @@
<refentry>
<refentryinfo>
- <date>Mar 8, 2011</date>
+ <date>February 28, 2012</date>
</refentryinfo>
<refmeta>
@@ -36,7 +36,7 @@
<docinfo>
<copyright>
- <year>2011</year>
+ <year>2011-2012</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
</docinfo>
@@ -171,9 +171,12 @@
<term><command>shutdown</command></term>
<listitem>
<para>
- exits the <command>b10-stats-httpd</command> process. (Note that
- the BIND 10 boss process will restart this service.)
- </para>
+ exits the <command>b10-stats-httpd</command> process.
+ This has an optional <varname>pid</varname> argument to
+ select the process ID to stop.
+ (Note that the BIND 10 boss process may restart this service
+ if configured.)
+ </para>
</listitem>
</varlistentry>
</variablelist>
@@ -205,7 +208,7 @@
<title>HISTORY</title>
<para>
<command>b10-stats-httpd</command> was designed and implemented by Naoki
- Kambe of JPRS in Mar 2011.
+ Kambe of JPRS in March 2011.
</para>
</refsect1>
</refentry><!--
diff --git a/src/bin/stats/b10-stats.8 b/src/bin/stats/b10-stats.8
index 0204ca1..80fbb50 100644
--- a/src/bin/stats/b10-stats.8
+++ b/src/bin/stats/b10-stats.8
@@ -2,12 +2,12 @@
.\" Title: b10-stats
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: August 11, 2011
+.\" Date: March 1, 2012
.\" Manual: BIND10
.\" Source: BIND10
.\" Language: English
.\"
-.TH "B10\-STATS" "8" "August 11, 2011" "BIND10" "BIND10"
+.TH "B10\-STATS" "8" "March 1, 2012" "BIND10" "BIND10"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -79,9 +79,9 @@ will send the statistics data in JSON format\&. By default, it outputs all the s
\fBshutdown\fR
will shutdown the
\fBb10\-stats\fR
-process\&. (Note that the
-\fBbind10\fR
-parent may restart it\&.)
+process\&. This has an optional
+\fIpid\fR
+argument to select the process ID to stop\&. (Note that the BIND 10 boss process may restart this service if configured\&.)
.PP
\fBstatus\fR
@@ -90,25 +90,22 @@ simply indicates that the daemon is running\&.
.PP
The
\fBb10\-stats\fR
-daemon contains these statistics:
-.PP
-report_time
-.RS 4
-The latest report date and time in ISO 8601 format\&.
-.RE
+daemon contains these
+\(lqStats\(rq
+statistics:
.PP
-stats\&.boot_time
+boot_time
.RS 4
The date and time when this daemon was started in ISO 8601 format\&. This is a constant which can\'t be reset except by restarting
\fBb10\-stats\fR\&.
.RE
.PP
-stats\&.last_update_time
+last_update_time
.RS 4
The date and time (in ISO 8601 format) when this daemon last received data from another component\&.
.RE
.PP
-stats\&.lname
+lname
.RS 4
This is the name used for the
\fBb10\-msgq\fR
@@ -116,14 +113,19 @@ command\-control channel\&. (This is a constant which can\'t be reset except by
\fBb10\-stats\fR\&.)
.RE
.PP
-stats\&.start_time
+report_time
+.RS 4
+The latest report date and time in ISO 8601 format\&.
+.RE
+.PP
+start_time
.RS 4
This is the date and time (in ISO 8601 format) when this daemon started collecting data\&.
.RE
.PP
-stats\&.timestamp
+timestamp
.RS 4
-The current date and time represented in seconds since UNIX epoch (1970\-01\-01T0 0:00:00Z) with precision (delimited with a period) up to one hundred thousandth of second\&.
+The current date and time represented in seconds since UNIX epoch (1970\-01\-01T00:00:00Z) with precision (delimited with a period) up to one hundred thousandth of second\&.
.RE
.PP
See other manual pages for explanations for their statistics that are kept track by
@@ -150,5 +152,5 @@ The
daemon was initially designed and implemented by Naoki Kambe of JPRS in October 2010\&.
.SH "COPYRIGHT"
.br
-Copyright \(co 2010 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2010-2012 Internet Systems Consortium, Inc. ("ISC")
.br
diff --git a/src/bin/stats/b10-stats.xml b/src/bin/stats/b10-stats.xml
index 13ada7a..4599563 100644
--- a/src/bin/stats/b10-stats.xml
+++ b/src/bin/stats/b10-stats.xml
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "—">]>
<!--
- - Copyright (C) 2010,2011 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2010-2012 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
@@ -20,7 +20,7 @@
<refentry>
<refentryinfo>
- <date>August 11, 2011</date>
+ <date>March 1, 2012</date>
</refentryinfo>
<refmeta>
@@ -36,7 +36,7 @@
<docinfo>
<copyright>
- <year>2010</year>
+ <year>2010-2012</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
</docinfo>
@@ -129,7 +129,10 @@
<para>
<command>shutdown</command> will shutdown the
<command>b10-stats</command> process.
- (Note that the <command>bind10</command> parent may restart it.)
+ This has an optional <varname>pid</varname> argument to
+ select the process ID to stop.
+ (Note that the BIND 10 boss process may restart this service
+ if configured.)
</para>
<para>
@@ -143,20 +146,15 @@
<title>STATISTICS DATA</title>
<para>
- The <command>b10-stats</command> daemon contains these statistics:
+ The <command>b10-stats</command> daemon contains these
+ <quote>Stats</quote> statistics:
</para>
<variablelist>
- <varlistentry>
- <term>report_time</term>
-<!-- TODO: why not named stats.report_time? -->
- <listitem><simpara>The latest report date and time in
- ISO 8601 format.</simpara></listitem>
- </varlistentry>
<varlistentry>
- <term>stats.boot_time</term>
+ <term>boot_time</term>
<listitem><simpara>The date and time when this daemon was
started in ISO 8601 format.
This is a constant which can't be reset except by restarting
@@ -165,14 +163,14 @@
</varlistentry>
<varlistentry>
- <term>stats.last_update_time</term>
+ <term>last_update_time</term>
<listitem><simpara>The date and time (in ISO 8601 format)
when this daemon last received data from another component.
</simpara></listitem>
</varlistentry>
<varlistentry>
- <term>stats.lname</term>
+ <term>lname</term>
<listitem><simpara>This is the name used for the
<command>b10-msgq</command> command-control channel.
(This is a constant which can't be reset except by restarting
@@ -181,16 +179,22 @@
</varlistentry>
<varlistentry>
- <term>stats.start_time</term>
+ <term>report_time</term>
+ <listitem><simpara>The latest report date and time in
+ ISO 8601 format.</simpara></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>start_time</term>
<listitem><simpara>This is the date and time (in ISO 8601 format)
when this daemon started collecting data.
</simpara></listitem>
</varlistentry>
<varlistentry>
- <term>stats.timestamp</term>
+ <term>timestamp</term>
<listitem><simpara>The current date and time represented in
- seconds since UNIX epoch (1970-01-01T0 0:00:00Z) with
+ seconds since UNIX epoch (1970-01-01T00:00:00Z) with
precision (delimited with a period) up to
one hundred thousandth of second.</simpara></listitem>
</varlistentry>
diff --git a/src/bin/xfrout/b10-xfrout.8 b/src/bin/xfrout/b10-xfrout.8
index c37198c..3670ec5 100644
--- a/src/bin/xfrout/b10-xfrout.8
+++ b/src/bin/xfrout/b10-xfrout.8
@@ -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: December 15, 2011
+.\" Date: February 28. 2012
.\" Manual: BIND10
.\" Source: BIND10
.\" Language: English
.\"
-.TH "B10\-XFROUT" "8" "December 15, 2011" "BIND10" "BIND10"
+.TH "B10\-XFROUT" "8" "February 28\&. 2012" "BIND10" "BIND10"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -70,11 +70,6 @@ The configurable settings are:
defines the maximum number of outgoing zone transfers that can run concurrently\&. The default is 10\&.
.PP
-\fItsig_key_ring\fR
-A list of TSIG keys (each of which is in the form of
-\fIname:base64\-key[:algorithm]\fR) used for access control on transfer requests\&. The default is an empty list\&.
-.PP
-
\fItransfer_acl\fR
A list of ACL elements that apply to all transfer requests by default (unless overridden in
\fIzone_config\fR)\&. See the
@@ -129,7 +124,9 @@ The configuration commands are:
\fBshutdown\fR
stops all outbound zone transfers and exits
-\fBb10\-xfrout\fR\&. (Note that the BIND 10 boss process will restart this service\&.)
+\fBb10\-xfrout\fR\&. This has an optional
+\fIpid\fR
+argument to select the process ID to stop\&. (Note that the BIND 10 boss process may restart this service if configured\&.)
.PP
\fBzone_new_data_ready\fR
@@ -154,5 +151,5 @@ The
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")
+Copyright \(co 2010-2012 Internet Systems Consortium, Inc. ("ISC")
.br
diff --git a/src/bin/xfrout/b10-xfrout.xml b/src/bin/xfrout/b10-xfrout.xml
index 87d0267..aaf0eb1 100644
--- a/src/bin/xfrout/b10-xfrout.xml
+++ b/src/bin/xfrout/b10-xfrout.xml
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "—">]>
<!--
- - Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2010-2012 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
@@ -20,7 +20,7 @@
<refentry>
<refentryinfo>
- <date>December 15, 2011</date>
+ <date>February 28. 2012</date>
</refentryinfo>
<refmeta>
@@ -36,7 +36,7 @@
<docinfo>
<copyright>
- <year>2010</year>
+ <year>2010-2012</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
</docinfo>
@@ -98,13 +98,6 @@
that can run concurrently. The default is 10.
</para>
<para>
- <varname>tsig_key_ring</varname>
- A list of TSIG keys (each of which is in the form of
- <replaceable>name:base64-key[:algorithm]</replaceable>)
- used for access control on transfer requests.
- The default is an empty list.
- </para>
- <para>
<varname>transfer_acl</varname>
A list of ACL elements that apply to all transfer requests by
default (unless overridden in <varname>zone_config</varname>).
@@ -122,33 +115,6 @@
See the <citetitle>BIND 10 Guide</citetitle> for configuration examples.
The default is an empty list, that is, no zone specific configuration.
</para>
- <para>
- <varname>log_name</varname>
-<!-- TODO -->
- </para>
- <para>
- <varname>log_file</varname>
-<!-- TODO -->
- The location of the log file if using a file channel.
- If undefined, then the file channel is closed.
- The default is
- <filename>/usr/local/var/bind10-devel/log/Xfrout.log</filename>.
- </para>
- <para>
- <varname>log_severity</varname>
-<!-- TODO -->
- The default is "debug".
- </para>
- <para>
- <varname>log_versions</varname>
-<!-- TODO -->
- The default is 5.
- </para>
- <para>
- <varname>log_max_bytes</varname>
-<!-- TODO -->
- The default is 1048576.
- </para>
<!-- TODO: log configurations not documented yet in here. jreed
has some but waiting on decisions ... -->
@@ -160,21 +126,18 @@
</simpara></note>
-<!--
-
-tsig_key_ring list of
-tsig_key string
-
--->
-
<!-- TODO: formating -->
<para>
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.)
+ and exits <command>b10-xfrout</command>.
+ This has an optional <varname>pid</varname> argument to
+ select the process ID to stop.
+ (Note that the BIND 10 boss process may restart this service
+ if configured.)
</para>
<para>
diff --git a/src/bin/xfrout/tests/xfrout_test.py.in b/src/bin/xfrout/tests/xfrout_test.py.in
index 3e953da..b60535c 100644
--- a/src/bin/xfrout/tests/xfrout_test.py.in
+++ b/src/bin/xfrout/tests/xfrout_test.py.in
@@ -28,6 +28,7 @@ from xfrout import *
import xfrout
import isc.log
import isc.acl.dns
+import isc.server_common.tsig_keyring
TESTDATA_SRCDIR = os.getenv("TESTDATASRCDIR")
TSIG_KEY = TSIGKey("example.com:SFuWd/q99SzF8Yzd1QbB9g==")
@@ -1155,6 +1156,39 @@ class TestUnixSockServer(unittest.TestCase):
self.write_sock, self.read_sock = socket.socketpair()
self.unix = MyUnixSockServer()
+ def test_tsig_keyring(self):
+ """
+ Check we use the global keyring when starting a request.
+ """
+ try:
+ # These are just so the keyring can be started
+ self.unix._cc.add_remote_config_by_name = \
+ lambda name, callback: None
+ self.unix._cc.get_remote_config_value = \
+ lambda module, name: ([], True)
+ self.unix._cc.remove_remote_config = lambda name: None
+ isc.server_common.tsig_keyring.init_keyring(self.unix._cc)
+ # These are not really interesting for the test. These are just
+ # handled over, so strings are OK.
+ self.unix._guess_remote = lambda sock: "Address"
+ self.unix._zone_config = "Zone config"
+ self.unix._acl = "acl"
+ # This would be the handler class, but we just check it is passed
+ # the right parametes, so function is enough for that.
+ keys = isc.server_common.tsig_keyring.get_keyring()
+ def handler(sock, data, server, keyring, address, acl, config):
+ self.assertEqual("sock", sock)
+ self.assertEqual("data", data)
+ self.assertEqual(self.unix, server)
+ self.assertEqual(keys, keyring)
+ self.assertEqual("Address", address)
+ self.assertEqual("acl", acl)
+ self.assertEqual("Zone config", config)
+ self.unix.RequestHandlerClass = handler
+ self.unix.finish_request("sock", "data")
+ finally:
+ isc.server_common.tsig_keyring.deinit_keyring()
+
def test_guess_remote(self):
"""Test we can guess the remote endpoint when we have only the
file descriptor. This is needed, because we get only that one
@@ -1214,25 +1248,12 @@ class TestUnixSockServer(unittest.TestCase):
def test_update_config_data(self):
self.check_default_ACL()
- tsig_key_str = 'example.com:SFuWd/q99SzF8Yzd1QbB9g=='
- tsig_key_list = [tsig_key_str]
- bad_key_list = ['bad..example.com:SFuWd/q99SzF8Yzd1QbB9g==']
self.unix.update_config_data({'transfers_out':10 })
self.assertEqual(self.unix._max_transfers_out, 10)
- self.assertTrue(self.unix.tsig_key_ring is not None)
self.check_default_ACL()
- self.unix.update_config_data({'transfers_out':9,
- 'tsig_key_ring':tsig_key_list})
+ self.unix.update_config_data({'transfers_out':9})
self.assertEqual(self.unix._max_transfers_out, 9)
- self.assertEqual(self.unix.tsig_key_ring.size(), 1)
- self.unix.tsig_key_ring.remove(Name("example.com."))
- self.assertEqual(self.unix.tsig_key_ring.size(), 0)
-
- # bad tsig key
- config_data = {'transfers_out':9, 'tsig_key_ring': bad_key_list}
- self.assertRaises(None, self.unix.update_config_data(config_data))
- self.assertEqual(self.unix.tsig_key_ring.size(), 0)
# Load the ACL
self.unix.update_config_data({'transfer_acl': [{'from': '127.0.0.1',
@@ -1449,7 +1470,6 @@ class TestXfroutServer(unittest.TestCase):
self.assertTrue(self.xfrout_server._notifier.shutdown_called)
self.assertTrue(self.xfrout_server._cc.stopped)
-
if __name__== "__main__":
isc.log.resetUnitTestRootLogger()
unittest.main()
diff --git a/src/bin/xfrout/xfrout.py.in b/src/bin/xfrout/xfrout.py.in
index 5c82f19..165560b 100755
--- a/src/bin/xfrout/xfrout.py.in
+++ b/src/bin/xfrout/xfrout.py.in
@@ -34,6 +34,7 @@ import select
import errno
from optparse import OptionParser, OptionValueError
from isc.util import socketserver_mixin
+import isc.server_common.tsig_keyring
from isc.log_messages.xfrout_messages import *
@@ -769,7 +770,7 @@ class UnixSockServer(socketserver_mixin.NoPollMixIn,
zone_config = self._zone_config
self._lock.release()
self.RequestHandlerClass(sock_fd, request_data, self,
- self.tsig_key_ring,
+ isc.server_common.tsig_keyring.get_keyring(),
self._guess_remote(sock_fd), acl, zone_config)
def _remove_unused_sock_file(self, sock_file):
@@ -833,7 +834,6 @@ class UnixSockServer(socketserver_mixin.NoPollMixIn,
self._acl = new_acl
self._zone_config = new_zone_config
self._max_transfers_out = new_config.get('transfers_out')
- self.set_tsig_key_ring(new_config.get('tsig_key_ring'))
except Exception as e:
self._lock.release()
raise e
@@ -870,21 +870,6 @@ class UnixSockServer(socketserver_mixin.NoPollMixIn,
zclass_str + ': ' + str(e))
return new_config
- def set_tsig_key_ring(self, key_list):
- """Set the tsig_key_ring , given a TSIG key string list representation. """
-
- # XXX add values to configure zones/tsig options
- self.tsig_key_ring = TSIGKeyRing()
- # If key string list is empty, create a empty tsig_key_ring
- if not key_list:
- return
-
- for key_item in key_list:
- try:
- self.tsig_key_ring.add(TSIGKey(key_item))
- except InvalidParameter as ipe:
- logger.error(XFROUT_BAD_TSIG_KEY_STRING, str(key_item))
-
def get_db_file(self):
file, is_default = self._cc.get_remote_config_value("Auth", "database_file")
# this too should be unnecessary, but currently the
@@ -920,7 +905,8 @@ class XfroutServer:
self._cc = isc.config.ModuleCCSession(SPECFILE_LOCATION, self.config_handler, self.command_handler)
self._config_data = self._cc.get_full_config()
self._cc.start()
- self._cc.add_remote_config(AUTH_SPECFILE_LOCATION);
+ self._cc.add_remote_config(AUTH_SPECFILE_LOCATION)
+ isc.server_common.tsig_keyring.init_keyring(self._cc)
self._start_xfr_query_listener()
self._start_notifier()
diff --git a/src/bin/xfrout/xfrout.spec.pre.in b/src/bin/xfrout/xfrout.spec.pre.in
index 6a97dea..ce8686e 100644
--- a/src/bin/xfrout/xfrout.spec.pre.in
+++ b/src/bin/xfrout/xfrout.spec.pre.in
@@ -9,48 +9,6 @@
"item_default": 10
},
{
- "item_name": "log_name",
- "item_type": "string",
- "item_optional": false,
- "item_default": "Xfrout"
- },
- {
- "item_name": "log_file",
- "item_type": "string",
- "item_optional": false,
- "item_default": "@@LOCALSTATEDIR@@/@PACKAGE@/log/Xfrout.log"
- },
- {
- "item_name": "log_severity",
- "item_type": "string",
- "item_optional": false,
- "item_default": "debug"
- },
- {
- "item_name": "log_versions",
- "item_type": "integer",
- "item_optional": false,
- "item_default": 5
- },
- {
- "item_name": "log_max_bytes",
- "item_type": "integer",
- "item_optional": false,
- "item_default": 1048576
- },
- {
- "item_name": "tsig_key_ring",
- "item_type": "list",
- "item_optional": true,
- "item_default": [],
- "list_item_spec" :
- {
- "item_name": "tsig_key",
- "item_type": "string",
- "item_optional": true
- }
- },
- {
"item_name": "transfer_acl",
"item_type": "list",
"item_optional": false,
diff --git a/src/bin/zonemgr/b10-zonemgr.8 b/src/bin/zonemgr/b10-zonemgr.8
index 1d24bbf..1bce2af 100644
--- a/src/bin/zonemgr/b10-zonemgr.8
+++ b/src/bin/zonemgr/b10-zonemgr.8
@@ -2,12 +2,12 @@
.\" Title: b10-zonemgr
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: December 8, 2011
+.\" Date: February 28, 2012
.\" Manual: BIND10
.\" Source: BIND10
.\" Language: English
.\"
-.TH "B10\-ZONEMGR" "8" "December 8, 2011" "BIND10" "BIND10"
+.TH "B10\-ZONEMGR" "8" "February 28, 2012" "BIND10" "BIND10"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -98,7 +98,9 @@ This is an internal command and not exposed to the administrator\&.
\fBshutdown\fR
exits
-\fBb10\-zonemgr\fR\&. (Note that the BIND 10 boss process will restart this service\&.)
+\fBb10\-zonemgr\fR\&. This has an optional
+\fIpid\fR
+argument to select the process ID to stop\&. (Note that the BIND 10 boss process may restart this service if configured\&.)
.PP
\fBzone_new_data_ready\fR
@@ -128,5 +130,5 @@ The
daemon was designed in July 2010 by CNNIC for the ISC BIND 10 project\&.
.SH "COPYRIGHT"
.br
-Copyright \(co 2010-2011 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2010-2012 Internet Systems Consortium, Inc. ("ISC")
.br
diff --git a/src/bin/zonemgr/b10-zonemgr.xml b/src/bin/zonemgr/b10-zonemgr.xml
index 5ea6041..f859d23 100644
--- a/src/bin/zonemgr/b10-zonemgr.xml
+++ b/src/bin/zonemgr/b10-zonemgr.xml
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "—">]>
<!--
- - Copyright (C) 2010-2011 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2010-2012 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
@@ -20,7 +20,7 @@
<refentry>
<refentryinfo>
- <date>December 8, 2011</date>
+ <date>February 28, 2012</date>
</refentryinfo>
<refmeta>
@@ -36,7 +36,7 @@
<docinfo>
<copyright>
- <year>2010-2011</year>
+ <year>2010-2012</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
</docinfo>
@@ -186,7 +186,10 @@
<para>
<command>shutdown</command> exits <command>b10-zonemgr</command>.
- (Note that the BIND 10 boss process will restart this service.)
+ This has an optional <varname>pid</varname> argument to
+ select the process ID to stop.
+ (Note that the BIND 10 boss process may restart this service
+ if configured.)
</para>
<para>
diff --git a/src/cppcheck-suppress.lst b/src/cppcheck-suppress.lst
index 1020ffe..164c549 100644
--- a/src/cppcheck-suppress.lst
+++ b/src/cppcheck-suppress.lst
@@ -4,8 +4,19 @@ debug
missingInclude
// This is a template, and should be excluded from the check
unreadVariable:src/lib/dns/rdata/template.cc:61
-// Intentional self assignment tests. Suppress warning about them.
-selfAssignment:src/lib/dns/tests/name_unittest.cc:293
-selfAssignment:src/lib/dns/tests/rdata_unittest.cc:228
-selfAssignment:src/lib/dns/tests/tsigkey_unittest.cc:137
-selfAssignment:src/lib/dns/tests/rdata_txt_like_unittest.cc:222
+
+// Intentional self-comparisons
+duplicateExpression:src/lib/dns/tests/name_unittest.cc:569
+duplicateExpression:src/lib/dns/tests/name_unittest.cc:580
+duplicateExpression:src/lib/dns/tests/rrttl_unittest.cc:164
+duplicateExpression:src/lib/dns/tests/rrttl_unittest.cc:175
+duplicateExpression:src/lib/dns/tests/name_unittest.cc:568
+duplicateExpression:src/lib/dns/tests/name_unittest.cc:579
+
+// Intentional self-comparisons
+uselessCallsCompare:src/lib/dns/tests/rdata_dhcid_unittest.cc:96
+uselessCallsCompare:src/lib/dns/tests/rdata_in_a_unittest.cc:98
+uselessCallsCompare:src/lib/dns/tests/rdata_in_aaaa_unittest.cc:94
+uselessCallsCompare:src/lib/dns/tests/rdata_mx_unittest.cc:104
+uselessCallsCompare:src/lib/dns/tests/rdata_unittest.cc:254
+uselessCallsCompare:src/lib/dns/tests/rdata_unittest.cc:253
diff --git a/src/lib/asiodns/Makefile.am b/src/lib/asiodns/Makefile.am
index b5d030d..a03f147 100644
--- a/src/lib/asiodns/Makefile.am
+++ b/src/lib/asiodns/Makefile.am
@@ -24,6 +24,7 @@ libasiodns_la_SOURCES += dns_server.h
libasiodns_la_SOURCES += dns_service.cc dns_service.h
libasiodns_la_SOURCES += tcp_server.cc tcp_server.h
libasiodns_la_SOURCES += udp_server.cc udp_server.h
+libasiodns_la_SOURCES += sync_udp_server.cc sync_udp_server.h
libasiodns_la_SOURCES += io_fetch.cc io_fetch.h
libasiodns_la_SOURCES += logger.h logger.cc
diff --git a/src/lib/asiodns/dns_server.h b/src/lib/asiodns/dns_server.h
index d3a8528..119aa66 100644
--- a/src/lib/asiodns/dns_server.h
+++ b/src/lib/asiodns/dns_server.h
@@ -88,22 +88,6 @@ public:
/// to return.
virtual void resume(const bool done) { self_->resume(done); }
- /// \brief Indicate whether the server is able to send an answer
- /// to a query.
- ///
- /// This is presently used only for testing purposes.
- virtual bool hasAnswer() { return (self_->hasAnswer()); }
-
- /// \brief Returns the current value of the 'coroutine' object
- ///
- /// This is a temporary method, intended to be used for debugging
- /// purposes during development and removed later. It allows
- /// callers from outside the coroutine object to retrieve information
- /// about its current state.
- ///
- /// \return The value of the 'coroutine' object
- virtual int value() { return (self_->value()); }
-
/// \brief Returns a pointer to a clone of this DNSServer object.
///
/// When a \c DNSServer object is copied or assigned, the result will
diff --git a/src/lib/asiodns/io_fetch.cc b/src/lib/asiodns/io_fetch.cc
index b22d067..65c1d64 100644
--- a/src/lib/asiodns/io_fetch.cc
+++ b/src/lib/asiodns/io_fetch.cc
@@ -205,7 +205,8 @@ IOFetch::IOFetch(Protocol protocol, IOService& service,
}
void
-IOFetch::initIOFetch(MessagePtr& query_msg, Protocol protocol, IOService& service,
+IOFetch::initIOFetch(MessagePtr& query_msg, Protocol protocol,
+ IOService& service,
const isc::dns::Question& question,
const IOAddress& address, uint16_t port,
OutputBufferPtr& buff, Callback* cb, int wait, bool edns)
@@ -225,8 +226,10 @@ IOFetch::initIOFetch(MessagePtr& query_msg, Protocol protocol, IOService& servic
query_msg->setEDNS(edns_query);
}
- MessageRenderer renderer(*data_->msgbuf);
+ MessageRenderer renderer;
+ renderer.setBuffer(data_->msgbuf.get());
query_msg->toWire(renderer);
+ renderer.setBuffer(NULL);
}
// Return protocol in use.
diff --git a/src/lib/asiodns/sync_udp_server.cc b/src/lib/asiodns/sync_udp_server.cc
new file mode 100644
index 0000000..52da3bf
--- /dev/null
+++ b/src/lib/asiodns/sync_udp_server.cc
@@ -0,0 +1,215 @@
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+
+#include <asio.hpp>
+#include <asio/error.hpp>
+
+#include "sync_udp_server.h"
+#include "logger.h"
+
+#include <asiolink/dummy_io_cb.h>
+#include <asiolink/udp_endpoint.h>
+#include <asiolink/udp_socket.h>
+
+#include <boost/bind.hpp>
+
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <unistd.h> // for some IPC/network system calls
+#include <errno.h>
+
+using namespace std;
+using namespace isc::asiolink;
+
+namespace isc {
+namespace asiodns {
+
+SyncUDPServer::SyncUDPServer(asio::io_service& io_service,
+ const asio::ip::address& addr,
+ const uint16_t port,
+ asiolink::SimpleCallback* checkin,
+ DNSLookup* lookup, DNSAnswer* answer) :
+ output_buffer_(new isc::util::OutputBuffer(0)),
+ query_(new isc::dns::Message(isc::dns::Message::PARSE)),
+ answer_(new isc::dns::Message(isc::dns::Message::RENDER)),
+ io_(io_service), checkin_callback_(checkin), lookup_callback_(lookup),
+ answer_callback_(answer), stopped_(false)
+{
+ // We must use different instantiations for v4 and v6;
+ // otherwise ASIO will bind to both
+ asio::ip::udp proto = addr.is_v4() ? asio::ip::udp::v4() :
+ asio::ip::udp::v6();
+ socket_.reset(new asio::ip::udp::socket(io_service, proto));
+ socket_->set_option(asio::socket_base::reuse_address(true));
+ if (addr.is_v6()) {
+ socket_->set_option(asio::ip::v6_only(true));
+ }
+ socket_->bind(asio::ip::udp::endpoint(addr, port));
+}
+
+SyncUDPServer::SyncUDPServer(asio::io_service& io_service, const int fd,
+ const int af, asiolink::SimpleCallback* checkin,
+ DNSLookup* lookup, DNSAnswer* answer) :
+ output_buffer_(new isc::util::OutputBuffer(0)),
+ query_(new isc::dns::Message(isc::dns::Message::PARSE)),
+ answer_(new isc::dns::Message(isc::dns::Message::RENDER)),
+ io_(io_service), checkin_callback_(checkin), lookup_callback_(lookup),
+ answer_callback_(answer), stopped_(false)
+{
+ if (af != AF_INET && af != AF_INET6) {
+ isc_throw(InvalidParameter, "Address family must be either AF_INET "
+ "or AF_INET6, not " << af);
+ }
+ LOG_DEBUG(logger, DBGLVL_TRACE_BASIC, ASIODNS_FD_ADD_UDP).arg(fd);
+ try {
+ socket_.reset(new asio::ip::udp::socket(io_service));
+ socket_->assign(af == AF_INET6 ? asio::ip::udp::v6() :
+ asio::ip::udp::v4(), fd);
+ } catch (const std::exception& exception) {
+ // Whatever the thing throws, it is something from ASIO and we
+ // convert it
+ isc_throw(IOError, exception.what());
+ }
+}
+
+void
+SyncUDPServer::scheduleRead() {
+ socket_->async_receive_from(asio::buffer(data_, MAX_LENGTH), sender_,
+ boost::bind(&SyncUDPServer::handleRead, this,
+ _1, _2));
+}
+
+void
+SyncUDPServer::handleRead(const asio::error_code& ec, const size_t length) {
+ // Abort on fatal errors
+ if (ec) {
+ using namespace asio::error;
+ if (ec.value() != would_block && ec.value() != try_again &&
+ ec.value() != interrupted) {
+ return;
+ }
+ }
+ // Some kind of interrupt, spurious wakeup, or like that. Just try reading
+ // again.
+ if (ec || length == 0) {
+ scheduleRead();
+ return;
+ }
+ // OK, we have a real packet of data. Let's dig into it!
+
+ // XXX: This is taken (and ported) from UDPSocket class. What the hell does
+ // it really mean?
+
+ // The UDP socket class has been extended with asynchronous functions
+ // and takes as a template parameter a completion callback class. As
+ // UDPServer does not use these extended functions (only those defined
+ // in the IOSocket base class) - but needs a UDPSocket to get hold of
+ // the underlying Boost UDP socket - DummyIOCallback is used. This
+ // provides the appropriate operator() but is otherwise functionless.
+ UDPSocket<DummyIOCallback> socket(*socket_);
+ UDPEndpoint endpoint(sender_);
+ IOMessage message(data_, length, socket, endpoint);
+ if (checkin_callback_ != NULL) {
+ (*checkin_callback_)(message);
+ if (stopped_) {
+ return;
+ }
+ }
+
+ // If we don't have a DNS Lookup provider, there's no point in
+ // continuing; we exit the coroutine permanently.
+ if (lookup_callback_ == NULL) {
+ scheduleRead();
+ return;
+ }
+
+ // Make sure the buffers are fresh
+ output_buffer_->clear();
+ query_->clear(isc::dns::Message::PARSE);
+ answer_->clear(isc::dns::Message::RENDER);
+
+ // Mark that we don't have an answer yet.
+ done_ = false;
+ resume_called_ = false;
+
+ // Call the actual lookup
+ (*lookup_callback_)(message, query_, answer_, output_buffer_, this);
+
+ if (!resume_called_) {
+ isc_throw(isc::Unexpected,
+ "No resume called from the lookup callback");
+ }
+
+ if (stopped_) {
+ return;
+ }
+
+ if (done_) {
+ // Good, there's an answer.
+ // Call the answer callback to render it.
+ (*answer_callback_)(message, query_, answer_, output_buffer_);
+
+ if (stopped_) {
+ return;
+ }
+
+ socket_->send_to(asio::buffer(output_buffer_->getData(),
+ output_buffer_->getLength()),
+ sender_);
+ }
+
+ // And schedule handling another socket.
+ scheduleRead();
+}
+
+void
+SyncUDPServer::operator()(asio::error_code, size_t) {
+ // To start the server, we just schedule reading of data when they
+ // arrive.
+ scheduleRead();
+}
+
+/// Stop the UDPServer
+void
+SyncUDPServer::stop() {
+ /// Using close instead of cancel, because cancel
+ /// will only cancel the asynchornized event already submitted
+ /// to io service, the events post to io service after
+ /// cancel still can be scheduled by io service, if
+ /// the socket is cloesed, all the asynchronized event
+ /// for it won't be scheduled by io service not matter it is
+ /// submit to io serice before or after close call. And we will
+ //. get bad_descriptor error
+ socket_->close();
+ stopped_ = true;
+}
+
+/// Post this coroutine on the ASIO service queue so that it will
+/// resume processing where it left off. The 'done' parameter indicates
+/// whether there is an answer to return to the client.
+void
+SyncUDPServer::resume(const bool done) {
+ resume_called_ = true;
+ done_ = done;
+}
+
+bool
+SyncUDPServer::hasAnswer() {
+ return (done_);
+}
+
+} // namespace asiodns
+} // namespace isc
diff --git a/src/lib/asiodns/sync_udp_server.h b/src/lib/asiodns/sync_udp_server.h
new file mode 100644
index 0000000..f21d3e5
--- /dev/null
+++ b/src/lib/asiodns/sync_udp_server.h
@@ -0,0 +1,161 @@
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __SYNC_UDP_SERVER_H
+#define __SYNC_UDP_SERVER_H 1
+
+#ifndef ASIO_HPP
+#error "asio.hpp must be included before including this, see asiolink.h as to why"
+#endif
+
+#include "dns_answer.h"
+#include "dns_lookup.h"
+#include "dns_server.h"
+
+#include <dns/message.h>
+#include <asiolink/simple_callback.h>
+#include <util/buffer.h>
+#include <exceptions/exceptions.h>
+
+#include <boost/noncopyable.hpp>
+
+#include <stdint.h>
+
+namespace isc {
+namespace asiodns {
+
+/// \brief An UDP server that doesn't asynchronous lookup handlers.
+///
+/// That means, the lookup handler must provide the answer right away.
+/// This allows for implementation with less overhead, compared with
+/// the UDPClass.
+class SyncUDPServer : public DNSServer, public boost::noncopyable {
+public:
+ /// \brief Constructor
+ /// \param io_service the asio::io_service to work with
+ /// \param addr the IP address to listen for queries on
+ /// \param port the port to listen for queries on
+ /// \param checkin the callbackprovider for non-DNS events
+ /// \param lookup the callbackprovider for DNS lookup events
+ /// \param answer the callbackprovider for DNS answer events
+ explicit SyncUDPServer(asio::io_service& io_service,
+ const asio::ip::address& addr, const uint16_t port,
+ isc::asiolink::SimpleCallback* checkin = NULL,
+ DNSLookup* lookup = NULL,
+ DNSAnswer* answer = NULL);
+
+ /// \brief Constructor
+ /// \param io_service the asio::io_service to work with
+ /// \param fd the file descriptor of opened UDP socket
+ /// \param af address family, either AF_INET or AF_INET6
+ /// \param checkin the callbackprovider for non-DNS events
+ /// \param lookup the callbackprovider for DNS lookup events
+ /// \param answer the callbackprovider for DNS answer events
+ /// \throw isc::InvalidParameter if af is neither AF_INET nor AF_INET6
+ /// \throw isc::asiolink::IOError when a low-level error happens, like the
+ /// fd is not a valid descriptor.
+ SyncUDPServer(asio::io_service& io_service, const int fd, const int af,
+ isc::asiolink::SimpleCallback* checkin = NULL,
+ DNSLookup* lookup = NULL, DNSAnswer* answer = NULL);
+
+ /// \brief Start the SyncUDPServer.
+ ///
+ /// This is the function operator to keep interface with other server
+ /// classes. They need that because they're coroutines.
+ virtual void operator()(asio::error_code ec = asio::error_code(),
+ size_t length = 0);
+
+ /// \brief Calls the lookup callback
+ virtual void asyncLookup() {
+ isc_throw(Unexpected,
+ "SyncUDPServer doesn't support asyncLookup by design, use "
+ "UDPServer if you need it.");
+ }
+
+ /// \brief Stop the running server
+ /// \note once the server stopped, it can't restart
+ virtual void stop();
+
+ /// \brief Resume operation
+ ///
+ /// Note that unlike other servers, this one expects it to be called
+ /// directly from the lookup callback. If it isn't, the server will
+ /// throw an Unexpected exception (probably to the event loop, which
+ /// would usually lead to termination of the program, but that's OK,
+ /// as it would be serious programmer error).
+ ///
+ /// \param done Set this to true if the lookup action is done and
+ /// we have an answer
+ virtual void resume(const bool done);
+
+ /// \brief Check if we have an answer
+ ///
+ /// \return true if we have an answer
+ virtual bool hasAnswer();
+
+ /// \brief Clones the object
+ ///
+ /// Since cloning is for the use of coroutines, the synchronous UDP server
+ /// does not need to be cloned. Therefore supporting it would be needless
+ /// work, and trying to clone it would be a programmer error anyway, this
+ /// throws Unexpected.
+ ///
+ /// \return a newly allocated copy of this object
+ virtual DNSServer* clone() {
+ isc_throw(Unexpected, "SyncUDPServer can't be cloned.");
+ }
+private:
+ // Internal state & buffers. We don't use the PIMPL idiom, as this class
+ // isn't usually used directly anyway.
+
+ // Maximum size of incoming UDP packet
+ static const size_t MAX_LENGTH = 4096;
+ // Buffer for incoming data
+ uint8_t data_[MAX_LENGTH];
+ // The buffer to render the output to and send it.
+ // If it was OK to have just a buffer, not the wrapper class,
+ // we could reuse the data_
+ isc::util::OutputBufferPtr output_buffer_;
+ // Objects to hold the query message and the answer
+ isc::dns::MessagePtr query_, answer_;
+ // The socket used for the communication
+ std::auto_ptr<asio::ip::udp::socket> socket_;
+ // The event loop we use
+ asio::io_service& io_;
+ // Place the socket puts the sender of a packet when it is received
+ asio::ip::udp::endpoint sender_;
+ // Callbacks
+ const asiolink::SimpleCallback* checkin_callback_;
+ const DNSLookup* lookup_callback_;
+ const DNSAnswer* answer_callback_;
+ // Answers from the lookup callback (not sent directly, but signalled
+ // through resume()
+ bool resume_called_, done_;
+ // This turns true when the server stops. Allows for not sending the
+ // answer after we closed the socket.
+ bool stopped_;
+
+ // Auxiliary functions
+
+ // Schedule next read on the socket. Just a wrapper around
+ // socket_->async_read_from with the correct parameters.
+ void scheduleRead();
+ // Callback from the socket's read call (called when there's an error or
+ // when a new packet comes).
+ void handleRead(const asio::error_code& ec, const size_t length);
+};
+
+} // namespace asiodns
+} // namespace isc
+#endif // __SYNC_UDP_SERVER_H
diff --git a/src/lib/asiodns/tcp_server.h b/src/lib/asiodns/tcp_server.h
index d079e97..a75fddb 100644
--- a/src/lib/asiodns/tcp_server.h
+++ b/src/lib/asiodns/tcp_server.h
@@ -62,9 +62,6 @@ public:
void asyncLookup();
void stop();
void resume(const bool done);
- bool hasAnswer() { return (done_); }
- int value() { return (get_value()); }
-
DNSServer* clone() {
TCPServer* s = new TCPServer(*this);
return (s);
diff --git a/src/lib/asiodns/tests/dns_server_unittest.cc b/src/lib/asiodns/tests/dns_server_unittest.cc
index c9bbe7c..0064bba 100644
--- a/src/lib/asiodns/tests/dns_server_unittest.cc
+++ b/src/lib/asiodns/tests/dns_server_unittest.cc
@@ -19,6 +19,7 @@
#include <asiolink/io_endpoint.h>
#include <asiolink/io_error.h>
#include <asiodns/udp_server.h>
+#include <asiodns/sync_udp_server.h>
#include <asiodns/tcp_server.h>
#include <asiodns/dns_answer.h>
#include <asiodns/dns_lookup.h>
@@ -112,15 +113,22 @@ class DummyChecker : public SimpleCallback, public ServerStopper {
// \brief no lookup logic at all,just provide a checkpoint to stop the server
class DummyLookup : public DNSLookup, public ServerStopper {
- public:
- void operator()(const IOMessage& io_message,
- isc::dns::MessagePtr message,
- isc::dns::MessagePtr answer_message,
- isc::util::OutputBufferPtr buffer,
- DNSServer* server) const {
- stopServer();
+public:
+ DummyLookup() :
+ allow_resume_(true)
+ { }
+ void operator()(const IOMessage& io_message,
+ isc::dns::MessagePtr message,
+ isc::dns::MessagePtr answer_message,
+ isc::util::OutputBufferPtr buffer,
+ DNSServer* server) const {
+ stopServer();
+ if (allow_resume_) {
server->resume(true);
}
+ }
+ // If you want it not to call resume, set this to false
+ bool allow_resume_;
};
// \brief copy the data received from user to the answer part
@@ -314,10 +322,11 @@ class TCPClient : public SimpleClient {
// two servers, UDP client will only communicate with UDP server, same for TCP
// client
//
-// This is only the active part of the test. We run the test case twice, once
+// This is only the active part of the test. We run the test case four times, once
// for each type of initialization (once when giving it the address and port,
-// once when giving the file descriptor), to ensure it works both ways exactly
-// the same.
+// once when giving the file descriptor) multiplied by once for each type of UDP
+// server (UDPServer and SyncUDPServer), to ensure it works exactly the same.
+template<class UDPServerClass>
class DNSServerTestBase : public::testing::Test {
protected:
DNSServerTestBase() :
@@ -396,7 +405,7 @@ class DNSServerTestBase : public::testing::Test {
SimpleAnswer* const answer_;
UDPClient* const udp_client_;
TCPClient* const tcp_client_;
- UDPServer* udp_server_;
+ UDPServerClass* udp_server_;
TCPServer* tcp_server_;
// To access them in signal handle function, the following
@@ -406,18 +415,23 @@ class DNSServerTestBase : public::testing::Test {
};
// Initialization with name and port
-class AddrPortInit : public DNSServerTestBase {
+template<class UDPServerClass>
+class AddrPortInit : public DNSServerTestBase<UDPServerClass> {
protected:
AddrPortInit() {
- udp_server_ = new UDPServer(service, server_address_, server_port,
- checker_, lookup_, answer_);
- tcp_server_ = new TCPServer(service, server_address_, server_port,
- checker_, lookup_, answer_);
+ this->udp_server_ = new UDPServerClass(this->service,
+ this->server_address_,
+ server_port, this->checker_,
+ this->lookup_, this->answer_);
+ this->tcp_server_ = new TCPServer(this->service, this->server_address_,
+ server_port, this->checker_,
+ this->lookup_, this->answer_);
}
};
// Initialization by the file descriptor
-class FdInit : public DNSServerTestBase {
+template<class UDPServerClass>
+class FdInit : public DNSServerTestBase<UDPServerClass> {
private:
// Opens the file descriptor for us
// It uses the low-level C api, as it seems to be the easiest way to get
@@ -465,12 +479,14 @@ protected:
void SetUp() {
const int fdUDP(getFd(SOCK_DGRAM));
ASSERT_NE(-1, fdUDP) << strerror(errno);
- udp_server_ = new UDPServer(service, fdUDP, AF_INET6, checker_,
- lookup_, answer_);
+ this->udp_server_ = new UDPServerClass(this->service, fdUDP, AF_INET6,
+ this->checker_, this->lookup_,
+ this->answer_);
const int fdTCP(getFd(SOCK_STREAM));
ASSERT_NE(-1, fdTCP) << strerror(errno);
- tcp_server_ = new TCPServer(service, fdTCP, AF_INET6, checker_,
- lookup_, answer_);
+ this->tcp_server_ = new TCPServer(this->service, fdTCP, AF_INET6,
+ this->checker_, this->lookup_,
+ this->answer_);
}
};
@@ -478,11 +494,24 @@ protected:
template<class Parent>
class DNSServerTest : public Parent { };
-typedef ::testing::Types<AddrPortInit, FdInit> ServerTypes;
+typedef ::testing::Types<AddrPortInit<UDPServer>, AddrPortInit<SyncUDPServer>,
+ FdInit<UDPServer>, FdInit<SyncUDPServer> >
+ ServerTypes;
TYPED_TEST_CASE(DNSServerTest, ServerTypes);
-bool DNSServerTestBase::io_service_is_time_out = false;
-asio::io_service* DNSServerTestBase::current_service(NULL);
+typedef ::testing::Types<UDPServer, SyncUDPServer> UDPServerTypes;
+TYPED_TEST_CASE(DNSServerTestBase, UDPServerTypes);
+
+template<class UDPServerClass>
+bool DNSServerTestBase<UDPServerClass>::io_service_is_time_out = false;
+template<class UDPServerClass>
+asio::io_service* DNSServerTestBase<UDPServerClass>::current_service(NULL);
+
+typedef ::testing::Types<AddrPortInit<SyncUDPServer>, FdInit<SyncUDPServer> >
+ SyncTypes;
+template<class Parent>
+class SyncServerTest : public Parent { };
+TYPED_TEST_CASE(SyncServerTest, SyncTypes);
// Test whether server stopped successfully after client get response
// client will send query and start to wait for response, once client
@@ -608,17 +637,20 @@ TYPED_TEST(DNSServerTest, stopTCPServeMoreThanOnce) {
}
// It raises an exception when invalid address family is passed
-TEST_F(DNSServerTestBase, invalidFamily) {
+// The parameter here doesn't mean anything
+TYPED_TEST(DNSServerTestBase, invalidFamily) {
// We abuse DNSServerTestBase for this test, as we don't need the
// initialization.
- EXPECT_THROW(UDPServer(service, 0, AF_UNIX, checker_, lookup_,
- answer_), isc::InvalidParameter);
- EXPECT_THROW(TCPServer(service, 0, AF_UNIX, checker_, lookup_,
- answer_), isc::InvalidParameter);
+ EXPECT_THROW(TypeParam(this->service, 0, AF_UNIX, this->checker_,
+ this->lookup_, this->answer_),
+ isc::InvalidParameter);
+ EXPECT_THROW(TCPServer(this->service, 0, AF_UNIX, this->checker_,
+ this->lookup_, this->answer_),
+ isc::InvalidParameter);
}
// It raises an exception when invalid address family is passed
-TEST_F(DNSServerTestBase, invalidTCPFD) {
+TYPED_TEST(DNSServerTestBase, invalidTCPFD) {
// We abuse DNSServerTestBase for this test, as we don't need the
// initialization.
/*
@@ -630,11 +662,12 @@ TEST_F(DNSServerTestBase, invalidTCPFD) {
EXPECT_THROW(UDPServer(service, -1, AF_INET, checker_, lookup_,
answer_), isc::asiolink::IOError);
*/
- EXPECT_THROW(TCPServer(service, -1, AF_INET, checker_, lookup_,
- answer_), isc::asiolink::IOError);
+ EXPECT_THROW(TCPServer(this->service, -1, AF_INET, this->checker_,
+ this->lookup_, this->answer_),
+ isc::asiolink::IOError);
}
-TEST_F(DNSServerTestBase, DISABLED_invalidUDPFD) {
+TYPED_TEST(DNSServerTestBase, DISABLED_invalidUDPFD) {
/*
FIXME: The UDP server doesn't fail reliably with an invalid FD.
We need to find a way to trigger it reliably (it seems epoll
@@ -642,8 +675,24 @@ TEST_F(DNSServerTestBase, DISABLED_invalidUDPFD) {
not the others, maybe we could make it run this at least on epoll-based
systems).
*/
- EXPECT_THROW(UDPServer(service, -1, AF_INET, checker_, lookup_,
- answer_), isc::asiolink::IOError);
+ EXPECT_THROW(TypeParam(this->service, -1, AF_INET, this->checker_,
+ this->lookup_, this->answer_),
+ isc::asiolink::IOError);
+}
+
+// Check it rejects some of the unsupported operatirons
+TYPED_TEST(SyncServerTest, unsupportedOps) {
+ EXPECT_THROW(this->udp_server_->clone(), isc::Unexpected);
+ EXPECT_THROW(this->udp_server_->asyncLookup(), isc::Unexpected);
+}
+
+// Check it rejects forgotten resume (eg. insists that it is synchronous)
+TYPED_TEST(SyncServerTest, mustResume) {
+ this->lookup_->allow_resume_ = false;
+ ASSERT_THROW(this->testStopServerByStopper(this->udp_server_,
+ this->udp_client_,
+ this->lookup_),
+ isc::Unexpected);
}
}
diff --git a/src/lib/asiodns/tests/io_fetch_unittest.cc b/src/lib/asiodns/tests/io_fetch_unittest.cc
index 936c6c7..acb184c 100644
--- a/src/lib/asiodns/tests/io_fetch_unittest.cc
+++ b/src/lib/asiodns/tests/io_fetch_unittest.cc
@@ -133,10 +133,15 @@ public:
EDNSPtr msg_edns(new EDNS());
msg_edns->setUDPSize(Message::DEFAULT_MAX_EDNS0_UDPSIZE);
msg.setEDNS(msg_edns);
- MessageRenderer renderer(*msgbuf_);
+
+ MessageRenderer renderer;
+ renderer.setBuffer(msgbuf_.get());
+ msg.toWire(renderer);
+ renderer.setBuffer(NULL);
+
+ renderer.setBuffer(expected_buffer_.get());
msg.toWire(renderer);
- MessageRenderer renderer2(*expected_buffer_);
- msg.toWire(renderer2);
+ renderer.setBuffer(NULL);
// Initialize the test data to be returned: tests will return a
// substring of this data. (It's convenient to have this as a member of
@@ -581,20 +586,22 @@ public:
return_data_ = "Message returned to the client";
udp::endpoint remote;
- socket.async_receive_from(asio::buffer(receive_buffer_, sizeof(receive_buffer_)),
- remote,
- boost::bind(&IOFetchTest::udpReceiveHandler, this, &remote, &socket,
- _1, _2, bad_qid, second_send));
+ socket.async_receive_from(asio::buffer(receive_buffer_,
+ sizeof(receive_buffer_)),
+ remote,
+ boost::bind(&IOFetchTest::udpReceiveHandler,
+ this, &remote, &socket,
+ _1, _2, bad_qid, second_send));
service_.get_io_service().post(udp_fetch_);
if (debug_) {
- cout << "udpSendReceive: async_receive_from posted, waiting for callback" <<
- endl;
+ cout << "udpSendReceive: async_receive_from posted,"
+ "waiting for callback" << endl;
}
service_.run();
socket.close();
- EXPECT_TRUE(run_);;
+ EXPECT_TRUE(run_);
}
};
diff --git a/src/lib/asiodns/udp_server.cc b/src/lib/asiodns/udp_server.cc
index 820db4c..990949e 100644
--- a/src/lib/asiodns/udp_server.cc
+++ b/src/lib/asiodns/udp_server.cc
@@ -343,10 +343,5 @@ UDPServer::resume(const bool done) {
data_->io_.post(*this);
}
-bool
-UDPServer::hasAnswer() {
- return (data_->done_);
-}
-
} // namespace asiodns
} // namespace isc
diff --git a/src/lib/asiodns/udp_server.h b/src/lib/asiodns/udp_server.h
index c82b78c..2b6a574 100644
--- a/src/lib/asiodns/udp_server.h
+++ b/src/lib/asiodns/udp_server.h
@@ -83,16 +83,6 @@ public:
/// we have an answer
void resume(const bool done);
- /// \brief Check if we have an answer
- ///
- /// \return true if we have an answer
- bool hasAnswer();
-
- /// \brief Returns the coroutine state value
- ///
- /// \return the coroutine state value
- int value() { return (get_value()); }
-
/// \brief Clones the object
///
/// \return a newly allocated copy of this object
diff --git a/src/lib/bench/benchmark_util.cc b/src/lib/bench/benchmark_util.cc
index 9cf3b26..34356c8 100644
--- a/src/lib/bench/benchmark_util.cc
+++ b/src/lib/bench/benchmark_util.cc
@@ -61,8 +61,7 @@ loadQueryData(istream& input, BenchQueries& queries, const RRClass& qclass,
string line;
unsigned int linenum = 0;
Message query_message(Message::RENDER);
- OutputBuffer buffer(128); // this should be sufficiently large
- MessageRenderer renderer(buffer);
+ MessageRenderer renderer;
while (getline(input, line), !input.eof()) {
++linenum;
if (input.bad() || input.fail()) {
@@ -99,9 +98,9 @@ loadQueryData(istream& input, BenchQueries& queries, const RRClass& qclass,
renderer.clear();
query_message.toWire(renderer);
vector<unsigned char> query_data(
- static_cast<const unsigned char*>(buffer.getData()),
- static_cast<const unsigned char*>(buffer.getData()) +
- buffer.getLength());
+ static_cast<const unsigned char*>(renderer.getData()),
+ static_cast<const unsigned char*>(renderer.getData()) +
+ renderer.getLength());
queries.push_back(query_data);
} catch (const Exception&) {
if (strict) {
diff --git a/src/lib/config/module_spec.cc b/src/lib/config/module_spec.cc
index bebe695..0defd6d 100644
--- a/src/lib/config/module_spec.cc
+++ b/src/lib/config/module_spec.cc
@@ -466,7 +466,6 @@ ModuleSpec::validateSpecList(ConstElementPtr spec, ConstElementPtr data,
const bool full, ElementPtr errors) const
{
bool validated = true;
- std::string cur_item_name;
BOOST_FOREACH(ConstElementPtr cur_spec_el, spec->listValue()) {
if (!validateSpec(cur_spec_el, data, full, errors)) {
validated = false;
diff --git a/src/lib/datasrc/Makefile.am b/src/lib/datasrc/Makefile.am
index 9c1405e..a058b33 100644
--- a/src/lib/datasrc/Makefile.am
+++ b/src/lib/datasrc/Makefile.am
@@ -7,10 +7,10 @@ AM_CPPFLAGS += $(SQLITE_CFLAGS)
AM_CXXFLAGS = $(B10_CXXFLAGS)
-pkglibexecdir = $(libexecdir)/@PACKAGE@/backends
+pkglibdir = $(libexecdir)/@PACKAGE@/backends
datasrc_config.h: datasrc_config.h.pre
- $(SED) -e "s|@@PKGLIBEXECDIR@@|$(pkglibexecdir)|" datasrc_config.h.pre >$@
+ $(SED) -e "s|@@PKGLIBDIR@@|$(pkglibdir)|" datasrc_config.h.pre >$@
CLEANFILES = *.gcno *.gcda datasrc_messages.h datasrc_messages.cc
CLEANFILES += datasrc_config.h
@@ -32,7 +32,7 @@ libdatasrc_la_SOURCES += database.h database.cc
libdatasrc_la_SOURCES += factory.h factory.cc
nodist_libdatasrc_la_SOURCES = datasrc_messages.h datasrc_messages.cc
-pkglibexec_LTLIBRARIES = sqlite3_ds.la memory_ds.la
+pkglib_LTLIBRARIES = sqlite3_ds.la memory_ds.la
sqlite3_ds_la_SOURCES = sqlite3_accessor.h sqlite3_accessor.cc
sqlite3_ds_la_LDFLAGS = -module
diff --git a/src/lib/datasrc/datasrc_config.h.pre.in b/src/lib/datasrc/datasrc_config.h.pre.in
index ff99601..9074df6 100644
--- a/src/lib/datasrc/datasrc_config.h.pre.in
+++ b/src/lib/datasrc/datasrc_config.h.pre.in
@@ -23,7 +23,7 @@ namespace datasrc {
/// such as memory_ds.so and sqlite3_ds.so are found. It is used by the
/// DataSourceClient loader if no absolute path is used and
/// B10_FROM_BUILD is not set in the environment.
-const char* const BACKEND_LIBRARY_PATH = "@@PKGLIBEXECDIR@@/";
+const char* const BACKEND_LIBRARY_PATH = "@@PKGLIBDIR@@/";
} // end namespace datasrc
} // end namespace isc
diff --git a/src/lib/datasrc/datasrc_messages.mes b/src/lib/datasrc/datasrc_messages.mes
index d8ad07b..f4ff213 100644
--- a/src/lib/datasrc/datasrc_messages.mes
+++ b/src/lib/datasrc/datasrc_messages.mes
@@ -585,7 +585,7 @@ The underlying data source failed to answer the query for referral information.
1 means some error, 2 is not implemented. The data source should have logged
the specific error already.
-% DATASRC_QUERY_RRSIG unable to answer RRSIG query
+% DATASRC_QUERY_RRSIG unable to answer RRSIG query for %1
The server is unable to answer a direct query for RRSIG type, but was asked
to do so.
diff --git a/src/lib/datasrc/memory_datasrc.cc b/src/lib/datasrc/memory_datasrc.cc
index 3cd52ab..e4700c2 100644
--- a/src/lib/datasrc/memory_datasrc.cc
+++ b/src/lib/datasrc/memory_datasrc.cc
@@ -611,27 +611,40 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
*
* If rename is false, it returns the one provided. If it is true, it
* creates a new rrset with the same data but with provided name.
+ * In addition, if DNSSEC records are required by the original caller of
+ * find(), it also creates expanded RRSIG based on the RRSIG of the
+ * wildcard RRset.
* It is designed for wildcard case, where we create the rrsets
* dynamically.
*/
- static ConstRRsetPtr prepareRRset(const Name& name, const ConstRRsetPtr&
- rrset, bool rename)
+ static ConstRRsetPtr prepareRRset(const Name& name,
+ const ConstRRsetPtr& rrset,
+ bool rename, FindOptions options)
{
if (rename) {
LOG_DEBUG(logger, DBG_TRACE_DETAILED, DATASRC_MEM_RENAME).
arg(rrset->getName()).arg(name);
- /*
- * We lose a signature here. But it would be wrong anyway, because
- * the name changed. This might turn out to be unimportant in
- * future, because wildcards will probably be handled somehow
- * by DNSSEC.
- */
RRsetPtr result(new RRset(name, rrset->getClass(),
- rrset->getType(), rrset->getTTL()));
+ rrset->getType(), rrset->getTTL()));
for (RdataIteratorPtr i(rrset->getRdataIterator()); !i->isLast();
- i->next()) {
+ i->next()) {
result->addRdata(i->getCurrent());
}
+ if ((options & FIND_DNSSEC) != 0) {
+ ConstRRsetPtr sig_rrset = rrset->getRRsig();
+ if (sig_rrset) {
+ RRsetPtr result_sig(new RRset(name, sig_rrset->getClass(),
+ RRType::RRSIG(),
+ sig_rrset->getTTL()));
+ for (RdataIteratorPtr i(sig_rrset->getRdataIterator());
+ !i->isLast();
+ i->next())
+ {
+ result_sig->addRdata(i->getCurrent());
+ }
+ result->addRRsig(result_sig);
+ }
+ }
return (result);
} else {
return (rrset);
@@ -658,7 +671,7 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
// Implementation of InMemoryZoneFinder::find
FindResult find(const Name& name, RRType type,
- std::vector<ConstRRsetPtr> *target,
+ std::vector<ConstRRsetPtr>* target,
const FindOptions options) const
{
LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_MEM_FIND).arg(name).
@@ -695,14 +708,14 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
// We were traversing a DNAME node (and wanted to go
// lower below it), so return the DNAME
return (FindResult(DNAME, prepareRRset(name, state.rrset_,
- false)));
+ false, options)));
}
if (state.zonecut_node_ != NULL) {
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_MEM_DELEG_FOUND).
arg(state.rrset_->getName());
return (FindResult(DELEGATION,
prepareRRset(name, state.rrset_,
- false)));
+ false, options)));
}
// If the RBTree search stopped at a node for a super domain
@@ -806,7 +819,8 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
LOG_DEBUG(logger, DBG_TRACE_DATA,
DATASRC_MEM_EXACT_DELEGATION).arg(name);
return (FindResult(DELEGATION,
- prepareRRset(name, found->second, rename)));
+ prepareRRset(name, found->second, rename,
+ options)));
}
}
@@ -816,7 +830,8 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
for (found = node->getData()->begin();
found != node->getData()->end(); ++found)
{
- target->push_back(prepareRRset(name, found->second, rename));
+ target->push_back(prepareRRset(name, found->second, rename,
+ options));
}
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_MEM_ANY_SUCCESS).
arg(name);
@@ -830,7 +845,8 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
arg(type);
return (createFindResult(SUCCESS, prepareRRset(name,
found->second,
- rename), rename));
+ rename, options),
+ rename));
} else {
// Next, try CNAME.
found = node->getData()->find(RRType::CNAME());
@@ -838,7 +854,8 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_MEM_CNAME).arg(name);
return (createFindResult(CNAME,
prepareRRset(name, found->second,
- rename), rename));
+ rename, options),
+ rename));
}
}
// No exact match or CNAME. Return NXRRSET.
@@ -1317,7 +1334,6 @@ checkConfig(ConstElementPtr config, ElementPtr errors) {
}
return (result);
- return true;
}
} // end anonymous namespace
diff --git a/src/lib/datasrc/sqlite3_datasrc.cc b/src/lib/datasrc/sqlite3_datasrc.cc
index 03b057c..7cd565d 100644
--- a/src/lib/datasrc/sqlite3_datasrc.cc
+++ b/src/lib/datasrc/sqlite3_datasrc.cc
@@ -76,6 +76,14 @@ const char* const SCHEMA_LIST[] = {
"ttl INTEGER NOT NULL, rdtype STRING NOT NULL COLLATE NOCASE, "
"rdata STRING NOT NULL)",
"CREATE INDEX nsec3_byhash ON nsec3 (hash)",
+ "CREATE TABLE diffs (id INTEGER PRIMARY KEY, "
+ "zone_id INTEGER NOT NULL, "
+ "version INTEGER NOT NULL, "
+ "operation INTEGER NOT NULL, "
+ "name STRING NOT NULL COLLATE NOCASE, "
+ "rrtype STRING NOT NULL COLLATE NOCASE, "
+ "ttl INTEGER NOT NULL, "
+ "rdata STRING NOT NULL)",
NULL
};
diff --git a/src/lib/datasrc/static_datasrc.cc b/src/lib/datasrc/static_datasrc.cc
index 03f56be..1ce3966 100644
--- a/src/lib/datasrc/static_datasrc.cc
+++ b/src/lib/datasrc/static_datasrc.cc
@@ -73,6 +73,7 @@ StaticDataSrcImpl::StaticDataSrcImpl() :
authors->addRdata(generic::TXT("Dmitriy Volodin"));
authors->addRdata(generic::TXT("Evan Hunt"));
authors->addRdata(generic::TXT("Haidong Wang")); // Ocean
+ authors->addRdata(generic::TXT("Haikuo Zhang"));
authors->addRdata(generic::TXT("Han Feng"));
authors->addRdata(generic::TXT("Jelte Jansen"));
authors->addRdata(generic::TXT("Jeremy C. Reed"));
diff --git a/src/lib/datasrc/tests/datasrc_unittest.cc b/src/lib/datasrc/tests/datasrc_unittest.cc
index cd1a40c..36bed1d 100644
--- a/src/lib/datasrc/tests/datasrc_unittest.cc
+++ b/src/lib/datasrc/tests/datasrc_unittest.cc
@@ -58,7 +58,7 @@ ConstElementPtr SQLITE_DBFILE_EXAMPLE = Element::fromJSON(
class DataSrcTest : public ::testing::Test {
protected:
- DataSrcTest() : obuffer(0), renderer(obuffer), msg(Message::PARSE),
+ DataSrcTest() : msg(Message::PARSE),
opcodeval(Opcode::QUERY().getCode()), qid(0)
{
DataSrcPtr sql3_source = DataSrcPtr(new Sqlite3DataSrc);
@@ -76,7 +76,6 @@ protected:
HotCache cache;
MetaDataSrc meta_source;
- OutputBuffer obuffer;
MessageRenderer renderer;
Message msg;
const uint16_t opcodeval;
diff --git a/src/lib/datasrc/tests/memory_datasrc_unittest.cc b/src/lib/datasrc/tests/memory_datasrc_unittest.cc
index c156319..92d3a9a 100644
--- a/src/lib/datasrc/tests/memory_datasrc_unittest.cc
+++ b/src/lib/datasrc/tests/memory_datasrc_unittest.cc
@@ -548,6 +548,8 @@ public:
if (zone_finder == NULL) {
zone_finder = &zone_finder_;
}
+ const ConstRRsetPtr answer_sig = answer ? answer->getRRsig() :
+ RRsetPtr(); // note we use the same type as of retval of getRRsig()
// The whole block is inside, because we need to check the result and
// we can't assign to FindResult
EXPECT_NO_THROW({
@@ -567,6 +569,11 @@ public:
} else {
ASSERT_TRUE(find_result.rrset);
rrsetCheck(answer, find_result.rrset);
+ if (answer_sig) {
+ ASSERT_TRUE(find_result.rrset->getRRsig());
+ rrsetCheck(answer_sig,
+ find_result.rrset->getRRsig());
+ }
}
} else if (check_wild_answer) {
ASSERT_NE(ConstRRsetPtr(), answer) <<
@@ -584,6 +591,22 @@ public:
wildanswer->addRdata(expectedIt->getCurrent());
}
rrsetCheck(wildanswer, find_result.rrset);
+
+ // Same for the RRSIG, if any.
+ if (answer_sig) {
+ ASSERT_TRUE(find_result.rrset->getRRsig());
+
+ RRsetPtr wildsig(new RRset(name,
+ answer_sig->getClass(),
+ RRType::RRSIG(),
+ answer_sig->getTTL()));
+ RdataIteratorPtr expectedIt(
+ answer_sig->getRdataIterator());
+ for (; !expectedIt->isLast(); expectedIt->next()) {
+ wildsig->addRdata(expectedIt->getCurrent());
+ }
+ rrsetCheck(wildsig, find_result.rrset->getRRsig());
+ }
}
});
}
@@ -1088,6 +1111,24 @@ InMemoryZoneFinderTest::wildcardCheck(
* |
* *
*/
+
+ // If the zone is "signed" (detecting it by the NSEC/NSEC3 signed flags),
+ // add RRSIGs to the records.
+ ZoneFinder::FindOptions find_options = ZoneFinder::FIND_DEFAULT;
+ if ((expected_flags & ZoneFinder::RESULT_NSEC_SIGNED) != 0 ||
+ (expected_flags & ZoneFinder::RESULT_NSEC3_SIGNED) != 0) {
+ // Convenience shortcut. The RDATA is not really validatable, but
+ // it doesn't matter for our tests.
+ const char* const rrsig_common = "5 3 3600 "
+ "20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE";
+
+ find_options = find_options | ZoneFinder::FIND_DNSSEC;
+ rr_wild_->addRRsig(textToRRset("*.wild.example.org. 300 IN RRSIG A " +
+ string(rrsig_common)));
+ rr_cnamewild_->addRRsig(textToRRset("*.cnamewild.example.org. 300 IN "
+ "RRSIG CNAME " +
+ string(rrsig_common)));
+ }
EXPECT_EQ(SUCCESS, zone_finder_.add(rr_wild_));
EXPECT_EQ(SUCCESS, zone_finder_.add(rr_cnamewild_));
// If the zone is expected to be "signed" with NSEC3, add an NSEC3.
@@ -1101,14 +1142,15 @@ InMemoryZoneFinderTest::wildcardCheck(
{
SCOPED_TRACE("Search at parent");
findTest(Name("wild.example.org"), RRType::A(), ZoneFinder::NXRRSET,
- true, ConstRRsetPtr(), expected_flags);
+ true, ConstRRsetPtr(), expected_flags, NULL, find_options);
}
// Search the original name of wildcard
{
SCOPED_TRACE("Search directly at *");
findTest(Name("*.wild.example.org"), RRType::A(), ZoneFinder::SUCCESS,
- true, rr_wild_);
+ true, rr_wild_, ZoneFinder::RESULT_DEFAULT, NULL,
+ find_options);
}
// Search "created" name.
{
@@ -1116,11 +1158,12 @@ InMemoryZoneFinderTest::wildcardCheck(
findTest(Name("a.wild.example.org"), RRType::A(), ZoneFinder::SUCCESS,
false, rr_wild_,
ZoneFinder::RESULT_WILDCARD | expected_flags, NULL,
- ZoneFinder::FIND_DEFAULT, true);
+ find_options, true);
// Wildcard match, but no data
findTest(Name("a.wild.example.org"), RRType::AAAA(),
ZoneFinder::NXRRSET, true, ConstRRsetPtr(),
- ZoneFinder::RESULT_WILDCARD | expected_flags);
+ ZoneFinder::RESULT_WILDCARD | expected_flags, NULL,
+ find_options);
}
// Search name that has CNAME.
@@ -1129,7 +1172,7 @@ InMemoryZoneFinderTest::wildcardCheck(
findTest(Name("a.cnamewild.example.org"), RRType::A(),
ZoneFinder::CNAME, false, rr_cnamewild_,
ZoneFinder::RESULT_WILDCARD | expected_flags, NULL,
- ZoneFinder::FIND_DEFAULT, true);
+ find_options, true);
}
// Search another created name, this time little bit lower
@@ -1138,14 +1181,15 @@ InMemoryZoneFinderTest::wildcardCheck(
findTest(Name("a.b.wild.example.org"), RRType::A(),
ZoneFinder::SUCCESS, false, rr_wild_,
ZoneFinder::RESULT_WILDCARD | expected_flags, NULL,
- ZoneFinder::FIND_DEFAULT, true);
+ find_options, true);
}
EXPECT_EQ(SUCCESS, zone_finder_.add(rr_under_wild_));
{
SCOPED_TRACE("Search under non-wildcard");
findTest(Name("bar.foo.wild.example.org"), RRType::A(),
- ZoneFinder::NXDOMAIN, true, ConstRRsetPtr(), expected_flags);
+ ZoneFinder::NXDOMAIN, true, ConstRRsetPtr(), expected_flags,
+ NULL, find_options);
}
}
diff --git a/src/lib/datasrc/tests/static_unittest.cc b/src/lib/datasrc/tests/static_unittest.cc
index 08f2582..6d6bd74 100644
--- a/src/lib/datasrc/tests/static_unittest.cc
+++ b/src/lib/datasrc/tests/static_unittest.cc
@@ -56,6 +56,7 @@ protected:
authors_data.push_back("Dmitriy Volodin");
authors_data.push_back("Evan Hunt");
authors_data.push_back("Haidong Wang");
+ authors_data.push_back("Haikuo Zhang");
authors_data.push_back("Han Feng");
authors_data.push_back("Jelte Jansen");
authors_data.push_back("Jeremy C. Reed");
diff --git a/src/lib/dhcp/iface_mgr.cc b/src/lib/dhcp/iface_mgr.cc
index b704370..14de5a0 100644
--- a/src/lib/dhcp/iface_mgr.cc
+++ b/src/lib/dhcp/iface_mgr.cc
@@ -130,7 +130,7 @@ IfaceMgr::IfaceMgr()
// interface detection is implemented. Otherwise
// it is not possible to run tests in a portable
// way (see detectIfaces() method).
- throw ex;
+ throw;
}
}
@@ -191,7 +191,7 @@ IfaceMgr::stubDetectIfaces() {
// TODO Do LOG_FATAL here
std::cerr << "Interface detection failed." << std::endl;
- throw ex;
+ throw;
}
}
diff --git a/src/lib/dns/benchmarks/rdatarender_bench.cc b/src/lib/dns/benchmarks/rdatarender_bench.cc
index d1fb0f2..368ea6a 100644
--- a/src/lib/dns/benchmarks/rdatarender_bench.cc
+++ b/src/lib/dns/benchmarks/rdatarender_bench.cc
@@ -42,7 +42,7 @@ template <typename T>
class RdataRenderBenchMark {
public:
RdataRenderBenchMark(const vector<T>& dataset) :
- dataset_(dataset), buffer_(4096), renderer_(buffer_)
+ dataset_(dataset)
{}
unsigned int run() {
typename vector<T>::const_iterator data;
@@ -55,7 +55,6 @@ public:
}
private:
const vector<T>& dataset_;
- OutputBuffer buffer_;
MessageRenderer renderer_;
};
diff --git a/src/lib/dns/masterload.cc b/src/lib/dns/masterload.cc
index 000487c..0b195f6 100644
--- a/src/lib/dns/masterload.cc
+++ b/src/lib/dns/masterload.cc
@@ -37,6 +37,29 @@ using namespace isc::dns::rdata;
namespace isc {
namespace dns {
+namespace {
+// A helper function that strips off any comment or whitespace at the end of
+// an RR.
+// This is an incomplete implementation, and cannot handle all such comments;
+// it's considered a short term workaround to deal with some real world
+// cases.
+string
+stripLine(string& s, const Exception& ex) {
+ // Find any ';' in the text data, and locate the position of the last
+ // occurrence. Note that unless/until we support empty RDATA it
+ // shouldn't be placed at the beginning of the data.
+ const size_t pos_semicolon = s.rfind(';');
+ if (pos_semicolon == 0) {
+ throw ex;
+ } else if (pos_semicolon != string::npos) {
+ s.resize(pos_semicolon);
+ }
+ // Remove any trailing whitespace return the resulting text.
+ s.resize(s.find_last_not_of(" \t") + 1);
+ return (s);
+}
+}
+
void
masterLoad(const char* const filename, const Name& origin,
const RRClass& zone_class, MasterLoadCallback callback)
@@ -116,7 +139,15 @@ masterLoad(istream& input, const Name& origin, const RRClass& zone_class,
ttl.reset(new RRTTL(ttl_txt));
rrclass.reset(new RRClass(rrclass_txt));
rrtype.reset(new RRType(rrtype_txt));
- rdata = createRdata(*rrtype, *rrclass, rdatabuf.str());
+ string rdtext = rdatabuf.str();
+ try {
+ rdata = createRdata(*rrtype, *rrclass, rdtext);
+ } catch (const Exception& ex) {
+ // If the parse for the RDATA fails, check if it has comments
+ // or whitespace at the end, and if so, retry the conversion
+ // after stripping off the comment or whitespace
+ rdata = createRdata(*rrtype, *rrclass, stripLine(rdtext, ex));
+ }
} catch (const Exception& ex) {
isc_throw(MasterLoadError, "Invalid RR text at line " << line_count
<< ": " << ex.what());
diff --git a/src/lib/dns/messagerenderer.cc b/src/lib/dns/messagerenderer.cc
index 1378ba9..bf4795a 100644
--- a/src/lib/dns/messagerenderer.cc
+++ b/src/lib/dns/messagerenderer.cc
@@ -12,14 +12,15 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#include <cctype>
-#include <cassert>
-#include <set>
-
+#include <exceptions/exceptions.h>
#include <util/buffer.h>
#include <dns/name.h>
#include <dns/messagerenderer.h>
+#include <cctype>
+#include <cassert>
+#include <set>
+
using namespace isc::util;
namespace isc {
@@ -171,8 +172,8 @@ struct MessageRenderer::MessageRendererImpl {
CompressMode compress_mode_;
};
-MessageRenderer::MessageRenderer(OutputBuffer& buffer) :
- AbstractMessageRenderer(buffer),
+MessageRenderer::MessageRenderer() :
+ AbstractMessageRenderer(),
impl_(new MessageRendererImpl)
{}
@@ -273,9 +274,34 @@ MessageRenderer::writeName(const Name& name, const bool compress) {
}
}
+AbstractMessageRenderer::AbstractMessageRenderer() :
+ local_buffer_(0), buffer_(&local_buffer_)
+{
+}
+
+void
+AbstractMessageRenderer::setBuffer(OutputBuffer* buffer) {
+ if (buffer != NULL && buffer_->getLength() != 0) {
+ isc_throw(isc::InvalidParameter,
+ "MessageRenderer buffer cannot be set when in use");
+ } if (buffer == NULL && buffer_ == &local_buffer_) {
+ isc_throw(isc::InvalidParameter,
+ "Default MessageRenderer buffer cannot be reset");
+ }
+
+ if (buffer == NULL) {
+ // Reset to the default buffer, then clear other internal resources.
+ // The order is important; we need to keep the used buffer intact.
+ buffer_ = &local_buffer_;
+ clear();
+ } else {
+ buffer_ = buffer;
+ }
+}
+
void
AbstractMessageRenderer::clear() {
- buffer_.clear();
+ buffer_->clear();
}
}
diff --git a/src/lib/dns/messagerenderer.h b/src/lib/dns/messagerenderer.h
index 52d9245..f7f2381 100644
--- a/src/lib/dns/messagerenderer.h
+++ b/src/lib/dns/messagerenderer.h
@@ -37,9 +37,15 @@ class Name;
/// comprehensive \c Message class internally; normal applications won't have
/// to care about details of this class.
///
-/// Once a renderer class object is constructed with a buffer, it is
-/// generally expected that all rendering operations are performed via that
-/// object. If the application modifies the buffer in
+/// By default any (derived) renderer class object is associated with
+/// an internal buffer, and subsequent write operations will be performed
+/// on that buffer. The rendering result can be retrieved via the
+/// \c getData() method.
+///
+/// If an application wants a separate buffer can be (normally temporarily)
+/// set for rendering operations via the \c setBuffer() method. In that case,
+/// it is generally expected that all rendering operations are performed via
+/// that object. If the application modifies the buffer in
/// parallel with the renderer, the result will be undefined.
///
/// Note to developers: we introduced a separate class for name compression
@@ -101,30 +107,30 @@ protected:
///
/// This is intentionally defined as \c protected as this base class should
/// never be instantiated (except as part of a derived class).
- /// \param buffer The buffer where the data should be rendered into.
- /// \todo We might want to revisit this API at some point and remove the
- /// buffer parameter. In that case it would create it's own buffer and
- /// a function to extract the data would be available instead. It seems
- /// like a cleaner design, but it's left undone until we would actually
- /// benefit from the change.
- AbstractMessageRenderer(isc::util::OutputBuffer& buffer) :
- buffer_(buffer)
- {}
+ AbstractMessageRenderer();
+
public:
/// \brief The destructor.
virtual ~AbstractMessageRenderer() {}
//@}
protected:
/// \brief Return the output buffer we render into.
- const isc::util::OutputBuffer& getBuffer() const { return (buffer_); }
- isc::util::OutputBuffer& getBuffer() { return (buffer_); }
+ const isc::util::OutputBuffer& getBuffer() const { return (*buffer_); }
+ isc::util::OutputBuffer& getBuffer() { return (*buffer_); }
private:
- /// \short Buffer to store data
+ /// \brief Local (default) buffer to store data.
+ isc::util::OutputBuffer local_buffer_;
+
+ /// \brief Buffer to store data.
+ ///
+ /// Note that the class interface ensures this pointer is never NULL;
+ /// it either refers to \c local_buffer_ or to an application-supplied
+ /// buffer by \c setBuffer().
///
/// It was decided that there's no need to have this in every subclass,
- /// at least not now, and this reduces code size and gives compiler a better
- /// chance to optimise.
- isc::util::OutputBuffer& buffer_;
+ /// at least not now, and this reduces code size and gives compiler a
+ /// better chance to optimise.
+ isc::util::OutputBuffer* buffer_;
public:
///
/// \name Getter Methods
@@ -136,12 +142,12 @@ public:
/// This method works exactly same as the same method of the \c OutputBuffer
/// class; all notes for \c OutputBuffer apply.
const void* getData() const {
- return (buffer_.getData());
+ return (buffer_->getData());
}
/// \brief Return the length of data written in the internal buffer.
size_t getLength() const {
- return (buffer_.getLength());
+ return (buffer_->getLength());
}
/// \brief Return whether truncation has occurred while rendering.
@@ -175,6 +181,35 @@ public:
/// \name Setter Methods
///
//@{
+ /// \brief Set or reset a temporary output buffer.
+ ///
+ /// This method can be used for an application that manages an output
+ /// buffer separately from the message renderer and wants to keep reusing
+ /// the renderer. When the renderer is associated with the default buffer
+ /// and the given pointer is non NULL, the given buffer will be
+ /// (temporarily) used for subsequent message rendering; if the renderer
+ /// is associated with a temporary buffer and the given pointer is NULL,
+ /// the renderer will be reset with the default buffer. In the latter
+ /// case any additional resources (possibly specific to a derived renderer
+ /// class) will be cleared, but the temporary buffer is kept as the latest
+ /// state (which would normally store the rendering result).
+ ///
+ /// This method imposes some restrictions to prevent accidental misuse
+ /// that could cause disruption such as dereferencing an invalid object.
+ /// First, a temporary buffer must not be set when the associated buffer
+ /// is in use, that is, any data are stored in the buffer. Also, the
+ /// default buffer cannot be "reset"; when NULL is specified a temporary
+ /// buffer must have been set beforehand. If these conditions aren't met
+ /// an isc::InvalidParameter exception will be thrown. This method is
+ /// exception free otherwise.
+ ///
+ /// \throw isc::InvalidParameter A restrictions of the method usage isn't
+ /// met.
+ ///
+ /// \param buffer A pointer to a temporary output buffer or NULL for reset
+ /// it.
+ void setBuffer(isc::util::OutputBuffer* buffer);
+
/// \brief Mark the renderer to indicate truncation has occurred while
/// rendering.
///
@@ -209,7 +244,7 @@ public:
///
/// \param len The length of the gap to be inserted in bytes.
void skip(size_t len) {
- buffer_.skip(len);
+ buffer_->skip(len);
}
/// \brief Trim the specified length of data from the end of the internal
@@ -223,7 +258,7 @@ public:
///
/// \param len The length of data that should be trimmed.
void trim(size_t len) {
- buffer_.trim(len);
+ buffer_->trim(len);
}
/// \brief Clear the internal buffer and other internal resources.
@@ -236,7 +271,7 @@ public:
///
/// \param data The 8-bit integer to be written into the internal buffer.
void writeUint8(const uint8_t data) {
- buffer_.writeUint8(data);
+ buffer_->writeUint8(data);
}
/// \brief Write an unsigned 16-bit integer in host byte order into the
@@ -244,7 +279,7 @@ public:
///
/// \param data The 16-bit integer to be written into the buffer.
void writeUint16(uint16_t data) {
- buffer_.writeUint16(data);
+ buffer_->writeUint16(data);
}
/// \brief Write an unsigned 16-bit integer in host byte order at the
@@ -259,7 +294,7 @@ public:
/// \param data The 16-bit integer to be written into the internal buffer.
/// \param pos The beginning position in the buffer to write the data.
void writeUint16At(uint16_t data, size_t pos) {
- buffer_.writeUint16At(data, pos);
+ buffer_->writeUint16At(data, pos);
}
/// \brief Write an unsigned 32-bit integer in host byte order into the
@@ -267,7 +302,7 @@ public:
///
/// \param data The 32-bit integer to be written into the buffer.
void writeUint32(uint32_t data) {
- buffer_.writeUint32(data);
+ buffer_->writeUint32(data);
}
/// \brief Copy an arbitrary length of data into the internal buffer
@@ -278,7 +313,7 @@ public:
/// \param data A pointer to the data to be copied into the internal buffer.
/// \param len The length of the data in bytes.
void writeData(const void *data, size_t len) {
- buffer_.writeData(data, len);
+ buffer_->writeData(data, len);
}
/// \brief Write a \c Name object into the internal buffer in wire format,
@@ -316,10 +351,7 @@ public:
using AbstractMessageRenderer::CASE_SENSITIVE;
/// \brief Constructor from an output buffer.
- ///
- /// \param buffer An \c OutputBuffer object to which wire format data is
- /// written.
- MessageRenderer(isc::util::OutputBuffer& buffer);
+ MessageRenderer();
virtual ~MessageRenderer();
virtual bool isTruncated() const;
diff --git a/src/lib/dns/python/message_python.cc b/src/lib/dns/python/message_python.cc
index 2f1e2e5..c7ad2ff 100644
--- a/src/lib/dns/python/message_python.cc
+++ b/src/lib/dns/python/message_python.cc
@@ -377,8 +377,9 @@ Message_getTSIGRecord(s_Message* self) {
if (tsig_record == NULL) {
Py_RETURN_NONE;
+ } else {
+ return (createTSIGRecordObject(*tsig_record));
}
- return (createTSIGRecordObject(*tsig_record));
} catch (const InvalidMessageOperation& ex) {
PyErr_SetString(po_InvalidMessageOperation, ex.what());
} catch (const exception& ex) {
diff --git a/src/lib/dns/python/messagerenderer_python.cc b/src/lib/dns/python/messagerenderer_python.cc
index bb89622..5561c12 100644
--- a/src/lib/dns/python/messagerenderer_python.cc
+++ b/src/lib/dns/python/messagerenderer_python.cc
@@ -36,7 +36,6 @@ namespace {
class s_MessageRenderer : public PyObject {
public:
s_MessageRenderer();
- isc::util::OutputBuffer* outputbuffer;
MessageRenderer* cppobj;
};
@@ -78,17 +77,14 @@ PyMethodDef MessageRenderer_methods[] = {
int
MessageRenderer_init(s_MessageRenderer* self) {
- self->outputbuffer = new OutputBuffer(4096);
- self->cppobj = new MessageRenderer(*self->outputbuffer);
+ self->cppobj = new MessageRenderer;
return (0);
}
void
MessageRenderer_destroy(s_MessageRenderer* self) {
delete self->cppobj;
- delete self->outputbuffer;
self->cppobj = NULL;
- self->outputbuffer = NULL;
Py_TYPE(self)->tp_free(self);
}
diff --git a/src/lib/dns/rdatafields.cc b/src/lib/dns/rdatafields.cc
index af9ba2e..94c9dbf 100644
--- a/src/lib/dns/rdatafields.cc
+++ b/src/lib/dns/rdatafields.cc
@@ -70,8 +70,7 @@ namespace {
// it's hopefully an acceptable practice.
class RdataFieldComposer : public AbstractMessageRenderer {
public:
- RdataFieldComposer(OutputBuffer& buffer) :
- AbstractMessageRenderer(buffer),
+ RdataFieldComposer() :
truncated_(false), length_limit_(65535),
mode_(CASE_INSENSITIVE), last_data_pos_(0)
{}
@@ -128,8 +127,7 @@ public:
}
RdataFields::RdataFields(const Rdata& rdata) {
- OutputBuffer buffer(0);
- RdataFieldComposer field_composer(buffer);
+ RdataFieldComposer field_composer;
rdata.toWire(field_composer);
nfields_ = field_composer.getFields().size();
data_length_ = field_composer.getLength();
diff --git a/src/lib/dns/tests/edns_unittest.cc b/src/lib/dns/tests/edns_unittest.cc
index 26cc01c..de2d244 100644
--- a/src/lib/dns/tests/edns_unittest.cc
+++ b/src/lib/dns/tests/edns_unittest.cc
@@ -43,9 +43,7 @@ const uint8_t EDNS::SUPPORTED_VERSION;
namespace {
class EDNSTest : public ::testing::Test {
protected:
- EDNSTest() : rrtype(RRType::OPT()), buffer(NULL, 0), obuffer(0),
- renderer(obuffer), rcode(0)
- {
+ EDNSTest() : rrtype(RRType::OPT()), buffer(NULL, 0), obuffer(0), rcode(0) {
opt_rdata = ConstRdataPtr(new generic::OPT());
edns_base.setUDPSize(4096);
}
diff --git a/src/lib/dns/tests/masterload_unittest.cc b/src/lib/dns/tests/masterload_unittest.cc
index acb9d64..95ce6f3 100644
--- a/src/lib/dns/tests/masterload_unittest.cc
+++ b/src/lib/dns/tests/masterload_unittest.cc
@@ -25,6 +25,7 @@
#include <dns/masterload.h>
#include <dns/name.h>
+#include <dns/rdata.h>
#include <dns/rrclass.h>
#include <dns/rrset.h>
@@ -80,6 +81,11 @@ const char* const rrsig_rr2 =
"www.example.com. 60 IN RRSIG AAAA 5 3 3600 20000101000000 20000201000000 "
"12345 example.com. FAKEFAKEFAKE\n";
+// Commonly used for some tests to check the constructed RR content.
+const char* const dnskey_rdata =
+ "256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LUsAD0QPWU+wzt89epO6tH "
+ "zkMBVDkC7qphQO2hTY4hHn9npWFRw5BYubE=\n";
+
TEST_F(MasterLoadTest, loadRRs) {
// a simple case: loading 3 RRs, each consists of a single RRset.
rr_stream << txt_rr << a_rr1 << soa_rr;
@@ -161,6 +167,98 @@ TEST_F(MasterLoadTest, loadRRsigs) {
EXPECT_EQ(2, results.size());
}
+TEST_F(MasterLoadTest, loadRRWithComment) {
+ // Comment at the end of line should be ignored and the RR should be
+ // accepted.
+ rr_stream << "example.com. 3600 IN DNSKEY 256 3 7 "
+ "AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LUsAD0QPWU+wzt89epO6tH "
+ "zkMBVDkC7qphQO2hTY4hHn9npWFRw5BYubE= ; key id = 40430\n";
+ masterLoad(rr_stream, origin, zclass, callback);
+ ASSERT_EQ(1, results.size());
+ EXPECT_EQ(0, results[0]->getRdataIterator()->getCurrent().compare(
+ *rdata::createRdata(RRType::DNSKEY(), zclass,
+ dnskey_rdata)));
+}
+
+TEST_F(MasterLoadTest, loadRRWithCommentNoSpace) {
+ // Similar to the previous one, but there's no space before comments.
+ // It should still work.
+ rr_stream << "example.com. 3600 IN DNSKEY 256 3 7 "
+ "AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LUsAD0QPWU+wzt89epO6tH "
+ "zkMBVDkC7qphQO2hTY4hHn9npWFRw5BYubE=; key id = 40430\n";
+ masterLoad(rr_stream, origin, zclass, callback);
+ ASSERT_EQ(1, results.size());
+ EXPECT_EQ(0, results[0]->getRdataIterator()->getCurrent().compare(
+ *rdata::createRdata(RRType::DNSKEY(), zclass,
+ dnskey_rdata)));
+}
+
+TEST_F(MasterLoadTest, loadRRWithCommentEmptyComment) {
+ // Similar to the previous one, but there's no data after the ;
+ // It should still work.
+ rr_stream << "example.com. 3600 IN DNSKEY 256 3 7 "
+ "AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LUsAD0QPWU+wzt89epO6tH "
+ "zkMBVDkC7qphQO2hTY4hHn9npWFRw5BYubE= ;\n";
+ masterLoad(rr_stream, origin, zclass, callback);
+ ASSERT_EQ(1, results.size());
+ EXPECT_EQ(0, results[0]->getRdataIterator()->getCurrent().compare(
+ *rdata::createRdata(RRType::DNSKEY(), zclass,
+ dnskey_rdata)));
+}
+
+TEST_F(MasterLoadTest, loadRRWithCommentEmptyCommentNoSpace) {
+ // Similar to the previous one, but there's no space before or after ;
+ // It should still work.
+ rr_stream << "example.com. 3600 IN DNSKEY 256 3 7 "
+ "AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LUsAD0QPWU+wzt89epO6tH "
+ "zkMBVDkC7qphQO2hTY4hHn9npWFRw5BYubE=;\n";
+ masterLoad(rr_stream, origin, zclass, callback);
+ ASSERT_EQ(1, results.size());
+ EXPECT_EQ(0, results[0]->getRdataIterator()->getCurrent().compare(
+ *rdata::createRdata(RRType::DNSKEY(), zclass,
+ dnskey_rdata)));
+}
+
+TEST_F(MasterLoadTest, loadRRWithEOLWhitespace) {
+ // Test with whitespace after rdata
+ // It should still work.
+ rr_stream << "example.com. 3600 IN NSEC3PARAM 1 0 1 beef \n";
+ masterLoad(rr_stream, origin, zclass, callback);
+ ASSERT_EQ(1, results.size());
+ EXPECT_EQ(0, results[0]->getRdataIterator()->getCurrent().compare(
+ *rdata::createRdata(RRType::NSEC3PARAM(), zclass,
+ "1 0 1 beef")));
+}
+
+TEST_F(MasterLoadTest, loadRRWithEOLWhitespaceTab) {
+ // Similar to the previous one, tab instead of space.
+ // It should still work.
+ rr_stream << "example.com. 3600 IN NSEC3PARAM 1 0 1 beef\t\n";
+ masterLoad(rr_stream, origin, zclass, callback);
+ ASSERT_EQ(1, results.size());
+ EXPECT_EQ(0, results[0]->getRdataIterator()->getCurrent().compare(
+ *rdata::createRdata(RRType::NSEC3PARAM(), zclass,
+ "1 0 1 beef")));
+}
+
+TEST_F(MasterLoadTest, loadRRNoComment) {
+ // A semicolon in a character-string shouldn't confuse the parser.
+ rr_stream << "example.com. 3600 IN TXT \"aaa;bbb\"\n";
+ masterLoad(rr_stream, origin, zclass, callback);
+ EXPECT_EQ(1, results.size());
+ EXPECT_EQ(0, results[0]->getRdataIterator()->getCurrent().compare(
+ *rdata::createRdata(RRType::TXT(), zclass,
+ "\"aaa;bbb\"")));
+}
+
+TEST_F(MasterLoadTest, loadRREmptyAndComment) {
+ // There's no RDATA (invalid in this case) but a comment. This position
+ // shouldn't cause any disruption and should be treated as a normal error.
+ rr_stream << "example.com. 3600 IN A ;\n";
+ EXPECT_THROW(masterLoad(rr_stream, origin, zclass, callback),
+ MasterLoadError);
+}
+
TEST_F(MasterLoadTest, loadWithNoEOF) {
// the input stream doesn't end with a new line (and the following blank
// line). It should be accepted.
diff --git a/src/lib/dns/tests/message_unittest.cc b/src/lib/dns/tests/message_unittest.cc
index c5bc7fd..3be1436 100644
--- a/src/lib/dns/tests/message_unittest.cc
+++ b/src/lib/dns/tests/message_unittest.cc
@@ -79,7 +79,6 @@ namespace {
class MessageTest : public ::testing::Test {
protected:
MessageTest() : test_name("test.example.com"), obuffer(0),
- renderer(obuffer),
message_parse(Message::PARSE),
message_render(Message::RENDER),
bogus_section(static_cast<Message::Section>(
@@ -731,8 +730,8 @@ TEST_F(MessageTest, toWire) {
message_render.toWire(renderer);
vector<unsigned char> data;
UnitTestUtil::readWireData("message_toWire1", data);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, obuffer.getData(),
- obuffer.getLength(), &data[0], data.size());
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
+ renderer.getLength(), &data[0], data.size());
}
TEST_F(MessageTest, toWireInParseMode) {
@@ -961,9 +960,6 @@ TEST_F(MessageTest, toWireTSIGNoTruncation) {
// rendering fail unexpectedly in the test that follows.
class BadRenderer : public MessageRenderer {
public:
- BadRenderer(isc::util::OutputBuffer& buffer) :
- MessageRenderer(buffer)
- {}
virtual void setLengthLimit(size_t len) {
if (getLength() > 0) {
MessageRenderer::setLengthLimit(getLength());
@@ -994,8 +990,7 @@ TEST_F(MessageTest, toWireTSIGLengthErrors) {
InvalidParameter);
// Trying to render a message with TSIG using a buggy renderer.
- obuffer.clear();
- BadRenderer bad_renderer(obuffer);
+ BadRenderer bad_renderer;
bad_renderer.setLengthLimit(512);
message_render.clear(Message::RENDER);
EXPECT_THROW(commonTSIGToWireCheck(message_render, bad_renderer, tsig_ctx,
diff --git a/src/lib/dns/tests/messagerenderer_unittest.cc b/src/lib/dns/tests/messagerenderer_unittest.cc
index fe790fe..2a1869f 100644
--- a/src/lib/dns/tests/messagerenderer_unittest.cc
+++ b/src/lib/dns/tests/messagerenderer_unittest.cc
@@ -12,8 +12,7 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#include <vector>
-
+#include <exceptions/exceptions.h>
#include <util/buffer.h>
#include <dns/name.h>
#include <dns/messagerenderer.h>
@@ -22,6 +21,8 @@
#include <gtest/gtest.h>
+#include <vector>
+
using isc::UnitTestUtil;
using isc::dns::Name;
using isc::dns::MessageRenderer;
@@ -30,15 +31,13 @@ using isc::util::OutputBuffer;
namespace {
class MessageRendererTest : public ::testing::Test {
protected:
- MessageRendererTest() : expected_size(0), buffer(0), renderer(buffer)
- {
+ MessageRendererTest() : expected_size(0) {
data16 = (2 << 8) | 3;
data32 = (4 << 24) | (5 << 16) | (6 << 8) | 7;
}
size_t expected_size;
uint16_t data16;
uint32_t data32;
- OutputBuffer buffer;
MessageRenderer renderer;
std::vector<unsigned char> data;
static const uint8_t testdata[5];
@@ -60,21 +59,22 @@ TEST_F(MessageRendererTest, writeName) {
renderer.writeName(Name("a.example.com."));
renderer.writeName(Name("b.example.com."));
renderer.writeName(Name("a.example.org."));
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer.getData(),
- buffer.getLength(), &data[0], data.size());
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
+ renderer.getLength(), &data[0], data.size());
}
TEST_F(MessageRendererTest, writeNameInLargeBuffer) {
size_t offset = 0x3fff;
- buffer.skip(offset);
+ renderer.skip(offset);
UnitTestUtil::readWireData("name_toWire2", data);
renderer.writeName(Name("a.example.com."));
renderer.writeName(Name("a.example.com."));
renderer.writeName(Name("b.example.com."));
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- static_cast<const uint8_t*>(buffer.getData()) + offset,
- buffer.getLength() - offset,
+ static_cast<const uint8_t*>(renderer.getData()) +
+ offset,
+ renderer.getLength() - offset,
&data[0], data.size());
}
@@ -83,8 +83,8 @@ TEST_F(MessageRendererTest, writeNameWithUncompressed) {
renderer.writeName(Name("a.example.com."));
renderer.writeName(Name("b.example.com."), false);
renderer.writeName(Name("b.example.com."));
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer.getData(),
- buffer.getLength(), &data[0], data.size());
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
+ renderer.getLength(), &data[0], data.size());
}
TEST_F(MessageRendererTest, writeNamePointerChain) {
@@ -92,8 +92,8 @@ TEST_F(MessageRendererTest, writeNamePointerChain) {
renderer.writeName(Name("a.example.com."));
renderer.writeName(Name("b.example.com."));
renderer.writeName(Name("b.example.com."));
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer.getData(),
- buffer.getLength(), &data[0], data.size());
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
+ renderer.getLength(), &data[0], data.size());
}
TEST_F(MessageRendererTest, compressMode) {
@@ -120,8 +120,8 @@ TEST_F(MessageRendererTest, writeNameCaseCompress) {
// this should match the first name in terms of compression:
renderer.writeName(Name("b.exAmple.CoM."));
renderer.writeName(Name("a.example.org."));
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer.getData(),
- buffer.getLength(), &data[0], data.size());
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
+ renderer.getLength(), &data[0], data.size());
}
TEST_F(MessageRendererTest, writeNameCaseSensitiveCompress) {
@@ -132,8 +132,8 @@ TEST_F(MessageRendererTest, writeNameCaseSensitiveCompress) {
renderer.writeName(Name("a.example.com."));
renderer.writeName(Name("b.eXample.com."));
renderer.writeName(Name("c.eXample.com."));
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer.getData(),
- buffer.getLength(), &data[0], data.size());
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
+ renderer.getLength(), &data[0], data.size());
}
TEST_F(MessageRendererTest, writeNameMixedCaseCompress) {
@@ -147,8 +147,8 @@ TEST_F(MessageRendererTest, writeNameMixedCaseCompress) {
// allowed in this API.
renderer.setCompressMode(MessageRenderer::CASE_INSENSITIVE);
renderer.writeName(Name("c.b.EXAMPLE.com."));
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer.getData(),
- buffer.getLength(), &data[0], data.size());
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
+ renderer.getLength(), &data[0], data.size());
}
TEST_F(MessageRendererTest, writeRootName) {
@@ -164,9 +164,51 @@ TEST_F(MessageRendererTest, writeRootName) {
renderer.writeName(Name("."));
renderer.writeName(example_name);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- static_cast<const uint8_t*>(buffer.getData()),
- buffer.getLength(),
+ static_cast<const uint8_t*>(renderer.getData()),
+ renderer.getLength(),
static_cast<const uint8_t*>(expected.getData()),
expected.getLength());
}
+
+TEST_F(MessageRendererTest, setBuffer) {
+ OutputBuffer new_buffer(0);
+ renderer.setBuffer(&new_buffer);
+ EXPECT_EQ(0, new_buffer.getLength()); // the buffer should be still empty
+ renderer.writeUint32(42);
+ EXPECT_EQ(sizeof(uint32_t), new_buffer.getLength());
+ EXPECT_EQ(sizeof(uint32_t), renderer.getLength());
+
+ // Change some other internal state for the reset test below.
+ EXPECT_EQ(512, renderer.getLengthLimit());
+ renderer.setLengthLimit(4096);
+ EXPECT_EQ(4096, renderer.getLengthLimit());
+
+ // Reset the buffer to the default again. Other internal states and
+ // resources should be cleared. The used buffer should be intact.
+ renderer.setBuffer(NULL);
+ EXPECT_EQ(sizeof(uint32_t), new_buffer.getLength());
+ EXPECT_EQ(0, renderer.getLength());
+ EXPECT_EQ(512, renderer.getLengthLimit());
+}
+
+TEST_F(MessageRendererTest, setBufferErrors) {
+ OutputBuffer new_buffer(0);
+
+ // Buffer cannot be reset when the renderer is in use.
+ renderer.writeUint32(10);
+ EXPECT_THROW(renderer.setBuffer(&new_buffer), isc::InvalidParameter);
+
+ renderer.clear();
+ renderer.setBuffer(&new_buffer);
+ renderer.writeUint32(10);
+ EXPECT_THROW(renderer.setBuffer(&new_buffer), isc::InvalidParameter);
+
+ // Resetting the buffer isn't allowed for the default buffer.
+ renderer.setBuffer(NULL);
+ EXPECT_THROW(renderer.setBuffer(NULL), isc::InvalidParameter);
+
+ // It's okay to reset a temporary buffer without using it.
+ renderer.setBuffer(&new_buffer);
+ EXPECT_NO_THROW(renderer.setBuffer(NULL));
+}
}
diff --git a/src/lib/dns/tests/name_unittest.cc b/src/lib/dns/tests/name_unittest.cc
index 6434229..c5f3b7f 100644
--- a/src/lib/dns/tests/name_unittest.cc
+++ b/src/lib/dns/tests/name_unittest.cc
@@ -357,13 +357,12 @@ TEST_F(NameTest, toWireBuffer) {
//
TEST_F(NameTest, toWireRenderer) {
vector<unsigned char> data;
- OutputBuffer buffer(0);
- MessageRenderer renderer(buffer);
+ MessageRenderer renderer;
UnitTestUtil::readWireData(string("01610376697803636f6d00"), data);
Name("a.vix.com.").toWire(renderer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, &data[0], data.size(),
- buffer.getData(), buffer.getLength());
+ renderer.getData(), renderer.getLength());
}
//
@@ -524,8 +523,8 @@ TEST_F(NameTest, at) {
example_name.toWire(buffer_expected);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- &data[0], data.size(),
- buffer_expected.getData(), buffer_expected.getLength());
+ &data[0], data.size(), buffer_expected.getData(),
+ buffer_expected.getLength());
// Out-of-range access: should trigger an exception.
EXPECT_THROW(example_name.at(example_name.getLength()), OutOfRange);
@@ -543,7 +542,7 @@ TEST_F(NameTest, leq) {
// small <= small is true
EXPECT_TRUE(small_name.leq(small_name));
- EXPECT_TRUE(small_name <= small_name);
+ EXPECT_LE(small_name, small_name);
// large <= small is false
EXPECT_FALSE(large_name.leq(small_name));
@@ -555,7 +554,7 @@ TEST_F(NameTest, geq) {
EXPECT_TRUE(large_name >= small_name);
EXPECT_TRUE(large_name.geq(large_name));
- EXPECT_TRUE(large_name >= large_name);
+ EXPECT_GE(large_name, large_name);
EXPECT_FALSE(small_name.geq(large_name));
EXPECT_FALSE(small_name >= large_name);
diff --git a/src/lib/dns/tests/question_unittest.cc b/src/lib/dns/tests/question_unittest.cc
index 1d483f2..54d0942 100644
--- a/src/lib/dns/tests/question_unittest.cc
+++ b/src/lib/dns/tests/question_unittest.cc
@@ -37,7 +37,7 @@ using namespace isc::util;
namespace {
class QuestionTest : public ::testing::Test {
protected:
- QuestionTest() : obuffer(0), renderer(obuffer),
+ QuestionTest() : obuffer(0),
example_name1(Name("foo.example.com")),
example_name2(Name("bar.example.com")),
test_question1(example_name1, RRClass::IN(),
@@ -102,8 +102,8 @@ TEST_F(QuestionTest, toWireRenderer) {
test_question1.toWire(renderer);
test_question2.toWire(renderer);
UnitTestUtil::readWireData("question_toWire2", wiredata);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, obuffer.getData(),
- obuffer.getLength(), &wiredata[0], wiredata.size());
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
+ renderer.getLength(), &wiredata[0], wiredata.size());
}
TEST_F(QuestionTest, toWireTruncated) {
diff --git a/src/lib/dns/tests/rdata_afsdb_unittest.cc b/src/lib/dns/tests/rdata_afsdb_unittest.cc
index 7df8d83..521bec5 100644
--- a/src/lib/dns/tests/rdata_afsdb_unittest.cc
+++ b/src/lib/dns/tests/rdata_afsdb_unittest.cc
@@ -162,7 +162,7 @@ TEST_F(Rdata_AFSDB_Test, toWireRenderer) {
renderer.clear();
// construct actual data
- Name("example.com.").toWire(obuffer);
+ renderer.writeName(Name("example.com."));
rdata_afsdb2.toWire(renderer);
// construct expected data
diff --git a/src/lib/dns/tests/rdata_cname_unittest.cc b/src/lib/dns/tests/rdata_cname_unittest.cc
index d6b02aa..2cce9bc 100644
--- a/src/lib/dns/tests/rdata_cname_unittest.cc
+++ b/src/lib/dns/tests/rdata_cname_unittest.cc
@@ -97,11 +97,11 @@ TEST_F(Rdata_CNAME_Test, toWireBuffer) {
TEST_F(Rdata_CNAME_Test, toWireRenderer) {
rdata_cname.toWire(renderer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
+ renderer.getData(), renderer.getLength(),
wiredata_cname, sizeof(wiredata_cname));
rdata_cname2.toWire(renderer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
+ renderer.getData(), renderer.getLength(),
wiredata_cname2, sizeof(wiredata_cname2));
}
diff --git a/src/lib/dns/tests/rdata_dname_unittest.cc b/src/lib/dns/tests/rdata_dname_unittest.cc
index ebd9e0e..cf3001c 100644
--- a/src/lib/dns/tests/rdata_dname_unittest.cc
+++ b/src/lib/dns/tests/rdata_dname_unittest.cc
@@ -97,11 +97,11 @@ TEST_F(Rdata_DNAME_Test, toWireBuffer) {
TEST_F(Rdata_DNAME_Test, toWireRenderer) {
rdata_dname.toWire(renderer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
+ renderer.getData(), renderer.getLength(),
wiredata_dname, sizeof(wiredata_dname));
rdata_dname2.toWire(renderer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
+ renderer.getData(), renderer.getLength(),
wiredata_dname2, sizeof(wiredata_dname2));
}
diff --git a/src/lib/dns/tests/rdata_dnskey_unittest.cc b/src/lib/dns/tests/rdata_dnskey_unittest.cc
index f0596ed..86b8f69 100644
--- a/src/lib/dns/tests/rdata_dnskey_unittest.cc
+++ b/src/lib/dns/tests/rdata_dnskey_unittest.cc
@@ -90,8 +90,8 @@ TEST_F(Rdata_DNSKEY_Test, toWireRenderer) {
vector<unsigned char> data;
UnitTestUtil::readWireData("rdata_dnskey_fromWire", data);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- static_cast<const uint8_t *>(obuffer.getData()) + 2,
- obuffer.getLength() - 2, &data[2], data.size() - 2);
+ static_cast<const uint8_t *>(renderer.getData()) + 2,
+ renderer.getLength() - 2, &data[2], data.size() - 2);
}
TEST_F(Rdata_DNSKEY_Test, toWireBuffer) {
diff --git a/src/lib/dns/tests/rdata_ds_like_unittest.cc b/src/lib/dns/tests/rdata_ds_like_unittest.cc
index 9b29446..6172431 100644
--- a/src/lib/dns/tests/rdata_ds_like_unittest.cc
+++ b/src/lib/dns/tests/rdata_ds_like_unittest.cc
@@ -115,8 +115,8 @@ TYPED_TEST(Rdata_DS_LIKE_Test, toWireRenderer) {
UnitTestUtil::readWireData("rdata_ds_fromWire", data);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
static_cast<const uint8_t*>
- (this->obuffer.getData()) + 2,
- this->obuffer.getLength() - 2,
+ (this->renderer.getData()) + 2,
+ this->renderer.getLength() - 2,
&data[2], data.size() - 2);
}
diff --git a/src/lib/dns/tests/rdata_hinfo_unittest.cc b/src/lib/dns/tests/rdata_hinfo_unittest.cc
index c52b2a0..c934a4f 100644
--- a/src/lib/dns/tests/rdata_hinfo_unittest.cc
+++ b/src/lib/dns/tests/rdata_hinfo_unittest.cc
@@ -94,8 +94,9 @@ TEST_F(Rdata_HINFO_Test, toWireRenderer) {
HINFO hinfo(hinfo_str);
hinfo.toWire(renderer);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, obuffer.getData(),
- obuffer.getLength(), hinfo_rdata, sizeof(hinfo_rdata));
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
+ renderer.getLength(), hinfo_rdata,
+ sizeof(hinfo_rdata));
}
TEST_F(Rdata_HINFO_Test, compare) {
diff --git a/src/lib/dns/tests/rdata_in_a_unittest.cc b/src/lib/dns/tests/rdata_in_a_unittest.cc
index 47e2bfa..af4369d 100644
--- a/src/lib/dns/tests/rdata_in_a_unittest.cc
+++ b/src/lib/dns/tests/rdata_in_a_unittest.cc
@@ -78,7 +78,7 @@ TEST_F(Rdata_IN_A_Test, toWireBuffer) {
TEST_F(Rdata_IN_A_Test, toWireRenderer) {
rdata_in_a.toWire(renderer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
+ renderer.getData(), renderer.getLength(),
wiredata_in_a, sizeof(wiredata_in_a));
}
diff --git a/src/lib/dns/tests/rdata_in_aaaa_unittest.cc b/src/lib/dns/tests/rdata_in_aaaa_unittest.cc
index 6fd4d0e..c3e1e16 100644
--- a/src/lib/dns/tests/rdata_in_aaaa_unittest.cc
+++ b/src/lib/dns/tests/rdata_in_aaaa_unittest.cc
@@ -76,7 +76,7 @@ TEST_F(Rdata_IN_AAAA_Test, toWireBuffer) {
TEST_F(Rdata_IN_AAAA_Test, toWireRenderer) {
rdata_in_aaaa.toWire(renderer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
+ renderer.getData(), renderer.getLength(),
wiredata_in_aaaa, sizeof(wiredata_in_aaaa));
}
diff --git a/src/lib/dns/tests/rdata_minfo_unittest.cc b/src/lib/dns/tests/rdata_minfo_unittest.cc
index 30c7c39..78e8325 100644
--- a/src/lib/dns/tests/rdata_minfo_unittest.cc
+++ b/src/lib/dns/tests/rdata_minfo_unittest.cc
@@ -142,15 +142,15 @@ TEST_F(Rdata_MINFO_Test, toWireRenderer) {
vector<unsigned char> data;
UnitTestUtil::readWireData("rdata_minfo_toWire1.wire", data);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- static_cast<const uint8_t *>(obuffer.getData()),
- obuffer.getLength(), &data[0], data.size());
+ static_cast<const uint8_t *>(renderer.getData()),
+ renderer.getLength(), &data[0], data.size());
renderer.clear();
rdata_minfo2.toWire(renderer);
vector<unsigned char> data2;
UnitTestUtil::readWireData("rdata_minfo_toWire2.wire", data2);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- static_cast<const uint8_t *>(obuffer.getData()),
- obuffer.getLength(), &data2[0], data2.size());
+ static_cast<const uint8_t *>(renderer.getData()),
+ renderer.getLength(), &data2[0], data2.size());
}
TEST_F(Rdata_MINFO_Test, toText) {
diff --git a/src/lib/dns/tests/rdata_mx_unittest.cc b/src/lib/dns/tests/rdata_mx_unittest.cc
index c4c9757..36814ea 100644
--- a/src/lib/dns/tests/rdata_mx_unittest.cc
+++ b/src/lib/dns/tests/rdata_mx_unittest.cc
@@ -68,12 +68,12 @@ TEST_F(Rdata_MX_Test, toWireRenderer) {
vector<unsigned char> data;
UnitTestUtil::readWireData("rdata_mx_toWire1", data);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, obuffer.getData(),
- obuffer.getLength(), &data[0], data.size());
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
+ renderer.getLength(), &data[0], data.size());
}
TEST_F(Rdata_MX_Test, toWireBuffer) {
- renderer.writeName(Name("example.com"));
+ Name("example.com").toWire(obuffer);
rdata_mx.toWire(obuffer);
vector<unsigned char> data;
diff --git a/src/lib/dns/tests/rdata_naptr_unittest.cc b/src/lib/dns/tests/rdata_naptr_unittest.cc
index f905943..5abcaef 100644
--- a/src/lib/dns/tests/rdata_naptr_unittest.cc
+++ b/src/lib/dns/tests/rdata_naptr_unittest.cc
@@ -140,8 +140,9 @@ TEST_F(Rdata_NAPTR_Test, toWireRenderer) {
NAPTR naptr(naptr_str);
naptr.toWire(renderer);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, obuffer.getData(),
- obuffer.getLength(), naptr_rdata, sizeof(naptr_rdata));
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
+ renderer.getLength(), naptr_rdata,
+ sizeof(naptr_rdata));
}
TEST_F(Rdata_NAPTR_Test, toText) {
diff --git a/src/lib/dns/tests/rdata_ns_unittest.cc b/src/lib/dns/tests/rdata_ns_unittest.cc
index b805783..47582ce 100644
--- a/src/lib/dns/tests/rdata_ns_unittest.cc
+++ b/src/lib/dns/tests/rdata_ns_unittest.cc
@@ -96,11 +96,11 @@ TEST_F(Rdata_NS_Test, toWireBuffer) {
TEST_F(Rdata_NS_Test, toWireRenderer) {
rdata_ns.toWire(renderer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
+ renderer.getData(), renderer.getLength(),
wiredata_ns, sizeof(wiredata_ns));
rdata_ns2.toWire(renderer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
+ renderer.getData(), renderer.getLength(),
wiredata_ns2, sizeof(wiredata_ns2));
}
diff --git a/src/lib/dns/tests/rdata_nsec3param_like_unittest.cc b/src/lib/dns/tests/rdata_nsec3param_like_unittest.cc
index 30110df..51fef01 100644
--- a/src/lib/dns/tests/rdata_nsec3param_like_unittest.cc
+++ b/src/lib/dns/tests/rdata_nsec3param_like_unittest.cc
@@ -40,7 +40,7 @@ protected:
NSEC3PARAMLikeTest() :
salt_txt("1 1 1 D399EAAB" + getCommonText()),
nosalt_txt("1 1 1 -" + getCommonText()),
- obuffer(0), renderer(obuffer)
+ obuffer(0)
{}
RDATA_TYPE fromText(const string& rdata_text) {
diff --git a/src/lib/dns/tests/rdata_nsec3param_unittest.cc b/src/lib/dns/tests/rdata_nsec3param_unittest.cc
index 90313d0..7558b42 100644
--- a/src/lib/dns/tests/rdata_nsec3param_unittest.cc
+++ b/src/lib/dns/tests/rdata_nsec3param_unittest.cc
@@ -94,8 +94,8 @@ TEST_F(Rdata_NSEC3PARAM_Test, toWireRenderer) {
vector<unsigned char> data;
UnitTestUtil::readWireData("rdata_nsec3param_fromWire1", data);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- static_cast<const uint8_t *>(obuffer.getData()) + 2,
- obuffer.getLength() - 2, &data[2], data.size() - 2);
+ static_cast<const uint8_t *>(renderer.getData()) + 2,
+ renderer.getLength() - 2, &data[2], data.size() - 2);
}
TEST_F(Rdata_NSEC3PARAM_Test, toWireBuffer) {
diff --git a/src/lib/dns/tests/rdata_nsec_unittest.cc b/src/lib/dns/tests/rdata_nsec_unittest.cc
index feb70c2..88c6201 100644
--- a/src/lib/dns/tests/rdata_nsec_unittest.cc
+++ b/src/lib/dns/tests/rdata_nsec_unittest.cc
@@ -74,8 +74,8 @@ TEST_F(Rdata_NSEC_Test, toWireRenderer_NSEC) {
vector<unsigned char> data;
UnitTestUtil::readWireData("rdata_nsec_fromWire1", data);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- static_cast<const uint8_t *>(obuffer.getData()) + 2,
- obuffer.getLength() - 2, &data[2], data.size() - 2);
+ static_cast<const uint8_t *>(renderer.getData()) + 2,
+ renderer.getLength() - 2, &data[2], data.size() - 2);
}
TEST_F(Rdata_NSEC_Test, toWireBuffer_NSEC) {
diff --git a/src/lib/dns/tests/rdata_nsecbitmap_unittest.cc b/src/lib/dns/tests/rdata_nsecbitmap_unittest.cc
index 426a69e..d7bce96 100644
--- a/src/lib/dns/tests/rdata_nsecbitmap_unittest.cc
+++ b/src/lib/dns/tests/rdata_nsecbitmap_unittest.cc
@@ -264,7 +264,7 @@ TEST_F(NSEC3BitmapTest, emptyMap) {
// Same for MessageRenderer.
obuffer.clear();
- MessageRenderer renderer(obuffer);
+ MessageRenderer renderer;
renderer.writeUint16(rdlen);
empty_nsec3.toWire(renderer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
diff --git a/src/lib/dns/tests/rdata_ptr_unittest.cc b/src/lib/dns/tests/rdata_ptr_unittest.cc
index 7f5de20..86160fb 100644
--- a/src/lib/dns/tests/rdata_ptr_unittest.cc
+++ b/src/lib/dns/tests/rdata_ptr_unittest.cc
@@ -100,11 +100,11 @@ TEST_F(Rdata_PTR_Test, toWireBuffer) {
TEST_F(Rdata_PTR_Test, toWireRenderer) {
rdata_ptr.toWire(renderer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
+ renderer.getData(), renderer.getLength(),
wiredata_ptr, sizeof(wiredata_ptr));
rdata_ptr2.toWire(renderer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
+ renderer.getData(), renderer.getLength(),
wiredata_ptr2, sizeof(wiredata_ptr2));
}
diff --git a/src/lib/dns/tests/rdata_rp_unittest.cc b/src/lib/dns/tests/rdata_rp_unittest.cc
index 07f5a93..20f32b9 100644
--- a/src/lib/dns/tests/rdata_rp_unittest.cc
+++ b/src/lib/dns/tests/rdata_rp_unittest.cc
@@ -38,7 +38,7 @@ protected:
// this also serves as a test for "from text" constructor in a normal
// case.
rdata_rp("root.example.com. rp-text.example.com."),
- obuffer(0), renderer(obuffer)
+ obuffer(0)
{}
const Name mailbox_name, text_name;
diff --git a/src/lib/dns/tests/rdata_soa_unittest.cc b/src/lib/dns/tests/rdata_soa_unittest.cc
index 07c24d5..a9d782c 100644
--- a/src/lib/dns/tests/rdata_soa_unittest.cc
+++ b/src/lib/dns/tests/rdata_soa_unittest.cc
@@ -56,8 +56,8 @@ TEST_F(Rdata_SOA_Test, toWireRenderer) {
vector<unsigned char> data;
UnitTestUtil::readWireData("rdata_soa_fromWire", data);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- static_cast<const uint8_t *>(obuffer.getData()) + 2,
- obuffer.getLength() - 2, &data[2], data.size() - 2);
+ static_cast<const uint8_t *>(renderer.getData()) + 2,
+ renderer.getLength() - 2, &data[2], data.size() - 2);
}
TEST_F(Rdata_SOA_Test, toWireBuffer) {
diff --git a/src/lib/dns/tests/rdata_srv_unittest.cc b/src/lib/dns/tests/rdata_srv_unittest.cc
index 3394f43..b194b1c 100644
--- a/src/lib/dns/tests/rdata_srv_unittest.cc
+++ b/src/lib/dns/tests/rdata_srv_unittest.cc
@@ -134,12 +134,12 @@ TEST_F(Rdata_SRV_Test, toWireBuffer) {
TEST_F(Rdata_SRV_Test, toWireRenderer) {
rdata_srv.toWire(renderer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
+ renderer.getData(), renderer.getLength(),
wiredata_srv, sizeof(wiredata_srv));
renderer.clear();
rdata_srv2.toWire(renderer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
+ renderer.getData(), renderer.getLength(),
wiredata_srv2, sizeof(wiredata_srv2));
}
diff --git a/src/lib/dns/tests/rdata_unittest.cc b/src/lib/dns/tests/rdata_unittest.cc
index fa791dc..5be06e8 100644
--- a/src/lib/dns/tests/rdata_unittest.cc
+++ b/src/lib/dns/tests/rdata_unittest.cc
@@ -38,8 +38,7 @@ namespace isc {
namespace dns {
namespace rdata {
RdataTest::RdataTest() :
- obuffer(0), renderer(obuffer),
- rdata_nomatch(createRdata(RRType(0), RRClass(1), "\\# 0"))
+ obuffer(0), rdata_nomatch(createRdata(RRType(0), RRClass(1), "\\# 0"))
{}
RdataPtr
@@ -245,7 +244,7 @@ TEST_F(Rdata_Unknown_Test, toWireBuffer) {
TEST_F(Rdata_Unknown_Test, toWireRenderer) {
rdata_unknown.toWire(renderer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
+ renderer.getData(), renderer.getLength(),
wiredata_unknown, sizeof(wiredata_unknown));
}
diff --git a/src/lib/dns/tests/rdatafields_unittest.cc b/src/lib/dns/tests/rdatafields_unittest.cc
index d619220..ef83ed4 100644
--- a/src/lib/dns/tests/rdatafields_unittest.cc
+++ b/src/lib/dns/tests/rdatafields_unittest.cc
@@ -36,9 +36,7 @@ using isc::util::InputBuffer;
namespace {
class RdataFieldsTest : public ::testing::Test {
protected:
- RdataFieldsTest() : obuffer(0), renderer_buffer(0),
- renderer(renderer_buffer),
- ns_name("example.com"),
+ RdataFieldsTest() : obuffer(0), ns_name("example.com"),
other_name("www.example.com")
{}
void constructCommonTests(const RdataFields& fields,
@@ -49,7 +47,6 @@ protected:
void constructCommonTestsRRSIG(const RdataFields& fields);
void constructCommonTestsOPT(const RdataFields& fields);
OutputBuffer obuffer;
- OutputBuffer renderer_buffer;
MessageRenderer renderer;
const Name ns_name;
const Name other_name;
diff --git a/src/lib/dns/tests/rrclass_unittest.cc b/src/lib/dns/tests/rrclass_unittest.cc
index 15f9a8c..6156be5 100644
--- a/src/lib/dns/tests/rrclass_unittest.cc
+++ b/src/lib/dns/tests/rrclass_unittest.cc
@@ -28,7 +28,7 @@ using namespace isc::util;
namespace {
class RRClassTest : public ::testing::Test {
protected:
- RRClassTest() : obuffer(0), renderer(obuffer) {}
+ RRClassTest() : obuffer(0) {}
OutputBuffer obuffer;
MessageRenderer renderer;
@@ -116,7 +116,7 @@ TEST_F(RRClassTest, toWireRenderer) {
rrclass_max.toWire(renderer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
+ renderer.getData(), renderer.getLength(),
wiredata, sizeof(wiredata));
}
diff --git a/src/lib/dns/tests/rrset_unittest.cc b/src/lib/dns/tests/rrset_unittest.cc
index f951341..a6bfe56 100644
--- a/src/lib/dns/tests/rrset_unittest.cc
+++ b/src/lib/dns/tests/rrset_unittest.cc
@@ -38,7 +38,7 @@ using namespace isc::dns::rdata;
namespace {
class RRsetTest : public ::testing::Test {
protected:
- RRsetTest() : buffer(0), renderer(buffer),
+ RRsetTest() : buffer(0),
test_name("test.example.com"),
test_domain("example.com"),
test_nsname("ns.example.com"),
@@ -201,8 +201,8 @@ TEST_F(RRsetTest, toWireRenderer) {
rrset_ns.toWire(renderer);
UnitTestUtil::readWireData("rrset_toWire2", wiredata);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer.getData(),
- buffer.getLength(), &wiredata[0], wiredata.size());
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
+ renderer.getLength(), &wiredata[0], wiredata.size());
// toWire() cannot be performed for an empty RRset.
renderer.clear();
diff --git a/src/lib/dns/tests/rrttl_unittest.cc b/src/lib/dns/tests/rrttl_unittest.cc
index fe75eb6..703616c 100644
--- a/src/lib/dns/tests/rrttl_unittest.cc
+++ b/src/lib/dns/tests/rrttl_unittest.cc
@@ -28,7 +28,7 @@ using namespace isc::util;
namespace {
class RRTTLTest : public ::testing::Test {
protected:
- RRTTLTest() : obuffer(0), renderer(obuffer) {}
+ RRTTLTest() : obuffer(0) {}
OutputBuffer obuffer;
MessageRenderer renderer;
@@ -114,7 +114,7 @@ TEST_F(RRTTLTest, toWireRenderer) {
ttl_max.toWire(renderer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
+ renderer.getData(), renderer.getLength(),
wiredata, sizeof(wiredata));
}
@@ -138,7 +138,7 @@ TEST_F(RRTTLTest, leq) {
// small <= small is true
EXPECT_TRUE(ttl_small.leq(ttl_small));
- EXPECT_TRUE(ttl_small <= ttl_small);
+ EXPECT_LE(ttl_small, ttl_small);
// large <= small is false
EXPECT_FALSE(ttl_large.leq(ttl_small));
@@ -150,7 +150,7 @@ TEST_F(RRTTLTest, geq) {
EXPECT_TRUE(ttl_large >= ttl_small);
EXPECT_TRUE(ttl_large.geq(ttl_large));
- EXPECT_TRUE(ttl_large >= ttl_large);
+ EXPECT_GE(ttl_large, ttl_large);
EXPECT_FALSE(ttl_small.geq(ttl_large));
EXPECT_FALSE(ttl_small >= ttl_large);
diff --git a/src/lib/dns/tests/rrtype_unittest.cc b/src/lib/dns/tests/rrtype_unittest.cc
index 12f6001..28ecee6 100644
--- a/src/lib/dns/tests/rrtype_unittest.cc
+++ b/src/lib/dns/tests/rrtype_unittest.cc
@@ -28,7 +28,7 @@ using namespace isc::util;
namespace {
class RRTypeTest : public ::testing::Test {
protected:
- RRTypeTest() : obuffer(0), renderer(obuffer) {}
+ RRTypeTest() : obuffer(0) {}
OutputBuffer obuffer;
MessageRenderer renderer;
@@ -120,7 +120,7 @@ TEST_F(RRTypeTest, toWireRenderer) {
rrtype_max.toWire(renderer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
+ renderer.getData(), renderer.getLength(),
wiredata, sizeof(wiredata));
}
diff --git a/src/lib/dns/tests/tsig_unittest.cc b/src/lib/dns/tests/tsig_unittest.cc
index 7944b29..ac503e5 100644
--- a/src/lib/dns/tests/tsig_unittest.cc
+++ b/src/lib/dns/tests/tsig_unittest.cc
@@ -71,7 +71,7 @@ protected:
TSIGTest() :
tsig_ctx(NULL), qid(0x2d65), test_name("www.example.com"),
badkey_name("badkey.example.com"), test_class(RRClass::IN()),
- test_ttl(86400), message(Message::RENDER), buffer(0), renderer(buffer),
+ test_ttl(86400), message(Message::RENDER),
dummy_data(1024, 0xdd), // should be sufficiently large for all tests
dummy_record(badkey_name, any::TSIG(TSIGKey::HMACMD5_NAME(),
0x4da8877a,
@@ -125,7 +125,6 @@ protected:
const RRClass test_class;
const RRTTL test_ttl;
Message message;
- OutputBuffer buffer;
MessageRenderer renderer;
vector<uint8_t> secret;
vector<uint8_t> dummy_data;
diff --git a/src/lib/dns/tests/tsigrecord_unittest.cc b/src/lib/dns/tests/tsigrecord_unittest.cc
index e1b3e93..532681a 100644
--- a/src/lib/dns/tests/tsigrecord_unittest.cc
+++ b/src/lib/dns/tests/tsigrecord_unittest.cc
@@ -46,7 +46,7 @@ protected:
test_mac.size(), &test_mac[0],
0x2d65, 0, 0, NULL)),
test_record(test_name, test_rdata),
- buffer(0), renderer(buffer)
+ buffer(0)
{}
const Name test_name;
vector<unsigned char> test_mac;
diff --git a/src/lib/nsas/glue_hints.cc b/src/lib/nsas/glue_hints.cc
index 02c27ee..3caae25 100644
--- a/src/lib/nsas/glue_hints.cc
+++ b/src/lib/nsas/glue_hints.cc
@@ -86,8 +86,8 @@ GlueHints::GlueHints(const std::string& zone_name,
bool
GlueHints::hasGlue(AddressFamily family) const {
- return ((addresses_v4.size() > 0 && (family == ANY_OK || family == V4_ONLY)) ||
- (addresses_v6.size() > 0 && (family == ANY_OK || family == V6_ONLY)));
+ return ((!addresses_v4.empty() && (family == ANY_OK || family == V4_ONLY)) ||
+ (!addresses_v6.empty() && (family == ANY_OK || family == V6_ONLY)));
}
NameserverAddress
diff --git a/src/lib/nsas/hash_table.h b/src/lib/nsas/hash_table.h
index c028fa4..6028473 100644
--- a/src/lib/nsas/hash_table.h
+++ b/src/lib/nsas/hash_table.h
@@ -59,7 +59,7 @@ struct HashTableSlot {
/// \brief Copy Constructor
///
/// ... which as noted in the class description does not copy.
- HashTableSlot(const HashTableSlot<T>&)
+ HashTableSlot(const HashTableSlot<T>&) : mutex_(), list_()
{ }
public:
diff --git a/src/lib/nsas/tests/nameserver_entry_unittest.cc b/src/lib/nsas/tests/nameserver_entry_unittest.cc
index 3435d26..3aca08f 100644
--- a/src/lib/nsas/tests/nameserver_entry_unittest.cc
+++ b/src/lib/nsas/tests/nameserver_entry_unittest.cc
@@ -139,7 +139,7 @@ TEST_F(NameserverEntryTest, SetRTT) {
NameserverEntry::AddressVector vec;
alpha->getAddresses(vec);
- ASSERT_TRUE(vec.size() > 0);
+ ASSERT_FALSE(vec.empty());
// Take the first address and change the RTT.
IOAddress first_address = vec[0].getAddress();
@@ -174,7 +174,7 @@ TEST_F(NameserverEntryTest, Unreachable) {
NameserverEntry::AddressVector vec;
alpha->getAddresses(vec);
- ASSERT_TRUE(vec.size() > 0);
+ ASSERT_FALSE(vec.empty());
// Take the first address and mark as unreachable.
IOAddress first_address = vec[0].getAddress();
diff --git a/src/lib/nsas/zone_entry.cc b/src/lib/nsas/zone_entry.cc
index 1c5df03..8a72e5f 100644
--- a/src/lib/nsas/zone_entry.cc
+++ b/src/lib/nsas/zone_entry.cc
@@ -329,7 +329,7 @@ updateAddressSelector(std::vector<NameserverAddress>& addresses,
it != probabilities.end(); ++it){
(*it) /= sum;
}
- } else if(probabilities.size() > 0){
+ } else if(!probabilities.empty()){
// If all the nameservers are unreachable, the sum will be 0
// So give each server equal opportunity to be selected.
for(vector<double>::iterator it = probabilities.begin();
diff --git a/src/lib/python/isc/Makefile.am b/src/lib/python/isc/Makefile.am
index a3e74c5..aef5dc3 100644
--- a/src/lib/python/isc/Makefile.am
+++ b/src/lib/python/isc/Makefile.am
@@ -1,5 +1,5 @@
SUBDIRS = datasrc cc config dns log net notify util testutils acl bind10
-SUBDIRS += xfrin log_messages
+SUBDIRS += xfrin log_messages server_common
python_PYTHON = __init__.py
diff --git a/src/lib/python/isc/config/ccsession.py b/src/lib/python/isc/config/ccsession.py
index b505399..703d196 100644
--- a/src/lib/python/isc/config/ccsession.py
+++ b/src/lib/python/isc/config/ccsession.py
@@ -38,6 +38,7 @@
from isc.cc import Session
from isc.config.config_data import ConfigData, MultiConfigData, BIND10_CONFIG_DATA_VERSION
+import isc.config.module_spec
import isc
from isc.util.file import path_search
import bind10_config
@@ -327,43 +328,97 @@ class ModuleCCSession(ConfigData):
and return an answer created with create_answer()"""
self._command_handler = command_handler
- def add_remote_config(self, spec_file_name, config_update_callback = None):
- """Gives access to the configuration of a different module.
- These remote module options can at this moment only be
- accessed through get_remote_config_value(). This function
- 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)
+ def _add_remote_config_internal(self, module_spec,
+ config_update_callback=None):
+ """The guts of add_remote_config and add_remote_config_by_name"""
module_cfg = ConfigData(module_spec)
module_name = module_spec.get_module_name()
+
self._session.group_subscribe(module_name)
# Get the current config for that module now
seq = self._session.group_sendmsg(create_command(COMMAND_GET_CONFIG, { "module_name": module_name }), "ConfigManager")
try:
- answer, env = self._session.group_recvmsg(False, seq)
+ answer, _ = self._session.group_recvmsg(False, seq)
except isc.cc.SessionTimeout:
raise ModuleCCSessionError("No answer from ConfigManager when "
"asking about Remote module " +
module_name)
+ call_callback = False
if answer:
rcode, value = parse_answer(answer)
if rcode == 0:
- if value != None and module_spec.validate_config(False, value):
- module_cfg.set_local_config(value)
- if config_update_callback is not None:
- config_update_callback(value, module_cfg)
+ if value != None:
+ if module_spec.validate_config(False, value):
+ module_cfg.set_local_config(value)
+ call_callback = True
+ else:
+ raise ModuleCCSessionError("Bad config data for " +
+ module_name + ": " +
+ str(value))
+ else:
+ raise ModuleCCSessionError("Failure requesting remote " +
+ "configuration data for " +
+ module_name)
# all done, add it
self._remote_module_configs[module_name] = module_cfg
self._remote_module_callbacks[module_name] = config_update_callback
+ if call_callback and config_update_callback is not None:
+ config_update_callback(value, module_cfg)
+
+ def add_remote_config_by_name(self, module_name,
+ config_update_callback=None):
+ """
+ This does the same as add_remote_config, but you provide the module name
+ instead of the name of the spec file.
+ """
+ seq = self._session.group_sendmsg(create_command(COMMAND_GET_MODULE_SPEC,
+ { "module_name":
+ module_name }),
+ "ConfigManager")
+ try:
+ answer, env = self._session.group_recvmsg(False, seq)
+ except isc.cc.SessionTimeout:
+ raise ModuleCCSessionError("No answer from ConfigManager when " +
+ "asking about for spec of Remote " +
+ "module " + module_name)
+ if answer:
+ rcode, value = parse_answer(answer)
+ if rcode == 0:
+ module_spec = isc.config.module_spec.ModuleSpec(value)
+ if module_spec.get_module_name() != module_name:
+ raise ModuleCCSessionError("Module name mismatch: " +
+ module_name + " and " +
+ module_spec.get_module_name())
+ self._add_remote_config_internal(module_spec,
+ config_update_callback)
+ else:
+ raise ModuleCCSessionError("Error code " + str(rcode) +
+ "when asking for module spec of " +
+ module_name)
+ else:
+ raise ModuleCCSessionError("No answer when asking for module " +
+ "spec of " + module_name)
+ # Just to be consistent with the add_remote_config
return module_name
-
+
+ def add_remote_config(self, spec_file_name, config_update_callback=None):
+ """Gives access to the configuration of a different module.
+ These remote module options can at this moment only be
+ accessed through get_remote_config_value(). This function
+ 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, but you can
+ specify a callback that is called after the change happened.
+ 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)
+ self._add_remote_config_internal(module_spec, config_update_callback)
+ return module_spec.get_module_name()
+
def remove_remote_config(self, module_name):
"""Removes the remote configuration access for this module"""
if module_name in self._remote_module_configs:
@@ -501,8 +556,8 @@ class UIModuleCCSession(MultiConfigData):
self.set_value(identifier, cur_map)
else:
raise isc.cc.data.DataAlreadyPresentError(value +
- " already in "
- + identifier)
+ " already in " +
+ identifier)
def add_value(self, identifier, value_str = None, set_value_str = None):
"""Add a value to a configuration list. Raises a DataTypeError
diff --git a/src/lib/python/isc/config/tests/ccsession_test.py b/src/lib/python/isc/config/tests/ccsession_test.py
index df39550..d1060bf 100644
--- a/src/lib/python/isc/config/tests/ccsession_test.py
+++ b/src/lib/python/isc/config/tests/ccsession_test.py
@@ -488,45 +488,6 @@ class TestModuleCCSession(unittest.TestCase):
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):
@@ -554,16 +515,65 @@ class TestModuleCCSession(unittest.TestCase):
mccs.set_command_handler(self.my_command_handler_ok)
self.assertRaises(WouldBlockForever, lambda: mccs.check_command(False))
- def test_remote_module(self):
+ # Now there's a group of tests testing both add_remote_config and
+ # add_remote_config_by_name. Since they are almost the same (they differ
+ # just in the parameter and that the second one asks one more question over
+ # the bus), the actual test code is shared.
+ #
+ # These three functions are helper functions to easy up the writing of them.
+ # To write a test, there need to be 3 functions. First, the function that
+ # does the actual test. It looks like:
+ # def _internal_test(self, function_lambda, param, fill_other_messages):
+ #
+ # The function_lambda provides the tested function if called on the
+ # ccsession. The param is the parameter to pass to the function (either
+ # the module name or the spec file name. The fill_other_messages fills
+ # needed messages (the answer containing the module spec in case of add by
+ # name, no messages in the case of adding by spec file) into the fake bus.
+ # So, the code would look like:
+ #
+ # * Create the fake session and tested ccsession object
+ # * function = function_lambda(ccsession object)
+ # * fill_other_messages(fake session)
+ # * Fill in answer to the get_module_config command
+ # * Test by calling function(param)
+ #
+ # Then you need two wrappers that do launch the tests. There are helpers
+ # for that, so you can just call:
+ # def test_by_spec(self)
+ # self._common_remote_module_test(self._internal_test)
+ # def test_by_name(self)
+ # self._common_remote_module_by_name_test(self._internal_test)
+ def _common_remote_module_test(self, internal_test):
+ internal_test(lambda ccs: ccs.add_remote_config,
+ self.spec_file("spec2.spec"),
+ lambda session: None)
+
+ def _prepare_spec_message(self, session, spec_name):
+ # It could have been one command, but the line would be way too long
+ # to even split it
+ spec_file = self.spec_file(spec_name)
+ spec = isc.config.module_spec_from_file(spec_file)
+ session.group_sendmsg({'result': [0, spec.get_full_spec()]}, "Spec1")
+
+ def _common_remote_module_by_name_test(self, internal_test):
+ internal_test(lambda ccs: ccs.add_remote_config_by_name, "Spec2",
+ lambda session: self._prepare_spec_message(session,
+ "spec2.spec"))
+
+ def _internal_remote_module(self, function_lambda, parameter,
+ fill_other_messages):
fake_session = FakeModuleCCSession()
mccs = self.create_session("spec1.spec", None, None, fake_session)
mccs.remove_remote_config("Spec2")
+ function = function_lambda(mccs)
self.assertRaises(ModuleCCSessionError, mccs.get_remote_config_value, "Spec2", "item1")
self.assertFalse("Spec2" in fake_session.subscriptions)
+ fill_other_messages(fake_session)
fake_session.group_sendmsg(None, 'Spec2')
- rmodname = mccs.add_remote_config(self.spec_file("spec2.spec"))
+ rmodname = function(parameter)
self.assertTrue("Spec2" in fake_session.subscriptions)
self.assertEqual("Spec2", rmodname)
self.assertRaises(isc.cc.data.DataNotFoundError, mccs.get_remote_config_value, rmodname, "asdf")
@@ -575,36 +585,77 @@ class TestModuleCCSession(unittest.TestCase):
self.assertFalse("Spec2" in fake_session.subscriptions)
self.assertRaises(ModuleCCSessionError, mccs.get_remote_config_value, "Spec2", "item1")
- # test if unsubscription is alse sent when object is deleted
+ # test if unsubscription is also sent when object is deleted
+ fill_other_messages(fake_session)
fake_session.group_sendmsg({'result' : [0]}, 'Spec2')
- rmodname = mccs.add_remote_config(self.spec_file("spec2.spec"))
+ rmodname = function(parameter)
self.assertTrue("Spec2" in fake_session.subscriptions)
mccs = None
+ function = None
self.assertFalse("Spec2" in fake_session.subscriptions)
- def test_remote_module_with_custom_config(self):
+ def test_remote_module(self):
+ """
+ Test we can add a remote config and get the configuration.
+ Remote module specified by the spec file name.
+ """
+ self._common_remote_module_test(self._internal_remote_module)
+
+ def test_remote_module_by_name(self):
+ """
+ Test we can add a remote config and get the configuration.
+ Remote module specified its name.
+ """
+ self._common_remote_module_by_name_test(self._internal_remote_module)
+
+ def _internal_remote_module_with_custom_config(self, function_lambda,
+ parameter,
+ fill_other_messages):
fake_session = FakeModuleCCSession()
mccs = self.create_session("spec1.spec", None, None, fake_session)
- # override the default config value for "item1". add_remote_config()
- # should incorporate the overridden value, and we should be abel to
+ function = function_lambda(mccs)
+ # override the default config value for "item1". add_remote_config[_by_name]()
+ # should incorporate the overridden value, and we should be able to
# get it via get_remote_config_value().
+ fill_other_messages(fake_session)
fake_session.group_sendmsg({'result': [0, {"item1": 10}]}, 'Spec2')
- rmodname = mccs.add_remote_config(self.spec_file("spec2.spec"))
+ rmodname = function(parameter)
value, default = mccs.get_remote_config_value(rmodname, "item1")
self.assertEqual(10, value)
self.assertEqual(False, default)
- def test_ignore_command_remote_module(self):
+ def test_remote_module_with_custom_config(self):
+ """
+ Test the config of module will load non-default values on
+ initialization.
+ Remote module specified by the spec file name.
+ """
+ self._common_remote_module_test(
+ self._internal_remote_module_with_custom_config)
+
+ def test_remote_module_by_name_with_custom_config(self):
+ """
+ Test the config of module will load non-default values on
+ initialization.
+ Remote module its name.
+ """
+ self._common_remote_module_by_name_test(
+ self._internal_remote_module_with_custom_config)
+
+ def _internal_ignore_command_remote_module(self, function_lambda, param,
+ fill_other_messages):
# Create a Spec1 module and subscribe to remote config for Spec2
fake_session = FakeModuleCCSession()
mccs = self.create_session("spec1.spec", None, None, fake_session)
mccs.set_command_handler(self.my_command_handler_ok)
+ function = function_lambda(mccs)
+ fill_other_messages(fake_session)
fake_session.group_sendmsg(None, 'Spec2')
- rmodname = mccs.add_remote_config(self.spec_file("spec2.spec"))
+ rmodname = function(param)
- # remove the 'get config' from the queue
- self.assertEqual(len(fake_session.message_queue), 1)
- fake_session.get_message("ConfigManager")
+ # remove the commands from queue
+ while len(fake_session.message_queue) > 0:
+ fake_session.get_message("ConfigManager")
# check if the command for the module itself is received
cmd = isc.config.ccsession.create_command("just_some_command", { 'foo': 'a' })
@@ -622,6 +673,174 @@ class TestModuleCCSession(unittest.TestCase):
mccs.check_command()
self.assertEqual(len(fake_session.message_queue), 0)
+ def test_ignore_commant_remote_module(self):
+ """
+ Test that commands for remote modules aren't handled.
+ Remote module specified by the spec file name.
+ """
+ self._common_remote_module_test(
+ self._internal_ignore_command_remote_module)
+
+ def test_ignore_commant_remote_module_by_name(self):
+ """
+ Test that commands for remote modules aren't handled.
+ Remote module specified by its name.
+ """
+ self._common_remote_module_by_name_test(
+ self._internal_ignore_command_remote_module)
+
+ def _internal_check_command_without_recvmsg_remote_module(self,
+ function_lambda,
+ param,
+ fill_other_messages):
+ fake_session = FakeModuleCCSession()
+ mccs = self.create_session("spec1.spec", None, None, fake_session)
+ mccs.set_config_handler(self.my_config_handler_ok)
+ function = function_lambda(mccs)
+ self.assertEqual(len(fake_session.message_queue), 0)
+
+ fill_other_messages(fake_session)
+ fake_session.group_sendmsg(None, 'Spec2')
+ rmodname = function(param)
+ if (len(fake_session.message_queue) == 2):
+ self.assertEqual({'command': ['get_module_spec',
+ {'module_name': 'Spec2'}]},
+ fake_session.get_message('ConfigManager', None))
+ 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_module(self):
+ """
+ Test updates on remote module.
+ The remote module is specified by the spec file name.
+ """
+ self._common_remote_module_test(
+ self._internal_check_command_without_recvmsg_remote_module)
+
+ def test_check_command_without_recvmsg_remote_module_by_name(self):
+ """
+ Test updates on remote module.
+ The remote module is specified by its name.
+ """
+ self._common_remote_module_by_name_test(
+ self._internal_check_command_without_recvmsg_remote_module)
+
+ def _internal_check_command_without_recvmsg_remote_module2(self,
+ function_lambda,
+ param,
+ fill_other_messages):
+ fake_session = FakeModuleCCSession()
+ mccs = self.create_session("spec1.spec", None, None, fake_session)
+ mccs.set_config_handler(self.my_config_handler_ok)
+ function = function_lambda(mccs)
+ self.assertEqual(len(fake_session.message_queue), 0)
+
+ fill_other_messages(fake_session)
+ fake_session.group_sendmsg(None, 'Spec2')
+ rmodname = function(param)
+ if (len(fake_session.message_queue) == 2):
+ self.assertEqual({'command': ['get_module_spec',
+ {'module_name': 'Spec2'}]},
+ fake_session.get_message('ConfigManager', None))
+ 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_without_recvmsg_remote_module2(self):
+ """
+ Test updates on remote module.
+ The remote module is specified by the spec file name.
+ """
+ self._common_remote_module_test(
+ self._internal_check_command_without_recvmsg_remote_module2)
+
+ def test_check_command_without_recvmsg_remote_module_by_name2(self):
+ """
+ Test updates on remote module.
+ The remote module is specified by its name.
+ """
+ self._common_remote_module_by_name_test(
+ self._internal_check_command_without_recvmsg_remote_module2)
+
+ def _internal_remote_module_bad_config(self, function_lambda, parameter,
+ fill_other_messages):
+ fake_session = FakeModuleCCSession()
+ mccs = self.create_session("spec1.spec", None, None, fake_session)
+ function = function_lambda(mccs)
+ # Provide wrong config data. It should be rejected.
+ fill_other_messages(fake_session)
+ fake_session.group_sendmsg({'result': [0, {"bad_item": -1}]}, 'Spec2')
+ self.assertRaises(isc.config.ModuleCCSessionError,
+ function, parameter)
+
+ def test_remote_module_bad_config(self):
+ """
+ Test the remote module rejects bad config data.
+ """
+ self._common_remote_module_test(
+ self._internal_remote_module_bad_config)
+
+ def test_remote_module_by_name_bad_config(self):
+ """
+ Test the remote module rejects bad config data.
+ """
+ self._common_remote_module_by_name_test(
+ self._internal_remote_module_bad_config)
+
+ def _internal_remote_module_error_response(self, function_lambda,
+ parameter, fill_other_messages):
+ fake_session = FakeModuleCCSession()
+ mccs = self.create_session("spec1.spec", None, None, fake_session)
+ function = function_lambda(mccs)
+ # Provide wrong config data. It should be rejected.
+ fill_other_messages(fake_session)
+ fake_session.group_sendmsg({'result': [1, "An error, and I mean it!"]},
+ 'Spec2')
+ self.assertRaises(isc.config.ModuleCCSessionError,
+ function, parameter)
+
+ def test_remote_module_bad_config(self):
+ """
+ Test the remote module complains if there's an error response."
+ """
+ self._common_remote_module_test(
+ self._internal_remote_module_error_response)
+
+ def test_remote_module_by_name_bad_config(self):
+ """
+ Test the remote module complains if there's an error response."
+ """
+ self._common_remote_module_by_name_test(
+ self._internal_remote_module_error_response)
+
+ def test_remote_module_bad_config(self):
+ """
+ Test the remote module rejects bad config data.
+ """
+ self._common_remote_module_by_name_test(
+ self._internal_remote_module_bad_config)
+
+ def test_module_name_mismatch(self):
+ fake_session = FakeModuleCCSession()
+ mccs = self.create_session("spec1.spec", None, None, fake_session)
+ mccs.set_config_handler(self.my_config_handler_ok)
+ self._prepare_spec_message(fake_session, 'spec1.spec')
+ self.assertRaises(isc.config.ModuleCCSessionError,
+ mccs.add_remote_config_by_name, "Spec2")
+
def test_logconfig_handler(self):
# test whether default_logconfig_handler reacts nicely to
# bad data. We assume the actual logger output is tested
diff --git a/src/lib/python/isc/log/Makefile.am b/src/lib/python/isc/log/Makefile.am
index 5ff2c28..b228caf 100644
--- a/src/lib/python/isc/log/Makefile.am
+++ b/src/lib/python/isc/log/Makefile.am
@@ -23,15 +23,6 @@ log_la_LIBADD += $(PYTHON_LIB)
# This is not installed, it helps locate the module during tests
EXTRA_DIST = __init__.py
-# We're going to abuse install-data-local for a pre-install check.
-# This is to be considered a short term hack and is expected to be removed
-# in a near future version.
-install-data-local:
- if test -d @pyexecdir@/isc/log; then \
- echo "@pyexecdir@/isc/log is deprecated, and will confuse newer versions. Please (re)move it by hand."; \
- exit 1; \
- fi
-
pytest:
$(SHELL) tests/log_test
diff --git a/src/lib/python/isc/log_messages/Makefile.am b/src/lib/python/isc/log_messages/Makefile.am
index 4b084cc..4b7e1d1 100644
--- a/src/lib/python/isc/log_messages/Makefile.am
+++ b/src/lib/python/isc/log_messages/Makefile.am
@@ -13,6 +13,7 @@ EXTRA_DIST += cfgmgr_messages.py
EXTRA_DIST += config_messages.py
EXTRA_DIST += notify_out_messages.py
EXTRA_DIST += libxfrin_messages.py
+EXTRA_DIST += server_common_messages.py
CLEANFILES = __init__.pyc
CLEANFILES += bind10_messages.pyc
@@ -27,6 +28,7 @@ CLEANFILES += cfgmgr_messages.pyc
CLEANFILES += config_messages.pyc
CLEANFILES += notify_out_messages.pyc
CLEANFILES += libxfrin_messages.pyc
+CLEANFILES += server_common_messages.pyc
CLEANDIRS = __pycache__
diff --git a/src/lib/python/isc/log_messages/server_common_messages.py b/src/lib/python/isc/log_messages/server_common_messages.py
new file mode 100644
index 0000000..a491071
--- /dev/null
+++ b/src/lib/python/isc/log_messages/server_common_messages.py
@@ -0,0 +1 @@
+from work.server_common_messages import *
diff --git a/src/lib/python/isc/server_common/Makefile.am b/src/lib/python/isc/server_common/Makefile.am
new file mode 100644
index 0000000..a9eca2e
--- /dev/null
+++ b/src/lib/python/isc/server_common/Makefile.am
@@ -0,0 +1,24 @@
+SUBDIRS = tests
+
+python_PYTHON = __init__.py tsig_keyring.py
+
+pythondir = $(pyexecdir)/isc/server_common
+
+BUILT_SOURCES = $(PYTHON_LOGMSGPKG_DIR)/work/server_common_messages.py
+nodist_pylogmessage_PYTHON = $(PYTHON_LOGMSGPKG_DIR)/work/server_common_messages.py
+
+pylogmessagedir = $(pyexecdir)/isc/log_messages/
+
+CLEANFILES = $(PYTHON_LOGMSGPKG_DIR)/work/server_common_messages.py
+CLEANFILES += $(PYTHON_LOGMSGPKG_DIR)/work/server_common_messages.pyc
+
+CLEANDIRS = __pycache__
+
+EXTRA_DIST = server_common_messages.mes
+
+$(PYTHON_LOGMSGPKG_DIR)/work/server_common_messages.py : server_common_messages.mes
+ $(top_builddir)/src/lib/log/compiler/message \
+ -d $(PYTHON_LOGMSGPKG_DIR)/work -p $(srcdir)/server_common_messages.mes
+
+clean-local:
+ rm -rf $(CLEANDIRS)
diff --git a/src/lib/python/isc/server_common/__init__.py b/src/lib/python/isc/server_common/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/src/lib/python/isc/server_common/server_common_messages.mes b/src/lib/python/isc/server_common/server_common_messages.mes
new file mode 100644
index 0000000..b32205c
--- /dev/null
+++ b/src/lib/python/isc/server_common/server_common_messages.mes
@@ -0,0 +1,36 @@
+# Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# No namespace declaration - these constants go in the global namespace
+# of the config_messages python module.
+
+# since these messages are for the python server_common library, care must
+# be taken that names do not conflict with the messages from the c++
+# server_common library. A checker script should verify that, but we do not
+# have that at this moment. So when adding a message, make sure that
+# the name is not already used in src/lib/config/config_messages.mes
+
+% PYSERVER_COMMON_TSIG_KEYRING_DEINIT Deinitializing global TSIG keyring
+A debug message noting that the global TSIG keyring is being removed from
+memory. Most programs don't do that, they just exit, which is OK.
+
+% PYSERVER_COMMON_TSIG_KEYRING_INIT Initializing global TSIG keyring
+A debug message noting the TSIG keyring storage is being prepared. It should
+appear at most once in the lifetime of a program. The keyring still needs
+to be loaded from configuration.
+
+% PYSERVER_COMMON_TSIG_KEYRING_UPDATE Updating global TSIG keyring
+A debug message. The TSIG keyring is being (re)loaded from configuration.
+This happens at startup or when the configuration changes. The old keyring
+is removed and new one created with all the keys.
diff --git a/src/lib/python/isc/server_common/tests/Makefile.am b/src/lib/python/isc/server_common/tests/Makefile.am
new file mode 100644
index 0000000..4829edc
--- /dev/null
+++ b/src/lib/python/isc/server_common/tests/Makefile.am
@@ -0,0 +1,24 @@
+PYCOVERAGE_RUN = @PYCOVERAGE_RUN@
+PYTESTS = tsig_keyring_test.py
+EXTRA_DIST = $(PYTESTS)
+
+# If necessary (rare cases), explicitly specify paths to dynamic libraries
+# required by loadable python modules.
+LIBRARY_PATH_PLACEHOLDER =
+if SET_ENV_LIBRARY_PATH
+LIBRARY_PATH_PLACEHOLDER += $(ENV_LIBRARY_PATH)=$(abs_top_builddir)/src/lib/cryptolink/.libs:$(abs_top_builddir)/src/lib/dns/.libs:$(abs_top_builddir)/src/lib/dns/python/.libs:$(abs_top_builddir)/src/lib/cc/.libs:$(abs_top_builddir)/src/lib/config/.libs:$(abs_top_builddir)/src/lib/log/.libs:$(abs_top_builddir)/src/lib/util/.libs:$(abs_top_builddir)/src/lib/exceptions/.libs:$(abs_top_builddir)/src/lib/datasrc/.libs:$$$(ENV_LIBRARY_PATH)
+endif
+
+# test using command-line arguments, so use check-local target instead of TESTS
+check-local:
+if ENABLE_PYTHON_COVERAGE
+ touch $(abs_top_srcdir)/.coverage
+ rm -f .coverage
+ ${LN_S} $(abs_top_srcdir)/.coverage .coverage
+endif
+ for pytest in $(PYTESTS) ; do \
+ echo Running test: $$pytest ; \
+ $(LIBRARY_PATH_PLACEHOLDER) \
+ PYTHONPATH=$(COMMON_PYTHON_PATH):$(abs_top_builddir)/src/lib/dns/python/.libs \
+ $(PYCOVERAGE_RUN) $(abs_srcdir)/$$pytest || exit ; \
+ done
diff --git a/src/lib/python/isc/server_common/tests/tsig_keyring_test.py b/src/lib/python/isc/server_common/tests/tsig_keyring_test.py
new file mode 100644
index 0000000..e9a2174
--- /dev/null
+++ b/src/lib/python/isc/server_common/tests/tsig_keyring_test.py
@@ -0,0 +1,193 @@
+# Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""
+Tests for isc.server_common.tsig_keyring.
+"""
+
+import unittest
+import isc.log
+from isc.server_common.tsig_keyring import *
+import isc.dns
+from isc.testutils.ccsession_mock import MockModuleCCSession
+
+class Session(MockModuleCCSession):
+ """
+ A class pretending to be the config session.
+ """
+ def __init__(self):
+ MockModuleCCSession.__init__(self)
+ self._name = None
+ self._callback = None
+ self._remove_name = None
+ self._data = None
+
+ def add_remote_config_by_name(self, name, callback):
+ self._name = name
+ self._callback = callback
+
+ def remove_remote_config(self, name):
+ self._remove_name = name
+
+ def get_remote_config_value(self, module, name):
+ if module != 'tsig_keys' or name != 'keys':
+ raise Exception("Asked for bad data element")
+ return (self._data, False)
+
+class TSIGKeyRingTest(unittest.TestCase):
+ """
+ Tests for the isc.server_common.tsig_keyring module.
+ """
+ def setUp(self):
+ self.__session = Session()
+ self.__sha1name = isc.dns.Name('hmac-sha1')
+ self.__md5name = isc.dns.Name('hmac-md5.sig-alg.reg.int')
+
+ def tearDown(self):
+ deinit_keyring()
+
+ def __do_init(self):
+ init_keyring(self.__session)
+ # Some initialization happened
+ self.assertEqual('tsig_keys', self.__session._name)
+
+ def test_initialization(self):
+ """
+ Test we can initialize and deintialize the keyring. It also
+ tests the interaction with the keyring() function.
+ """
+ # The keyring function raises until initialized
+ self.assertRaises(Unexpected, get_keyring)
+ self.__do_init()
+ current_keyring = get_keyring()
+ self.assertTrue(isinstance(current_keyring, isc.dns.TSIGKeyRing))
+ # Another initialization does nothing
+ self.__do_init()
+ self.assertEqual(current_keyring, get_keyring())
+ # When we deinitialize it, it no longer provides the keyring
+ deinit_keyring()
+ self.assertEqual('tsig_keys', self.__session._remove_name)
+ self.__session._remove_name = None
+ self.assertRaises(Unexpected, get_keyring)
+ # Another deinitialization doesn't change anything
+ deinit_keyring()
+ self.assertRaises(Unexpected, get_keyring)
+ self.assertIsNone(self.__session._remove_name)
+ # Test we can init it again (not expected, but not forbidden)
+ self.__do_init()
+ self.assertTrue(isinstance(get_keyring(), isc.dns.TSIGKeyRing))
+
+ def test_load(self):
+ """
+ Test it can load the keys from the configuration and reload them
+ when the data change.
+ """
+ # Initial load
+ self.__session._data = ['key:MTIzNAo=:hmac-sha1']
+ self.__do_init()
+ keys = get_keyring()
+ self.assertEqual(1, keys.size())
+ (rcode, key) = keys.find(isc.dns.Name('key'), self.__sha1name)
+ self.assertEqual(isc.dns.TSIGKeyRing.SUCCESS, rcode)
+ self.assertEqual(isc.dns.Name('key'), key.get_key_name())
+ # There's a change in the configuration
+ # (The key has a different name)
+ self.__session._data = ['key.example:MTIzNAo=:hmac-sha1']
+ self.__session._callback()
+ orig_keys = keys
+ keys = get_keyring()
+ self.assertNotEqual(keys, orig_keys)
+ self.assertEqual(1, keys.size())
+ # The old key is not here
+ (rcode, key) = keys.find(isc.dns.Name('key'), self.__sha1name)
+ self.assertEqual(isc.dns.TSIGKeyRing.NOTFOUND, rcode)
+ self.assertIsNone(key)
+ # But the new one is
+ (rcode, key) = keys.find(isc.dns.Name('key.example'), self.__sha1name)
+ self.assertEqual(isc.dns.TSIGKeyRing.SUCCESS, rcode)
+ self.assertEqual(isc.dns.Name('key.example'), key.get_key_name())
+
+ def test_empty_update(self):
+ """
+ Test an update that doesn't carry the correct element doesn't change
+ anything.
+ """
+ self.__session._data = ['key:MTIzNAo=:hmac-sha1']
+ self.__do_init()
+ keys = get_keyring()
+ self.__session._data = None
+ self.__session._callback()
+ self.assertEqual(keys, get_keyring())
+
+ def test_no_keys_update(self):
+ """
+ Test we can update the keyring to be empty.
+ """
+ self.__session._data = ['key:MTIzNAo=:hmac-sha1']
+ self.__do_init()
+ keys = get_keyring()
+ self.assertEqual(1, keys.size())
+ self.__session._data = []
+ self.__session._callback()
+ keys = get_keyring()
+ self.assertEqual(0, keys.size())
+
+ def test_update_multi(self):
+ """
+ Test we can handle multiple keys in startup/update.
+ """
+ # Init
+ self.__session._data = ['key:MTIzNAo=:hmac-sha1', 'key2:MTIzNAo=']
+ self.__do_init()
+ keys = get_keyring()
+ self.assertEqual(2, keys.size())
+ (rcode, key) = keys.find(isc.dns.Name('key'), self.__sha1name)
+ self.assertEqual(isc.dns.TSIGKeyRing.SUCCESS, rcode)
+ self.assertEqual(isc.dns.Name('key'), key.get_key_name())
+ (rcode, key) = keys.find(isc.dns.Name('key2'), self.__md5name)
+ self.assertEqual(isc.dns.TSIGKeyRing.SUCCESS, rcode)
+ self.assertEqual(isc.dns.Name('key2'), key.get_key_name())
+ # Update
+ self.__session._data = ['key1:MTIzNAo=:hmac-sha1', 'key3:MTIzNAo=']
+ self.__session._callback()
+ keys = get_keyring()
+ self.assertEqual(2, keys.size())
+ (rcode, key) = keys.find(isc.dns.Name('key1'), self.__sha1name)
+ self.assertEqual(isc.dns.TSIGKeyRing.SUCCESS, rcode)
+ self.assertEqual(isc.dns.Name('key1'), key.get_key_name())
+ (rcode, key) = keys.find(isc.dns.Name('key3'), self.__md5name)
+ self.assertEqual(isc.dns.TSIGKeyRing.SUCCESS, rcode)
+ self.assertEqual(isc.dns.Name('key3'), key.get_key_name())
+
+ def test_update_bad(self):
+ """
+ Test it raises on bad updates and doesn't change anything.
+ """
+ self.__session._data = ['key:MTIzNAo=:hmac-sha1']
+ self.__do_init()
+ keys = get_keyring()
+ # Bad TSIG string
+ self.__session._data = ['key:this makes no sense:really']
+ self.assertRaises(isc.dns.InvalidParameter, self.__session._callback)
+ self.assertEqual(keys, get_keyring())
+ # A duplicity
+ self.__session._data = ['key:MTIzNAo=:hmac-sha1', 'key:MTIzNAo=:hmac-sha1']
+ self.assertRaises(AddError, self.__session._callback)
+ self.assertEqual(keys, get_keyring())
+
+if __name__ == "__main__":
+ isc.log.init("bind10") # FIXME Should this be needed?
+ isc.log.resetUnitTestRootLogger()
+ unittest.main()
diff --git a/src/lib/python/isc/server_common/tsig_keyring.py b/src/lib/python/isc/server_common/tsig_keyring.py
new file mode 100644
index 0000000..308cfd4
--- /dev/null
+++ b/src/lib/python/isc/server_common/tsig_keyring.py
@@ -0,0 +1,121 @@
+# Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""
+This module conveniently keeps a copy of TSIG keyring loaded from the
+tsig_keys module.
+"""
+
+import isc.dns
+import isc.log
+from isc.log_messages.server_common_messages import *
+
+updater = None
+logger = isc.log.Logger("server_common")
+
+class Unexpected(Exception):
+ """
+ Raised when an unexpected operation is requested by the user of this
+ module. For example if calling keyring() before init_keyring().
+ """
+ pass
+
+class AddError(Exception):
+ """
+ Raised when a key can not be added. This usually means there's a
+ duplicate.
+ """
+ pass
+
+class Updater:
+ """
+ The updater of tsig key ring. Not to be used directly.
+ """
+ def __init__(self, session):
+ """
+ Constructor. Pass the ccsession object so the key ring can be
+ downloaded.
+ """
+ logger.debug(logger.DBGLVL_TRACE_BASIC,
+ PYSERVER_COMMON_TSIG_KEYRING_INIT)
+ self.__session = session
+ self.__keyring = isc.dns.TSIGKeyRing()
+ session.add_remote_config_by_name('tsig_keys', self.__update)
+ self.__update()
+
+ def __update(self, value=None, module_cfg=None):
+ """
+ Update the key ring by the configuration.
+
+ Note that this function is used as a callback, but can raise
+ on bad data. The bad data is expected to be handled by the
+ configuration plugin and not be allowed as far as here.
+
+ The parameters are there just to match the signature which
+ the callback should have (i.e. they are ignored).
+ """
+ logger.debug(logger.DBGLVL_TRACE_BASIC,
+ PYSERVER_COMMON_TSIG_KEYRING_UPDATE)
+ (data, _) = self.__session.get_remote_config_value('tsig_keys', 'keys')
+ if data is not None: # There's an update
+ keyring = isc.dns.TSIGKeyRing()
+ for key_data in data:
+ key = isc.dns.TSIGKey(key_data)
+ if keyring.add(key) != isc.dns.TSIGKeyRing.SUCCESS:
+ raise AddError("Can't add key " + str(key))
+ self.__keyring = keyring
+
+ def get_keyring(self):
+ """
+ Return the current key ring.
+ """
+ return self.__keyring
+
+ def deinit(self):
+ """
+ Unregister from getting updates. The object will not be
+ usable any more after this.
+ """
+ logger.debug(logger.DBGLVL_TRACE_BASIC,
+ PYSERVER_COMMON_TSIG_KEYRING_DEINIT)
+ self.__session.remove_remote_config('tsig_keys')
+
+def get_keyring():
+ """
+ Get the current key ring. You need to call init_keyring first.
+ """
+ if updater is None:
+ raise Unexpected("You need to initialize the keyring first by " +
+ "init_keyring()")
+ return updater.get_keyring()
+
+def init_keyring(session):
+ """
+ Initialize the key ring for future use. It does nothing if already
+ initialized.
+ """
+ global updater
+ if updater is None:
+ updater = Updater(session)
+
+def deinit_keyring():
+ """
+ Deinit key ring. Yoeu can no longer access keyring() after this.
+ Does nothing if not initialized.
+ """
+ global updater
+ if updater is not None:
+ updater.deinit()
+ updater = None
diff --git a/src/lib/resolve/tests/recursive_query_unittest_2.cc b/src/lib/resolve/tests/recursive_query_unittest_2.cc
index a222240..2b3d129 100644
--- a/src/lib/resolve/tests/recursive_query_unittest_2.cc
+++ b/src/lib/resolve/tests/recursive_query_unittest_2.cc
@@ -343,7 +343,8 @@ public:
// Convert to wire format
udp_send_buffer_->clear();
- MessageRenderer renderer(*udp_send_buffer_);
+ MessageRenderer renderer;
+ renderer.setBuffer(udp_send_buffer_.get());
msg.toWire(renderer);
if (mangle_response) {
@@ -477,10 +478,9 @@ public:
setReferralExampleOrg(msg);
// Convert to wire format
- // Use a temporary buffer for the dns wire data (we copy it
+ // Use a temporary renderer for the dns wire data (we copy it
// to the 'real' buffer below)
- OutputBuffer msg_buf(BUFFER_SIZE);
- MessageRenderer renderer(msg_buf);
+ MessageRenderer renderer;
msg.toWire(renderer);
// Expected next state (when checked) is the UDP query to example.org.
@@ -496,12 +496,13 @@ public:
// followed by the actual data. We copy them to a new buffer
// first
tcp_send_buffer_->clear();
- tcp_send_buffer_->writeUint16(msg_buf.getLength());
- tcp_send_buffer_->writeData(msg_buf.getData(), msg_buf.getLength());
+ tcp_send_buffer_->writeUint16(renderer.getLength());
+ tcp_send_buffer_->writeData(renderer.getData(), renderer.getLength());
tcp_socket_.async_send(asio::buffer(tcp_send_buffer_->getData(),
tcp_send_buffer_->getLength()),
- boost::bind(&RecursiveQueryTest2::tcpSendHandler, this,
- tcp_send_buffer_->getLength(), _1, _2));
+ boost::bind(
+ &RecursiveQueryTest2::tcpSendHandler, this,
+ tcp_send_buffer_->getLength(), _1, _2));
}
/// \brief Completion Handler for Sending TCP data
diff --git a/src/lib/resolve/tests/recursive_query_unittest_3.cc b/src/lib/resolve/tests/recursive_query_unittest_3.cc
index 3602b03..168ec80 100644
--- a/src/lib/resolve/tests/recursive_query_unittest_3.cc
+++ b/src/lib/resolve/tests/recursive_query_unittest_3.cc
@@ -240,8 +240,10 @@ public:
// Convert to wire format
udp_send_buffer_->clear();
- MessageRenderer renderer(*udp_send_buffer_);
+ MessageRenderer renderer;
+ renderer.setBuffer(udp_send_buffer_.get());
message.toWire(renderer);
+ renderer.setBuffer(NULL);
// Return a message back to the IOFetch object (after setting the
// expected length of data for the check in the send handler).
@@ -353,8 +355,7 @@ public:
// Convert to wire format
// Use a temporary buffer for the dns wire data (we copy it
// to the 'real' buffer below)
- OutputBuffer msg_buf(BUFFER_SIZE);
- MessageRenderer renderer(msg_buf);
+ MessageRenderer renderer;
message.toWire(renderer);
// Also, take this opportunity to clear the accumulated read count in
@@ -368,12 +369,14 @@ public:
// followed by the actual data. We copy them to a new buffer
// first
tcp_send_buffer_->clear();
- tcp_send_buffer_->writeUint16(msg_buf.getLength());
- tcp_send_buffer_->writeData(msg_buf.getData(), msg_buf.getLength());
+ tcp_send_buffer_->writeUint16(renderer.getLength());
+ tcp_send_buffer_->writeData(renderer.getData(), renderer.getLength());
tcp_socket_.async_send(asio::buffer(tcp_send_buffer_->getData(),
tcp_send_buffer_->getLength()),
- boost::bind(&RecursiveQueryTest3::tcpSendHandler,
- this, tcp_send_buffer_->getLength(), _1, _2));
+ boost::bind(
+ &RecursiveQueryTest3::tcpSendHandler,
+ this,
+ tcp_send_buffer_->getLength(), _1, _2));
}
/// \brief Completion Handler for Sending TCP data
diff --git a/src/lib/testutils/srv_test.cc b/src/lib/testutils/srv_test.cc
index 8b0053c..b28ad57 100644
--- a/src/lib/testutils/srv_test.cc
+++ b/src/lib/testutils/srv_test.cc
@@ -43,8 +43,6 @@ SrvTestBase::SrvTestBase() : request_message(Message::RENDER),
qclass(RRClass::IN()),
qtype(RRType::A()), io_sock(NULL),
io_message(NULL), endpoint(NULL),
- request_obuffer(0),
- request_renderer(request_obuffer),
response_obuffer(new OutputBuffer(0))
{}
diff --git a/src/lib/testutils/srv_test.h b/src/lib/testutils/srv_test.h
index 630232c..be32b55 100644
--- a/src/lib/testutils/srv_test.h
+++ b/src/lib/testutils/srv_test.h
@@ -100,7 +100,6 @@ protected:
asiolink::IOSocket* io_sock;
asiolink::IOMessage* io_message;
const asiolink::IOEndpoint* endpoint;
- isc::util::OutputBuffer request_obuffer;
isc::dns::MessageRenderer request_renderer;
isc::util::OutputBufferPtr response_obuffer;
std::vector<uint8_t> data;
diff --git a/src/lib/testutils/testdata/rfc5155-example.zone.signed b/src/lib/testutils/testdata/rfc5155-example.zone.signed
index 4120224..595c441 100644
--- a/src/lib/testutils/testdata/rfc5155-example.zone.signed
+++ b/src/lib/testutils/testdata/rfc5155-example.zone.signed
@@ -7,8 +7,8 @@ example. 3600 IN NS ns2.example.
example. 3600 IN RRSIG NS 7 1 3600 20150420235959 20051021000000 40430 example. PVOgtMK1HHeSTau+HwDWC8Ts+6C8qtqd4pQJqOtdEVgg+MA+ai4fWDEh u3qHJyLcQ9tbD2vvCnMXjtz6SyObxA==
example. 3600 IN MX 1 xx.example.
example. 3600 IN RRSIG MX 7 1 3600 20150420235959 20051021000000 40430 example. GgQ1A9xs47k42VPvpL/a1BWUz/6XsnHkjotw9So8MQtZtl2wJBsnOQsa oHrRCrRbyriEl/GZn9Mto/Kx+wBo+w==
-example. 3600 IN DNSKEY 256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LUsAD0QPWU+wzt89epO6tH zkMBVDkC7qphQO2hTY4hHn9npWFRw5BYubE=
-example. 3600 IN DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJj7IommWSpJABVfW8Q0rO vXdM6kzt+TAu92L9AbsUdblMFin8CVF3n4s=
+example. 3600 IN DNSKEY 256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LUsAD0QPWU+wzt89epO6tH zkMBVDkC7qphQO2hTY4hHn9npWFRw5BYubE= ; key id = 40430
+example. 3600 IN DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJj7IommWSpJABVfW8Q0rO vXdM6kzt+TAu92L9AbsUdblMFin8CVF3n4s= ; key id = 12708
example. 3600 IN RRSIG DNSKEY 7 1 3600 20150420235959 20051021000000 12708 example. AuU4juU9RaxescSmStrQks3Gh9FblGBlVU31uzMZ/U/FpsUb8aC6QZS+ sTsJXnLnz7flGOsmMGQZf3bH+QsCtg==
example. 3600 IN NSEC3PARAM 1 0 12 AABBCCDD
example. 3600 IN RRSIG NSEC3PARAM 7 1 3600 20150420235959 20051021000000 40430 example. C1Gl8tPZNtnjlrYWDeeUV/sGLCyy/IHie2rerN05XSA3Pq0U3+4VvGWY WdUMfflOdxqnXHwJTLQsjlkynhG6Cg==
diff --git a/src/lib/util/io/fd_share.cc b/src/lib/util/io/fd_share.cc
index 9c02a33..7adbbbe 100644
--- a/src/lib/util/io/fd_share.cc
+++ b/src/lib/util/io/fd_share.cc
@@ -20,6 +20,7 @@
#include <sys/uio.h>
#include <errno.h>
#include <stdlib.h> // for malloc and free
+#include <unistd.h>
#include "fd_share.h"
namespace isc {
@@ -106,7 +107,21 @@ recv_fd(const int sock) {
std::memcpy(&fd, CMSG_DATA(cmsg), sizeof(int));
}
free(msghdr.msg_control);
- return (fd);
+ // It is strange, but the call can return the same file descriptor as
+ // one returned previously, even if that one is not closed yet. So,
+ // we just re-number every one we get, so they are unique.
+ int new_fd(dup(fd));
+ int close_error(close(fd));
+ if (close_error == -1 || new_fd == -1) {
+ // We need to return an error, because something failed. But in case
+ // it was the previous close, we at least try to close the duped FD.
+ if (new_fd != -1) {
+ close(new_fd); // If this fails, nothing but returning error can't
+ // be done and we are doing that anyway.
+ }
+ return (FD_SYSTEM_ERROR);
+ }
+ return (new_fd);
}
int
diff --git a/tests/lettuce/configurations/multi_instance/multi_auth.config.orig b/tests/lettuce/configurations/multi_instance/multi_auth.config.orig
new file mode 100644
index 0000000..f181d42
--- /dev/null
+++ b/tests/lettuce/configurations/multi_instance/multi_auth.config.orig
@@ -0,0 +1 @@
+{"version": 2, "Auth": {"listen_on": [{"port": 47806, "address": "0.0.0.0"}]}, "Boss": {"components": {"b10-auth-2": {"kind": "needed", "special": "auth"}, "b10-auth": {"kind": "needed", "special": "auth"}, "b10-cmdctl": {"kind": "needed", "special": "cmdctl"}}}}
diff --git a/tests/lettuce/configurations/nsec3/nsec3_auth.config b/tests/lettuce/configurations/nsec3/nsec3_auth.config
new file mode 100644
index 0000000..2de5284
--- /dev/null
+++ b/tests/lettuce/configurations/nsec3/nsec3_auth.config
@@ -0,0 +1 @@
+{"version": 2, "Auth": {"datasources": [{"zones": [{"origin": "example.", "file": "configurations/nsec3/rfc5155-example.zone.signed"}], "type": "memory"}], "listen_on": [{"port": 47806, "address": "0.0.0.0"}]}, "Boss": {"components": {"b10-auth": {"kind": "needed", "special": "auth"}, "b10-cmdctl": {"kind": "needed", "special": "cmdctl"}}}}
diff --git a/tests/lettuce/configurations/nsec3/rfc5155-example.zone.signed b/tests/lettuce/configurations/nsec3/rfc5155-example.zone.signed
new file mode 100644
index 0000000..4120224
--- /dev/null
+++ b/tests/lettuce/configurations/nsec3/rfc5155-example.zone.signed
@@ -0,0 +1,72 @@
+;; The example NSEC3-signed zone used in RFC5155.
+
+example. 3600 IN SOA ns1.example. bugs.x.w.example. 1 3600 300 3600000 3600
+example. 3600 IN RRSIG SOA 7 1 3600 20150420235959 20051021000000 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8iq4ZLlYWfUUbbAS41pG+6 8z81q1xhkYAcEyHdVI2LmKusbZsT0Q==
+example. 3600 IN NS ns1.example.
+example. 3600 IN NS ns2.example.
+example. 3600 IN RRSIG NS 7 1 3600 20150420235959 20051021000000 40430 example. PVOgtMK1HHeSTau+HwDWC8Ts+6C8qtqd4pQJqOtdEVgg+MA+ai4fWDEh u3qHJyLcQ9tbD2vvCnMXjtz6SyObxA==
+example. 3600 IN MX 1 xx.example.
+example. 3600 IN RRSIG MX 7 1 3600 20150420235959 20051021000000 40430 example. GgQ1A9xs47k42VPvpL/a1BWUz/6XsnHkjotw9So8MQtZtl2wJBsnOQsa oHrRCrRbyriEl/GZn9Mto/Kx+wBo+w==
+example. 3600 IN DNSKEY 256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LUsAD0QPWU+wzt89epO6tH zkMBVDkC7qphQO2hTY4hHn9npWFRw5BYubE=
+example. 3600 IN DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJj7IommWSpJABVfW8Q0rO vXdM6kzt+TAu92L9AbsUdblMFin8CVF3n4s=
+example. 3600 IN RRSIG DNSKEY 7 1 3600 20150420235959 20051021000000 12708 example. AuU4juU9RaxescSmStrQks3Gh9FblGBlVU31uzMZ/U/FpsUb8aC6QZS+ sTsJXnLnz7flGOsmMGQZf3bH+QsCtg==
+example. 3600 IN NSEC3PARAM 1 0 12 AABBCCDD
+example. 3600 IN RRSIG NSEC3PARAM 7 1 3600 20150420235959 20051021000000 40430 example. C1Gl8tPZNtnjlrYWDeeUV/sGLCyy/IHie2rerN05XSA3Pq0U3+4VvGWY WdUMfflOdxqnXHwJTLQsjlkynhG6Cg==
+2t7b4g4vsa5smi47k61mv5bv1a22bojr.example. 3600 IN A 192.0.2.127
+2t7b4g4vsa5smi47k61mv5bv1a22bojr.example. 3600 IN RRSIG A 7 2 3600 20150420235959 20051021000000 40430 example. h6c++bzhRuWWt2bykN6mjaTNBcXNq5UuL5EdK+iDP4eY8I0kSiKaCjg3 tC1SQkeloMeub2GWk8p6xHMPZumXlw==
+a.example. 3600 IN NS ns1.a.example.
+a.example. 3600 IN NS ns2.a.example.
+a.example. 3600 IN DS 58470 5 1 3079F1593EBAD6DC121E202A8B766A6A4837206C
+a.example. 3600 IN RRSIG DS 7 2 3600 20150420235959 20051021000000 40430 example. XacFcQVHLVzdoc45EJhN616zQ4mEXtE8FzUhM2KWjfy1VfRKD9r1MeVG wwoukOKgJxBPFsWoo722vZ4UZ2dIdA==
+ns1.a.example. 3600 IN A 192.0.2.5
+ns2.a.example. 3600 IN A 192.0.2.6
+ai.example. 3600 IN A 192.0.2.9
+ai.example. 3600 IN RRSIG A 7 2 3600 20150420235959 20051021000000 40430 example. hVe+wKYMlObTRPhX0NL67GxeZfdxqr/QeR6FtfdAj5+FgYxyzPEjIzvK Wy00hWIl6wD3Vws+rznEn8sQ64UdqA==
+ai.example. 3600 IN HINFO "KLH-10" "ITS"
+ai.example. 3600 IN RRSIG HINFO 7 2 3600 20150420235959 20051021000000 40430 example. Yi42uOq43eyO6qXHNvwwfFnIustWgV5urFcxenkLvs6pKRh00VBjODmf 3Z4nMO7IOl6nHSQ1v0wLHpEZG7Xj2w==
+ai.example. 3600 IN AAAA 2001:db8::f00:baa9
+ai.example. 3600 IN RRSIG AAAA 7 2 3600 20150420235959 20051021000000 40430 example. LcdxKaCB5bGZwPDg+3JJ4O02zoMBrjxqlf6WuaHQZZfTUpb9Nf2nxFGe 2XRPfR5tpJT6GdRGcHueLuXkMjBArQ==
+c.example. 3600 IN NS ns1.c.example.
+c.example. 3600 IN NS ns2.c.example.
+ns1.c.example. 3600 IN A 192.0.2.7
+ns2.c.example. 3600 IN A 192.0.2.8
+ns1.example. 3600 IN A 192.0.2.1
+ns1.example. 3600 IN RRSIG A 7 2 3600 20150420235959 20051021000000 40430 example. bu6kx73n6XEunoVGuRfAgY7EF/AJqHy7hj0jkiqJjB0dOrx3wuz9SaBe GfqWIdn/uta3SavN4FRvZR9SCFHF5Q==
+ns2.example. 3600 IN A 192.0.2.2
+ns2.example. 3600 IN RRSIG A 7 2 3600 20150420235959 20051021000000 40430 example. ktQ3TqE0CfRfki0Rb/Ip5BM0VnxelbuejCC4zpLbFKA/7eD7UNAwxMgx JPtbdST+syjYSJaj4IHfeX6n8vfoGA==
+*.w.example. 3600 IN MX 1 ai.example.
+*.w.example. 3600 IN RRSIG MX 7 2 3600 20150420235959 20051021000000 40430 example. CikebjQwGQPwijVcxgcZcSJKtfynugtlBiKb9FcBTrmOoyQ4InoWVudh CWsh/URX3lc4WRUMivEBP6+4KS3ldA==
+x.w.example. 3600 IN MX 1 xx.example.
+x.w.example. 3600 IN RRSIG MX 7 3 3600 20150420235959 20051021000000 40430 example. IrK3tq/tHFIBF0scHiE/1IwMAvckS/55hAVvQyxTFbkAdDloP3NbZzu+ yoSsr3b3OX6qbBpY7WCtwwekLKRAwQ==
+x.y.w.example. 3600 IN MX 1 xx.example.
+x.y.w.example. 3600 IN RRSIG MX 7 4 3600 20150420235959 20051021000000 40430 example. MqSt5HqJIN8+SLlzTOImrh5h9Xa6gDvAW/GnnbdPc6Z7nXvCpLPJj/5l Cwx3VuzVOjkbvXze8/8Ccl2Zn2hbug==
+xx.example. 3600 IN A 192.0.2.10
+xx.example. 3600 IN RRSIG A 7 2 3600 20150420235959 20051021000000 40430 example. T35hBWEZ017VC5u2c4OriKyVn/pu+fVK4AlXYOxJ6iQylfV2HQIKjv6b 7DzINB3aF/wjJqgXpQvhq+Ac6+ZiFg==
+xx.example. 3600 IN HINFO "KLH-10" "TOPS-20"
+xx.example. 3600 IN RRSIG HINFO 7 2 3600 20150420235959 20051021000000 40430 example. KimG+rDd+7VA1zRsu0ITNAQUTRlpnsmqWrihFRnU+bRa93v2e5oFNFYC s3Rqgv62K93N7AhW6Jfqj/8NzWjvKg==
+xx.example. 3600 IN AAAA 2001:db8::f00:baaa
+xx.example. 3600 IN RRSIG AAAA 7 2 3600 20150420235959 20051021000000 40430 example. IXBcXORITNwd8h3gNwyxtYFvAupS/CYWufVeuBUX0O25ivBCULjZjpDx FSxfohb/KA7YRdxENzYfMItpILl/Xw==
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. 3600 IN NSEC3 1 1 12 AABBCCDD 2T7B4G4VSA5SMI47K61MV5BV1A22BOJR NS SOA MX RRSIG DNSKEY NSEC3PARAM
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKLIBHYH6blRxK9rC0bMJPw Q4mLIuw85H2EY762BOCXJZMnpuwhpA==
+2t7b4g4vsa5smi47k61mv5bv1a22bojr.example. 3600 IN NSEC3 1 1 12 AABBCCDD 2VPTU5TIMAMQTTGL4LUU9KG21E0AOR3S A RRSIG
+2t7b4g4vsa5smi47k61mv5bv1a22bojr.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. OmBvJ1Vgg1hCKMXHFiNeIYHK9XVW0iLDLwJN4TFoNxZuP03gAXEI634Y wOc4YBNITrj413iqNI6mRk/r1dOSUw==
+2vptu5timamqttgl4luu9kg21e0aor3s.example. 3600 IN NSEC3 1 1 12 AABBCCDD 35MTHGPGCU1QG68FAB165KLNSNK3DPVL MX RRSIG
+2vptu5timamqttgl4luu9kg21e0aor3s.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. KL1V2oFYghNV0Hm7Tf2vpJjM6l+0g1JCcVYGVfI0lKrhPmTsOA96cLEA Cgo1x8I7kApJX+obTuktZ+sdsZPY1w==
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. 3600 IN NSEC3 1 1 12 AABBCCDD B4UM86EGHHDS6NEA196SMVMLO4ORS995 NS DS RRSIG
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQAynzo8EUWH+z6hEIBlUT PGj15eZll6VhQqgZXtAIR3chwgW+SA==
+b4um86eghhds6nea196smvmlo4ors995.example. 3600 IN NSEC3 1 1 12 AABBCCDD GJEQE526PLBF1G8MKLP59ENFD789NJGI MX RRSIG
+b4um86eghhds6nea196smvmlo4ors995.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. ZkPG3M32lmoHM6pa3D6gZFGB/rhL//Bs3Omh5u4m/CUiwtblEVOaAKKZ d7S959OeiX43aLX3pOv0TSTyiTxIZg==
+gjeqe526plbf1g8mklp59enfd789njgi.example. 3600 IN NSEC3 1 1 12 AABBCCDD JI6NEOAEPV8B5O6K4EV33ABHA8HT9FGC A HINFO AAAA RRSIG
+gjeqe526plbf1g8mklp59enfd789njgi.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. IVnezTJ9iqblFF97vPSmfXZ5Zozngx3KX3byLTZC4QBH2dFWhf6scrGF ZB980AfCxoD9qbbKDy+rdGIeRSVNyw==
+ji6neoaepv8b5o6k4ev33abha8ht9fgc.example. 3600 IN NSEC3 1 1 12 AABBCCDD K8UDEMVP1J2F7EG6JEBPS17VP3N8I58H
+ji6neoaepv8b5o6k4ev33abha8ht9fgc.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. gPkFp1s2QDQ6wQzcg1uSebZ61W33rUBDcTj72F3kQ490fEdp7k1BUIfb cZtPbX3YCpE+sIt0MpzVSKfTwx4uYA==
+k8udemvp1j2f7eg6jebps17vp3n8i58h.example. 3600 IN NSEC3 1 1 12 AABBCCDD KOHAR7MBB8DC2CE8A9QVL8HON4K53UHI
+k8udemvp1j2f7eg6jebps17vp3n8i58h.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. FtXGbvF0+wf8iWkyo73enAuVx03klN+pILBKS6qCcftVtfH4yVzsEZqu J27NHR7ruxJWDNMtOtx7w9WfcIg62A==
+kohar7mbb8dc2ce8a9qvl8hon4k53uhi.example. 3600 IN NSEC3 1 1 12 AABBCCDD Q04JKCEVQVMU85R014C7DKBA38O0JI5R A RRSIG
+kohar7mbb8dc2ce8a9qvl8hon4k53uhi.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. VrDXs2uVW21N08SyQIz88zml+y4ZCInTwgDr6zz43yAg+LFERjOrj3Oj ct51ac7Dp4eZbf9FQJazmASFKGxGXg==
+q04jkcevqvmu85r014c7dkba38o0ji5r.example. 3600 IN NSEC3 1 1 12 AABBCCDD R53BQ7CC2UVMUBFU5OCMM6PERS9TK9EN A RRSIG
+q04jkcevqvmu85r014c7dkba38o0ji5r.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. hV5I89b+4FHJDATp09g4bbN0R1F845CaXpL3ZxlMKimoPAyqletMlEWw LfFia7sdpSzn+ZlNNlkxWcLsIlMmUg==
+r53bq7cc2uvmubfu5ocmm6pers9tk9en.example. 3600 IN NSEC3 1 1 12 AABBCCDD T644EBQK9BIBCNA874GIVR6JOJ62MLHV MX RRSIG
+r53bq7cc2uvmubfu5ocmm6pers9tk9en.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. aupviViruXs4bDg9rCbezzBMf9h1ZlDvbW/CZFKulIGXXLj8B/fsDJar XVDA9bnUoRhEbKp+HF1FWKW7RIJdtQ==
+t644ebqk9bibcna874givr6joj62mlhv.example. 3600 IN NSEC3 1 1 12 AABBCCDD 0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM A HINFO AAAA RRSIG
+t644ebqk9bibcna874givr6joj62mlhv.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. RAjGECB8P7O+F4Pa4Dx3tC0M+Z3KmlLKImcafb9XWwx+NWUNz7NBEDBQ HivIyKPVDkChcePIX1xPl1ATNa+8Dw==
diff --git a/tests/lettuce/features/multi_instance.feature b/tests/lettuce/features/multi_instance.feature
new file mode 100644
index 0000000..864431d
--- /dev/null
+++ b/tests/lettuce/features/multi_instance.feature
@@ -0,0 +1,35 @@
+Feature: Multiple instances
+ This feature tests whether multiple instances can be run, and whether
+ removing them does not affect the running of other instances
+
+ Scenario: Multiple instances of Auth
+ # This config should have two running instances
+ Given I have bind10 running with configuration multi_instance/multi_auth.config
+ And bind10 module Auth should be running
+ A query for example.com should have rcode REFUSED
+
+ # this also checks whether the process is running
+ If I remember the pid of process b10-auth
+ And remember the pid of process b10-auth-2
+
+ When I remove bind10 configuration Boss/components value b10-auth-2
+
+ Then the pid of process b10-auth should not have changed
+ And a query for example.com should have rcode REFUSED
+
+ When I send bind10 the following commands
+ """
+ config add Boss/components b10-auth-2
+ config set Boss/components/b10-auth-2/special auth
+ config set Boss/components/b10-auth-2/kind needed
+ config commit
+ """
+ And wait for new bind10 stderr message AUTH_SERVER_STARTED
+ And remember the pid of process b10-auth-2
+
+ Then the pid of process b10-auth should not have changed
+ A query for example.com should have rcode REFUSED
+
+ When I remove bind10 configuration Boss/components value b10-auth
+ Then the pid of process b10-auth-2 should not have changed
+ A query for example.com should have rcode REFUSED
diff --git a/tests/lettuce/features/nsec3_auth.feature b/tests/lettuce/features/nsec3_auth.feature
new file mode 100644
index 0000000..ceb9a7f
--- /dev/null
+++ b/tests/lettuce/features/nsec3_auth.feature
@@ -0,0 +1,302 @@
+Feature: NSEC3 Authoritative service
+ This feature tests NSEC3 as defined in RFC5155, using the example
+ zone from appendix A and testing the example responses from appendix B.
+ Additional tests can be added as well.
+
+ # Response section data is taken directly from RFC5155
+ # It has been modified slightly; it has been 'flattened' (i.e. converted
+ # to 1-line RRs with TTL and class data), and whitespace has been added
+ # in the places where dig adds them too.
+ # Any other changes from the specific example data are added as inline
+ # comments.
+
+ Scenario: B.1. Name Error
+ Given I have bind10 running with configuration nsec3/nsec3_auth.config
+ A dnssec query for a.c.x.w.example. should have rcode NXDOMAIN
+ The last query response should have flags qr aa rd
+ The last query response should have edns_flags do
+ The last query response should have ancount 0
+ The last query response should have nscount 8
+ The last query response should have adcount 1
+ The authority section of the last query response should be
+ """
+ example. 3600 IN SOA ns1.example. bugs.x.w.example. 1 3600 300 3600000 3600
+ example. 3600 IN RRSIG SOA 7 1 3600 20150420235959 20051021000000 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8iq4ZLlYWfUUbbAS41pG+6 8z81q1xhkYAcEyHdVI2LmKusbZsT0Q==
+ 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. 3600 IN NSEC3 1 1 12 aabbccdd 2t7b4g4vsa5smi47k61mv5bv1a22bojr NS SOA MX RRSIG DNSKEY NSEC3PARAM
+ 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKLIBHYH6blRxK9rC0bMJPw Q4mLIuw85H2EY762BOCXJZMnpuwhpA==
+ b4um86eghhds6nea196smvmlo4ors995.example. 3600 IN NSEC3 1 1 12 aabbccdd gjeqe526plbf1g8mklp59enfd789njgi MX RRSIG
+ b4um86eghhds6nea196smvmlo4ors995.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. ZkPG3M32lmoHM6pa3D6gZFGB/rhL//Bs3Omh5u4m/CUiwtblEVOaAKKZ d7S959OeiX43aLX3pOv0TSTyiTxIZg==
+ 35mthgpgcu1qg68fab165klnsnk3dpvl.example. 3600 IN NSEC3 1 1 12 aabbccdd b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG
+ 35mthgpgcu1qg68fab165klnsnk3dpvl.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQAynzo8EUWH+z6hEIBlUT PGj15eZll6VhQqgZXtAIR3chwgW+SA==
+ """
+
+ Scenario: B.2. No Data Error
+ Given I have bind10 running with configuration nsec3/nsec3_auth.config
+ A dnssec query for ns1.example. type MX should have rcode NOERROR
+ The last query response should have flags qr aa rd
+ The last query response should have edns_flags do
+ The last query response should have ancount 0
+ The last query response should have nscount 4
+ The last query response should have adcount 1
+ The authority section of the last query response should be
+ """
+ example. 3600 IN SOA ns1.example. bugs.x.w.example. 1 3600 300 3600000 3600
+ example. 3600 IN RRSIG SOA 7 1 3600 20150420235959 20051021000000 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8iq4ZLlYWfUUbbAS41pG+6 8z81q1xhkYAcEyHdVI2LmKusbZsT0Q==
+ 2t7b4g4vsa5smi47k61mv5bv1a22bojr.example. 3600 IN NSEC3 1 1 12 aabbccdd 2vptu5timamqttgl4luu9kg21e0aor3s A RRSIG
+ 2t7b4g4vsa5smi47k61mv5bv1a22bojr.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. OmBvJ1Vgg1hCKMXHFiNeIYHK9XVW0iLDLwJN4TFoNxZuP03gAXEI634Y wOc4YBNITrj413iqNI6mRk/r1dOSUw==
+ """
+
+ Scenario: B2.1. No Data Error, Empty Non-Terminal
+ Given I have bind10 running with configuration nsec3/nsec3_auth.config
+ A dnssec query for y.w.example. should have rcode NOERROR
+ The last query response should have flags qr aa rd
+ The last query response should have edns_flags do
+ The last query response should have ancount 0
+ The last query response should have nscount 4
+ The last query response should have adcount 1
+ The authority section of the last query response should be
+ """
+ example. 3600 IN SOA ns1.example. bugs.x.w.example. 1 3600 300 3600000 3600
+ example. 3600 IN RRSIG SOA 7 1 3600 20150420235959 20051021000000 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8iq4ZLlYWfUUbbAS41pG+6 8z81q1xhkYAcEyHdVI2LmKusbZsT0Q==
+ ji6neoaepv8b5o6k4ev33abha8ht9fgc.example. 3600 IN NSEC3 1 1 12 aabbccdd k8udemvp1j2f7eg6jebps17vp3n8i58h
+ ji6neoaepv8b5o6k4ev33abha8ht9fgc.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. gPkFp1s2QDQ6wQzcg1uSebZ61W33rUBDcTj72F3kQ490fEdp7k1BUIfb cZtPbX3YCpE+sIt0MpzVSKfTwx4uYA==
+ """
+
+ Scenario: B.3. Referral to an Opt-Out Unsigned Zone
+ Given I have bind10 running with configuration nsec3/nsec3_auth.config
+ A dnssec query for mc.c.example. type MX should have rcode NOERROR
+ The last query response should have flags qr rd
+ The last query response should have edns_flags do
+ The last query response should have ancount 0
+ The last query response should have nscount 6
+ The last query response should have adcount 3
+ The authority section of the last query response should be
+ """
+ c.example. 3600 IN NS ns1.c.example.
+ c.example. 3600 IN NS ns2.c.example.
+ 35mthgpgcu1qg68fab165klnsnk3dpvl.example. 3600 IN NSEC3 1 1 12 aabbccdd b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG
+ 35mthgpgcu1qg68fab165klnsnk3dpvl.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQAynzo8EUWH+z6hEIBlUT PGj15eZll6VhQqgZXtAIR3chwgW+SA==
+ 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. 3600 IN NSEC3 1 1 12 aabbccdd 2t7b4g4vsa5smi47k61mv5bv1a22bojr NS SOA MX RRSIG DNSKEY NSEC3PARAM
+ 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKLIBHYH6blRxK9rC0bMJPw Q4mLIuw85H2EY762BOCXJZMnpuwhpA==
+ """
+ The additional section of the last query response should be
+ """
+ ns1.c.example. 3600 IN A 192.0.2.7
+ ns2.c.example. 3600 IN A 192.0.2.8
+ """
+
+ Scenario: B.4. Wildcard Expansion
+ Given I have bind10 running with configuration nsec3/nsec3_auth.config
+ A dnssec query for a.z.w.example. type MX should have rcode NOERROR
+ The last query response should have flags qr aa rd
+ The last query response should have edns_flags do
+ The last query response should have ancount 2
+ The last query response should have nscount 5
+ The last query response should have adcount 9
+ The answer section of the last query response should be
+ """
+ a.z.w.example. 3600 IN MX 1 ai.example.
+ a.z.w.example. 3600 IN RRSIG MX 7 2 3600 20150420235959 20051021000000 40430 example. CikebjQwGQPwijVcxgcZcSJKtfynugtlBiKb9FcBTrmOoyQ4InoWVudh CWsh/URX3lc4WRUMivEBP6+4KS3ldA==
+ """
+ The authority section of the last query response should be
+ """
+ example. 3600 IN NS ns1.example.
+ example. 3600 IN NS ns2.example.
+ example. 3600 IN RRSIG NS 7 1 3600 20150420235959 20051021000000 40430 example. PVOgtMK1HHeSTau+HwDWC8Ts+6C8qtqd4pQJqOtdEVgg+MA+ai4fWDEh u3qHJyLcQ9tbD2vvCnMXjtz6SyObxA==
+ q04jkcevqvmu85r014c7dkba38o0ji5r.example. 3600 IN NSEC3 1 1 12 aabbccdd r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG
+ q04jkcevqvmu85r014c7dkba38o0ji5r.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. hV5I89b+4FHJDATp09g4bbN0R1F845CaXpL3ZxlMKimoPAyqletMlEWw LfFia7sdpSzn+ZlNNlkxWcLsIlMmUg==
+ """
+ # This is slightly different from the example in RFC5155; there are
+ # more RRs in the additional section.
+ The additional section of the last query response should be
+ """
+ ai.example. 3600 IN A 192.0.2.9
+ ai.example. 3600 IN AAAA 2001:db8::f00:baa9
+ ns1.example. 3600 IN A 192.0.2.1
+ ns2.example. 3600 IN A 192.0.2.2
+ ai.example. 3600 IN RRSIG A 7 2 3600 20150420235959 20051021000000 40430 example. hVe+wKYMlObTRPhX0NL67GxeZfdxqr/QeR6FtfdAj5+FgYxyzPEjIzvK Wy00hWIl6wD3Vws+rznEn8sQ64UdqA==
+ ai.example. 3600 IN RRSIG AAAA 7 2 3600 20150420235959 20051021000000 40430 example. LcdxKaCB5bGZwPDg+3JJ4O02zoMBrjxqlf6WuaHQZZfTUpb9Nf2nxFGe 2XRPfR5tpJT6GdRGcHueLuXkMjBArQ==
+ ns1.example. 3600 IN RRSIG A 7 2 3600 20150420235959 20051021000000 40430 example. bu6kx73n6XEunoVGuRfAgY7EF/AJqHy7hj0jkiqJjB0dOrx3wuz9SaBe GfqWIdn/uta3SavN4FRvZR9SCFHF5Q==
+ ns2.example. 3600 IN RRSIG A 7 2 3600 20150420235959 20051021000000 40430 example. ktQ3TqE0CfRfki0Rb/Ip5BM0VnxelbuejCC4zpLbFKA/7eD7UNAwxMgx JPtbdST+syjYSJaj4IHfeX6n8vfoGA==
+ """
+
+ Scenario: B.5. Wildcard No Data Error
+ Given I have bind10 running with configuration nsec3/nsec3_auth.config
+ A dnssec query for a.z.w.example. type AAAA should have rcode NOERROR
+ The last query response should have flags qr aa rd
+ The last query response should have edns_flags do
+ The last query response should have ancount 0
+ The last query response should have nscount 8
+ The last query response should have adcount 1
+ The authority section of the last query response should be
+ """
+ example. 3600 IN SOA ns1.example. bugs.x.w.example. 1 3600 300 3600000 3600
+ example. 3600 IN RRSIG SOA 7 1 3600 20150420235959 20051021000000 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8iq4ZLlYWfUUbbAS41pG+6 8z81q1xhkYAcEyHdVI2LmKusbZsT0Q==
+ k8udemvp1j2f7eg6jebps17vp3n8i58h.example. 3600 IN NSEC3 1 1 12 aabbccdd kohar7mbb8dc2ce8a9qvl8hon4k53uhi
+ k8udemvp1j2f7eg6jebps17vp3n8i58h.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. FtXGbvF0+wf8iWkyo73enAuVx03klN+pILBKS6qCcftVtfH4yVzsEZqu J27NHR7ruxJWDNMtOtx7w9WfcIg62A==
+ q04jkcevqvmu85r014c7dkba38o0ji5r.example. 3600 IN NSEC3 1 1 12 aabbccdd r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG
+ q04jkcevqvmu85r014c7dkba38o0ji5r.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. hV5I89b+4FHJDATp09g4bbN0R1F845CaXpL3ZxlMKimoPAyqletMlEWw LfFia7sdpSzn+ZlNNlkxWcLsIlMmUg==
+ r53bq7cc2uvmubfu5ocmm6pers9tk9en.example. 3600 IN NSEC3 1 1 12 aabbccdd t644ebqk9bibcna874givr6joj62mlhv MX RRSIG
+ r53bq7cc2uvmubfu5ocmm6pers9tk9en.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. aupviViruXs4bDg9rCbezzBMf9h1ZlDvbW/CZFKulIGXXLj8B/fsDJar XVDA9bnUoRhEbKp+HF1FWKW7RIJdtQ==
+ """
+
+ Scenario: B.6. DS Child Zone No Data Error
+ Given I have bind10 running with configuration nsec3/nsec3_auth.config
+ A dnssec query for example. type DS should have rcode NOERROR
+ The last query response should have flags qr aa rd
+ The last query response should have edns_flags do
+ The last query response should have ancount 0
+ The last query response should have nscount 4
+ The last query response should have adcount 1
+ The authority section of the last query response should be
+ """
+ example. 3600 IN SOA ns1.example. bugs.x.w.example. 1 3600 300 3600000 3600
+ example. 3600 IN RRSIG SOA 7 1 3600 20150420235959 20051021000000 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8iq4ZLlYWfUUbbAS41pG+6 8z81q1xhkYAcEyHdVI2LmKusbZsT0Q==
+ 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. 3600 IN NSEC3 1 1 12 aabbccdd 2t7b4g4vsa5smi47k61mv5bv1a22bojr NS SOA MX RRSIG DNSKEY NSEC3PARAM
+ 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKLIBHYH6blRxK9rC0bMJPw Q4mLIuw85H2EY762BOCXJZMnpuwhpA==
+ """
+
+ #
+ # Below are additional tests, not explicitely stated in RFC5155
+ #
+
+ # THIS TEST CURRENTLY FAILS: An NSEC3 record is added twice
+ # See ticket #1688
+ #Scenario: 7.2.2 other; Name Error where one NSEC3 covers multiple parts of proof (closest encloser)
+ # Given I have bind10 running with configuration nsec3/nsec3_auth.config
+ # A dnssec query for b.x.w.example. should have rcode NXDOMAIN
+ # The last query response should have flags qr aa rd
+ # The last query response should have edns_flags do
+ # The last query response should have ancount 0
+ # The last query response should have nscount 6
+ # The last query response should have adcount 1
+ # The authority section of the last query response should be
+ # """
+ # example. 3600 IN SOA ns1.example. bugs.x.w.example. 1 3600 300 3600000 3600
+ # example. 3600 IN RRSIG SOA 7 1 3600 20150420235959 20051021000000 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8iq4ZLlYWfUUbbAS41pG+6 8z81q1xhkYAcEyHdVI2LmKusbZsT0Q==
+ # b4um86eghhds6nea196smvmlo4ors995.example. 3600 IN NSEC3 1 1 12 aabbccdd gjeqe526plbf1g8mklp59enfd789njgi MX RRSIG
+ # b4um86eghhds6nea196smvmlo4ors995.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. ZkPG3M32lmoHM6pa3D6gZFGB/rhL//Bs3Omh5u4m/CUiwtblEVOaAKKZ d7S959OeiX43aLX3pOv0TSTyiTxIZg==
+ # 35mthgpgcu1qg68fab165klnsnk3dpvl.example. 3600 IN NSEC3 1 1 12 aabbccdd b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG
+ # 35mthgpgcu1qg68fab165klnsnk3dpvl.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQAynzo8EUWH+z6hEIBlUT PGj15eZll6VhQqgZXtAIR3chwgW+SA==
+ # """
+
+ # THIS TEST CURRENTLY FAILS: An NSEC3 record is added twice
+ # See ticket #1688
+ #Scenario: 7.2.2 other; Name Error where one NSEC3 covers multiple parts of proof (wildcard)
+ # Given I have bind10 running with configuration nsec3/nsec3_auth.config
+ # A dnssec query for a.w.example. should have rcode NXDOMAIN
+ # The last query response should have flags qr aa rd
+ # The last query response should have edns_flags do
+ # The last query response should have ancount 0
+ # The last query response should have nscount 6
+ # The last query response should have adcount 1
+ # The authority section of the last query response should be
+ # """
+ # example. 3600 IN SOA ns1.example. bugs.x.w.example. 1 3600 300 3600000 3600
+ # example. 3600 IN RRSIG SOA 7 1 3600 20150420235959 20051021000000 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8iq4ZLlYWfUUbbAS41pG+6 8z81q1xhkYAcEyHdVI2LmKusbZsT0Q==
+ # k8udemvp1j2f7eg6jebps17vp3n8i58h.example. 3600 IN NSEC3 1 1 12 AABBCCDD KOHAR7MBB8DC2CE8A9QVL8HON4K53UHI
+ # k8udemvp1j2f7eg6jebps17vp3n8i58h.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. FtXGbvF0+wf8iWkyo73enAuVx03klN+pILBKS6qCcftVtfH4yVzsEZqu J27NHR7ruxJWDNMtOtx7w9WfcIg62A==
+ # r53bq7cc2uvmubfu5ocmm6pers9tk9en.example. 3600 IN NSEC3 1 1 12 AABBCCDD T644EBQK9BIBCNA874GIVR6JOJ62MLHV MX RRSIG
+ # r53bq7cc2uvmubfu5ocmm6pers9tk9en.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. aupviViruXs4bDg9rCbezzBMf9h1ZlDvbW/CZFKulIGXXLj8B/fsDJar XVDA9bnUoRhEbKp+HF1FWKW7RIJdtQ==
+ # """
+
+ Scenario: Wildcard other: Wildcard name itself
+ Given I have bind10 running with configuration nsec3/nsec3_auth.config
+ A dnssec query for *.w.example. type MX should have rcode NOERROR
+ The last query response should have flags qr aa rd
+ The last query response should have edns_flags do
+ The last query response should have ancount 2
+ The last query response should have nscount 3
+ The last query response should have adcount 9
+ The answer section of the last query response should be
+ """
+ *.w.example. 3600 IN MX 1 ai.example.
+ *.w.example. 3600 IN RRSIG MX 7 2 3600 20150420235959 20051021000000 40430 example. CikebjQwGQPwijVcxgcZcSJKtfynugtlBiKb9FcBTrmOoyQ4InoWVudh CWsh/URX3lc4WRUMivEBP6+4KS3ldA==
+ """
+ The authority section of the last query response should be
+ """
+ example. 3600 IN NS ns1.example.
+ example. 3600 IN NS ns2.example.
+ example. 3600 IN RRSIG NS 7 1 3600 20150420235959 20051021000000 40430 example. PVOgtMK1HHeSTau+HwDWC8Ts+6C8qtqd4pQJqOtdEVgg+MA+ai4fWDEh u3qHJyLcQ9tbD2vvCnMXjtz6SyObxA==
+ """
+ The additional section of the last query response should be
+ """
+ ai.example. 3600 IN A 192.0.2.9
+ ai.example. 3600 IN AAAA 2001:db8::f00:baa9
+ ns1.example. 3600 IN A 192.0.2.1
+ ns2.example. 3600 IN A 192.0.2.2
+ ai.example. 3600 IN RRSIG A 7 2 3600 20150420235959 20051021000000 40430 example. hVe+wKYMlObTRPhX0NL67GxeZfdxqr/QeR6FtfdAj5+FgYxyzPEjIzvK Wy00hWIl6wD3Vws+rznEn8sQ64UdqA==
+ ai.example. 3600 IN RRSIG AAAA 7 2 3600 20150420235959 20051021000000 40430 example. LcdxKaCB5bGZwPDg+3JJ4O02zoMBrjxqlf6WuaHQZZfTUpb9Nf2nxFGe 2XRPfR5tpJT6GdRGcHueLuXkMjBArQ==
+ ns1.example. 3600 IN RRSIG A 7 2 3600 20150420235959 20051021000000 40430 example. bu6kx73n6XEunoVGuRfAgY7EF/AJqHy7hj0jkiqJjB0dOrx3wuz9SaBe GfqWIdn/uta3SavN4FRvZR9SCFHF5Q==
+ ns2.example. 3600 IN RRSIG A 7 2 3600 20150420235959 20051021000000 40430 example. ktQ3TqE0CfRfki0Rb/Ip5BM0VnxelbuejCC4zpLbFKA/7eD7UNAwxMgx JPtbdST+syjYSJaj4IHfeX6n8vfoGA==
+ """
+
+ Scenario: Wildcard other: Wildcard name itself nodata
+ Given I have bind10 running with configuration nsec3/nsec3_auth.config
+ A dnssec query for *.w.example. type A should have rcode NOERROR
+ The last query response should have flags qr aa rd
+ The last query response should have edns_flags do
+ The last query response should have ancount 0
+ The last query response should have nscount 4
+ The last query response should have adcount 1
+ The authority section of the last query response should be
+ """
+ example. 3600 IN SOA ns1.example. bugs.x.w.example. 1 3600 300 3600000 3600
+ example. 3600 IN RRSIG SOA 7 1 3600 20150420235959 20051021000000 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8iq4ZLlYWfUUbbAS41pG+6 8z81q1xhkYAcEyHdVI2LmKusbZsT0Q==
+ r53bq7cc2uvmubfu5ocmm6pers9tk9en.example. 3600 IN NSEC3 1 1 12 AABBCCDD T644EBQK9BIBCNA874GIVR6JOJ62MLHV MX RRSIG
+ r53bq7cc2uvmubfu5ocmm6pers9tk9en.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. aupviViruXs4bDg9rCbezzBMf9h1ZlDvbW/CZFKulIGXXLj8B/fsDJar XVDA9bnUoRhEbKp+HF1FWKW7RIJdtQ==
+ """
+
+ Scenario: Direct query for NSEC3 record
+ Given I have bind10 running with configuration nsec3/nsec3_auth.config
+ A dnssec query for 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. type NSEC3 should have rcode NXDOMAIN
+ The last query response should have flags qr aa rd
+ The last query response should have edns_flags do
+ The last query response should have ancount 0
+ The last query response should have nscount 8
+ The last query response should have adcount 1
+ The authority section of the last query response should be
+ """
+ example. 3600 IN SOA ns1.example. bugs.x.w.example. 1 3600 300 3600000 3600
+ example. 3600 IN RRSIG SOA 7 1 3600 20150420235959 20051021000000 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8iq4ZLlYWfUUbbAS41pG+6 8z81q1xhkYAcEyHdVI2LmKusbZsT0Q==
+ 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. 3600 IN NSEC3 1 1 12 AABBCCDD 2T7B4G4VSA5SMI47K61MV5BV1A22BOJR NS SOA MX RRSIG DNSKEY NSEC3PARAM
+ 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKLIBHYH6blRxK9rC0bMJPw Q4mLIuw85H2EY762BOCXJZMnpuwhpA==
+ q04jkcevqvmu85r014c7dkba38o0ji5r.example. 3600 IN NSEC3 1 1 12 AABBCCDD R53BQ7CC2UVMUBFU5OCMM6PERS9TK9EN A RRSIG
+ q04jkcevqvmu85r014c7dkba38o0ji5r.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. hV5I89b+4FHJDATp09g4bbN0R1F845CaXpL3ZxlMKimoPAyqletMlEWw LfFia7sdpSzn+ZlNNlkxWcLsIlMmUg==
+ gjeqe526plbf1g8mklp59enfd789njgi.example. 3600 IN NSEC3 1 1 12 AABBCCDD JI6NEOAEPV8B5O6K4EV33ABHA8HT9FGC A HINFO AAAA RRSIG
+ gjeqe526plbf1g8mklp59enfd789njgi.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. IVnezTJ9iqblFF97vPSmfXZ5Zozngx3KX3byLTZC4QBH2dFWhf6scrGF ZB980AfCxoD9qbbKDy+rdGIeRSVNyw==
+ """
+
+ Scenario: No data, type DS, in-zone
+ Given I have bind10 running with configuration nsec3/nsec3_auth.config
+ A dnssec query for ai.example. type DS should have rcode NOERROR
+ The last query response should have flags qr aa rd
+ The last query response should have edns_flags do
+ The last query response should have ancount 0
+ The last query response should have nscount 4
+ The last query response should have adcount 1
+ The authority section of the last query response should be
+ """
+ example. 3600 IN SOA ns1.example. bugs.x.w.example. 1 3600 300 3600000 3600
+ example. 3600 IN RRSIG SOA 7 1 3600 20150420235959 20051021000000 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8iq4ZLlYWfUUbbAS41pG+6 8z81q1xhkYAcEyHdVI2LmKusbZsT0Q==
+ gjeqe526plbf1g8mklp59enfd789njgi.example. 3600 IN NSEC3 1 1 12 AABBCCDD JI6NEOAEPV8B5O6K4EV33ABHA8HT9FGC A HINFO AAAA RRSIG
+ gjeqe526plbf1g8mklp59enfd789njgi.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. IVnezTJ9iqblFF97vPSmfXZ5Zozngx3KX3byLTZC4QBH2dFWhf6scrGF ZB980AfCxoD9qbbKDy+rdGIeRSVNyw==
+ """
+
+ Scenario: No data, type DS, optout delegation
+ Given I have bind10 running with configuration nsec3/nsec3_auth.config
+ A dnssec query for c.example. type DS should have rcode NOERROR
+ The last query response should have flags qr aa rd
+ The last query response should have edns_flags do
+ The last query response should have ancount 0
+ The last query response should have nscount 6
+ The last query response should have adcount 1
+ The authority section of the last query response should be
+ """
+ example. 3600 IN SOA ns1.example. bugs.x.w.example. 1 3600 300 3600000 3600
+ example. 3600 IN RRSIG SOA 7 1 3600 20150420235959 20051021000000 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8iq4ZLlYWfUUbbAS41pG+6 8z81q1xhkYAcEyHdVI2LmKusbZsT0Q==
+ 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. 3600 IN NSEC3 1 1 12 AABBCCDD 2T7B4G4VSA5SMI47K61MV5BV1A22BOJR NS SOA MX RRSIG DNSKEY NSEC3PARAM
+ 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKLIBHYH6blRxK9rC0bMJPw Q4mLIuw85H2EY762BOCXJZMnpuwhpA==
+ 35mthgpgcu1qg68fab165klnsnk3dpvl.example. 3600 IN NSEC3 1 1 12 AABBCCDD B4UM86EGHHDS6NEA196SMVMLO4ORS995 NS DS RRSIG
+ 35mthgpgcu1qg68fab165klnsnk3dpvl.example. 3600 IN RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQAynzo8EUWH+z6hEIBlUT PGj15eZll6VhQqgZXtAIR3chwgW+SA==
+ """
diff --git a/tests/lettuce/features/terrain/bind10_control.py b/tests/lettuce/features/terrain/bind10_control.py
index 7ccd2b3..b2a367c 100644
--- a/tests/lettuce/features/terrain/bind10_control.py
+++ b/tests/lettuce/features/terrain/bind10_control.py
@@ -16,6 +16,7 @@
from lettuce import *
import subprocess
import re
+import json
@step('start bind10(?: with configuration (\S+))?' +\
'(?: with cmdctl port (\d+))?' +\
@@ -167,6 +168,83 @@ def check_bindctl_output(step, stderr, notv, string):
"' was found in bindctl output:\n" +\
output
+def parse_bindctl_output_as_data_structure():
+ """Helper function for data-related command tests: evaluates the
+ last output of bindctl as a data structure that can then be
+ inspected.
+ If the bindctl output is not valid (json) data, this call will
+ fail with an assertion failure.
+ If it is valid, it is parsed and returned as whatever data
+ structure it represented.
+ """
+ # strip any extra output after a charater that commonly terminates a valid
+ # JSON expression, i.e., ']', '}' and '"'. (The extra output would
+ # contain 'Exit from bindctl' message, and depending on environment some
+ # other control-like characters...but why is this message even there?)
+ # Note that this filter is not perfect. For example, it cannot recognize
+ # a simple expression of true/false/null.
+ output = re.sub("(.*)([^]}\"]*$)", r"\1", world.last_bindctl_stdout)
+ try:
+ return json.loads(output)
+ except ValueError as ve:
+ assert False, "Last bindctl output does not appear to be a " +\
+ "parseable data structure: '" + output + "': " + str(ve)
+
+def find_process_pid(step, process_name):
+ """Helper function to request the running processes from Boss, and
+ return the pid of the process with the given process_name.
+ Fails with an assert if the response from boss is not valid JSON,
+ or if the process with the given name is not found.
+ """
+ # show_processes output is a list of lists, where the inner lists
+ # are of the form [ pid, "name" ]
+ # Not checking data form; errors will show anyway (if these turn
+ # out to be too vague, we can change this)
+ step.given('send bind10 the command Boss show_processes')
+ running_processes = parse_bindctl_output_as_data_structure()
+
+ for process in running_processes:
+ if process[1] == process_name:
+ return process[0]
+ assert False, "Process named " + process_name +\
+ " not found in output of Boss show_processes";
+
+ at step("remember the pid of process ([\S]+)")
+def remember_pid(step, process_name):
+ """Stores the PID of the process with the given name as returned by
+ Boss show_processes command.
+ Fails if the process with the given name does not appear to exist.
+ Stores the component_name->pid value in the dict world.process_pids.
+ This should only be used by the related step
+ 'the pid of process <name> should (not) have changed'
+ Arguments:
+ process name ('process <name>') the name of the component to store
+ the pid of.
+ """
+ if world.process_pids is None:
+ world.process_pids = {}
+ world.process_pids[process_name] = find_process_pid(step, process_name)
+
+ at step('pid of process ([\S]+) should not have changed')
+def check_pid(step, process_name):
+ """Checks the PID of the process with the given name as returned by
+ Boss show_processes command.
+ Fails if the process with the given name does not appear to exist.
+ Fails if the process with the given name exists, but has a different
+ pid than it had when the step 'remember the pid of process' was
+ called.
+ Fails if that step has not been called (since world.process_pids
+ does not exist).
+ """
+ assert world.process_pids is not None, "No process pids stored"
+ assert process_name in world.process_pids, "Process named " +\
+ process_name +\
+ " was not stored"
+ pid = find_process_pid(step, process_name)
+ assert world.process_pids[process_name] == pid,\
+ "Expected pid: " + str(world.process_pids[process_name]) +\
+ " Got pid: " + str(pid)
+
@step('set bind10 configuration (\S+) to (.*)(?: with cmdctl port (\d+))?')
def config_set_command(step, name, value, cmdctl_port):
"""
@@ -183,6 +261,20 @@ def config_set_command(step, name, value, cmdctl_port):
"quit"]
run_bindctl(commands, cmdctl_port)
+ at step('send bind10 the following commands(?: with cmdctl port (\d+))?')
+def send_multiple_commands(step, cmdctl_port):
+ """
+ Run bindctl, and send it the given multiline set of commands.
+ A quit command is always appended.
+ cmdctl_port ('with cmdctl port <portnr>', optional): cmdctl port to send
+ the command to. Defaults to 47805.
+ Fails if cmdctl does not exit with status code 0.
+ """
+ commands = step.multiline.split("\n")
+ # Always add quit
+ commands.append("quit")
+ run_bindctl(commands, cmdctl_port)
+
@step('remove bind10 configuration (\S+)(?: value (\S+))?(?: with cmdctl port (\d+))?')
def config_remove_command(step, name, value, cmdctl_port):
"""
diff --git a/tests/lettuce/features/terrain/querying.py b/tests/lettuce/features/terrain/querying.py
index 51c158e..c070dd2 100644
--- a/tests/lettuce/features/terrain/querying.py
+++ b/tests/lettuce/features/terrain/querying.py
@@ -41,9 +41,10 @@ import re
#
# The following attributes are 'parsed' from the response, all as strings,
# and end up as direct attributes of the QueryResult object:
-# opcode, rcode, id, flags, qdcount, ancount, nscount, adcount
-# (flags is one string with all flags, in the order they appear in the
-# response packet.)
+# opcode, rcode, id, flags, qdcount, ancount, nscount, adcount,
+# edns_version, edns_flags, and edns_udp_size
+# (flags and edns_flags are both one string with all flags, in the order
+# in which they appear in the response message.)
#
# this will set 'rcode' as the result code, we 'define' one additional
# rcode, "NO_ANSWER", if the dig process returned an error code itself
@@ -55,10 +56,12 @@ import re
# See server_from_sqlite3.feature for various examples to perform queries
class QueryResult(object):
status_re = re.compile("opcode: ([A-Z])+, status: ([A-Z]+), id: ([0-9]+)")
+ edns_re = re.compile("; EDNS: version: ([0-9]+), flags: ([a-z ]*); udp: ([0-9]+)")
flags_re = re.compile("flags: ([a-z ]+); QUERY: ([0-9]+), ANSWER: " +
"([0-9]+), AUTHORITY: ([0-9]+), ADDITIONAL: ([0-9]+)")
- def __init__(self, name, qtype, qclass, address, port):
+ def __init__(self, name, qtype, qclass, address, port,
+ additional_args=None):
"""
Constructor. This fires of a query using dig.
Parameters:
@@ -67,6 +70,7 @@ class QueryResult(object):
qclass: The RR class to query. Defaults to IN if it is None.
address: The IP adress to send the query to.
port: The port number to send the query to.
+ additional_args: List of additional arguments (e.g. '+dnssec').
All parameters must be either strings or have the correct string
representation.
Only one query attempt will be made.
@@ -78,6 +82,8 @@ class QueryResult(object):
if qclass is not None:
args.append('-c')
args.append(str(qclass))
+ if additional_args is not None:
+ args.extend(additional_args)
args.append(name)
dig_process = subprocess.Popen(args, 1, None, None, subprocess.PIPE,
None)
@@ -102,6 +108,8 @@ class QueryResult(object):
"""
if line == ";; ANSWER SECTION:\n":
self.line_handler = self.parse_answer
+ elif line == ";; OPT PSEUDOSECTION:\n":
+ self.line_handler = self.parse_opt
elif line == ";; AUTHORITY SECTION:\n":
self.line_handler = self.parse_authority
elif line == ";; ADDITIONAL SECTION:\n":
@@ -131,6 +139,19 @@ class QueryResult(object):
self.nscount = flags_match.group(4)
self.adcount = flags_match.group(5)
+ def parse_opt(self, line):
+ """
+ Parse the header lines of the query response.
+ Parameters:
+ line: The current line of the response.
+ """
+ if not self._check_next_header(line):
+ edns_match = self.edns_re.search(line)
+ if edns_match is not None:
+ self.edns_version = edns_match.group(1)
+ self.edns_flags = edns_match.group(2)
+ self.edns_udp_size = edns_match.group(3)
+
def parse_question(self, line):
"""
Parse the question section lines of the query response.
@@ -179,9 +200,10 @@ class QueryResult(object):
"""
pass
- at step('A query for ([\w.-]+) (?:type ([A-Z0-9]+) )?(?:class ([A-Z]+) )?' +
- '(?:to ([^:]+)(?::([0-9]+))? )?should have rcode ([\w.]+)')
-def query(step, query_name, qtype, qclass, addr, port, rcode):
+ at step('A (dnssec )?query for ([\S]+) (?:type ([A-Z0-9]+) )?' +
+ '(?:class ([A-Z]+) )?(?:to ([^:]+)(?::([0-9]+))? )?' +
+ 'should have rcode ([\w.]+)')
+def query(step, dnssec, query_name, qtype, qclass, addr, port, rcode):
"""
Run a query, check the rcode of the response, and store the query
result in world.last_query_result.
@@ -203,7 +225,11 @@ def query(step, query_name, qtype, qclass, addr, port, rcode):
addr = "127.0.0.1"
if port is None:
port = 47806
- query_result = QueryResult(query_name, qtype, qclass, addr, port)
+ additional_arguments = []
+ if dnssec is not None:
+ additional_arguments.append("+dnssec")
+ query_result = QueryResult(query_name, qtype, qclass, addr, port,
+ additional_arguments)
assert query_result.rcode == rcode,\
"Expected: " + rcode + ", got " + query_result.rcode
world.last_query_result = query_result
@@ -255,9 +281,15 @@ def check_last_query_section(step, section):
section ('<section> section'): The name of the section (QUESTION, ANSWER,
AUTHORITY or ADDITIONAL).
The expected response is taken from the multiline part of the step in the
- scenario. Differing whitespace is ignored, but currently the order is
- significant.
+ scenario. Differing whitespace is ignored, the order of the lines is
+ ignored, and the comparison is case insensitive.
Fails if they do not match.
+ WARNING: Case insensitivity is not strictly correct; for instance the
+ data of TXT RRs would be case sensitive. But most other output is, so
+ currently the checks are always case insensitive. Should we decide
+ these checks do need to be case sensitive, we can either remove it
+ or make it optional (for the former, we'll need to update a number of
+ tests).
"""
response_string = None
if section.lower() == 'question':
@@ -265,15 +297,32 @@ def check_last_query_section(step, section):
elif section.lower() == 'answer':
response_string = "\n".join(world.last_query_result.answer_section)
elif section.lower() == 'authority':
- response_string = "\n".join(world.last_query_result.answer_section)
+ response_string = "\n".join(world.last_query_result.authority_section)
elif section.lower() == 'additional':
- response_string = "\n".join(world.last_query_result.answer_section)
+ response_string = "\n".join(world.last_query_result.additional_section)
else:
assert False, "Unknown section " + section
+
+ # Now mangle the data for 'conformance'
+ # This could be done more efficiently, but is done one
+ # by one on a copy of the original data, so it is clear
+ # what is done. Final error output is currently still the
+ # original unchanged multiline strings
+
# replace whitespace of any length by one space
response_string = re.sub("[ \t]+", " ", response_string)
expect = re.sub("[ \t]+", " ", step.multiline)
+ # lowercase them
+ response_string = response_string.lower()
+ expect = expect.lower()
+ # sort them
+ response_string_parts = response_string.split("\n")
+ response_string_parts.sort()
+ response_string = "\n".join(response_string_parts)
+ expect_parts = expect.split("\n")
+ expect_parts.sort()
+ expect = "\n".join(expect_parts)
+
assert response_string.strip() == expect.strip(),\
"Got:\n'" + response_string + "'\nExpected:\n'" + step.multiline +"'"
-
-
+
diff --git a/tests/lettuce/features/terrain/terrain.py b/tests/lettuce/features/terrain/terrain.py
index 90531a1..2bfddd6 100644
--- a/tests/lettuce/features/terrain/terrain.py
+++ b/tests/lettuce/features/terrain/terrain.py
@@ -45,7 +45,9 @@ copylist = [
["configurations/example.org.config.orig",
"configurations/example.org.config"],
["configurations/resolver/resolver_basic.config.orig",
- "configurations/resolver/resolver_basic.config"]
+ "configurations/resolver/resolver_basic.config"],
+ ["configurations/multi_instance/multi_auth.config.orig",
+ "configurations/multi_instance/multi_auth.config"]
]
# This is a list of files that, if present, will be removed before a scenario
@@ -343,6 +345,10 @@ def initialize(scenario):
# Convenience variable to access the last query result from querying.py
world.last_query_result = None
+ # For slightly better errors, initialize a process_pids for the relevant
+ # steps
+ world.process_pids = None
+
# Some tests can modify the settings. If the tests fail half-way, or
# don't clean up, this can leave configurations or data in a bad state,
# so we copy them from originals before each scenario
diff --git a/tests/system/bindctl/nsx1/b10-config.db.template.in b/tests/system/bindctl/nsx1/b10-config.db.template.in
index 162329a..7a3647c 100644
--- a/tests/system/bindctl/nsx1/b10-config.db.template.in
+++ b/tests/system/bindctl/nsx1/b10-config.db.template.in
@@ -3,8 +3,5 @@
"listen_on": [{"address": "10.53.0.1", "port": 53210}],
"database_file": "@abs_builddir@/zone.sqlite3",
"statistics-interval": 1
- },
- "Xfrout": {
- "log_file": "@abs_builddir@/Xfrout.log"
}
}
diff --git a/tests/system/glue/nsx1/b10-config.db.in b/tests/system/glue/nsx1/b10-config.db.in
index acd040c..0d5a324 100644
--- a/tests/system/glue/nsx1/b10-config.db.in
+++ b/tests/system/glue/nsx1/b10-config.db.in
@@ -2,8 +2,5 @@
"Auth": {
"listen_on": [{"address": "10.53.0.1", "port": 53210}],
"database_file": "@abs_builddir@/zone.sqlite3"
- },
- "Xfrout": {
- "log_file": "@abs_builddir@/Xfrout.log"
}
}
diff --git a/tests/tools/badpacket/scan.cc b/tests/tools/badpacket/scan.cc
index a6e7229..1559a1f 100644
--- a/tests/tools/badpacket/scan.cc
+++ b/tests/tools/badpacket/scan.cc
@@ -61,7 +61,8 @@ Scan::scan(const CommandOptions& options) {
RRType::A()));
OutputBufferPtr msgbuf(new OutputBuffer(512));
- MessageRenderer renderer(*msgbuf);
+ MessageRenderer renderer;
+ renderer.setBuffer(msgbuf.get());
message.toWire(renderer);
iterateFlagsStart(msgbuf, options);
More information about the bind10-changes
mailing list