BIND 10 trac749, updated. fe0c557fa06274df7610c0d07a6c6bb827a5cd3f [trac749] Merge 'master' into trac749
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Apr 19 16:34:22 UTC 2011
The branch, trac749 has been updated
via fe0c557fa06274df7610c0d07a6c6bb827a5cd3f (commit)
via 6ffefafd958806769b56e1e5972eab62b87a1135 (commit)
via 54cc81d718e60a3e095fecefe502cdca9dad1776 (commit)
via 1b666838b6c0fe265522b30971e878d9f0d21fde (commit)
via 20607bda887846e2745bac1d275c51874885f917 (commit)
via 17106327efdf114e15b21cf8079f9191ab073648 (commit)
via 921ca1236dbf64fa1f73a03a6903b5a2fa82f84d (commit)
via 06c4fa64bb59638af953e9b3961d23e173eab49f (commit)
via 3b42967a83f4e15e1b1d07a159a600cb67628039 (commit)
via 262ac6c6fc61224d54705ed4c700dadb606fcb1c (commit)
via 8eb32c279693c55b444cbacaa835c9d04ee3f242 (commit)
via 66c4f9e1df9c4c00d117323d016cca1c16c13e01 (commit)
via 3c348815b0ddc70deed6e5ffcdb3b6828edae961 (commit)
via 75080dc8f887cad817ed9b1d20db97461704d1cf (commit)
via 2c8303354db6a7d41b4c2e90181b5fcd5db40aee (commit)
via 96b5b4c186fffb2a52891209bd8c95e92e45573e (commit)
via 6f91ee90cd428b0e7eecd4cb99eefc0201f4360e (commit)
via f19053d9083026ad651b574f276313f5f2bd8dc6 (commit)
via bc88971bdb67728a22d029504bf18e778af26591 (commit)
via 047cdc39aa335b778d4ba9ecdacbd859d612807c (commit)
via 7bc6ee513da806b25cab12a32465122f33232128 (commit)
via 3999bb246ea782310611471d3ff28cdd85bf4a0d (commit)
via 10b62db1ae170eed2fb897335037d50c399b37e9 (commit)
via f155c3edec68515cccb5f5c4da611af08770ae4e (commit)
via 4e9bf13057eba0ccff7052f1859ab49b0a27c777 (commit)
via c20ca2440575e5cfc9d4a3dd582c9f56776452d6 (commit)
via e23c4b1e90ba1127a5b7eaef4add6f3b68fbc6fa (commit)
via a83e29a881af14dc61b366024e25f5ca68244220 (commit)
via bf0a9b3576da038ee53bd49360fe3bd8b01189fd (commit)
via 4e47d5f6b692c63c907af6681a75024450884a88 (commit)
via 0eacaf1a394d3674ca73c6531aca60dd952e0e3b (commit)
via ad04d070072126a8f221f67244e9a54e68b53955 (commit)
via fb99e325e667a39ef88b6c8fab128a8df862a786 (commit)
via 31b96198427b2c140556afcd61ff3809c43266f6 (commit)
via 0a2a239a12af8c0ee54d62cb34d170c6cfdd33f9 (commit)
via 0e519f4da5ef99475c3bf5941ed1ea553a7c9a6e (commit)
via 1e3b465d617d7e7dc9c9ac2427e37a1b837369d9 (commit)
via 429ade576746b5c5e1d9113ae57ee863276809b1 (commit)
via 25fe349f4fb12f444c06fdc2117a4f62f1dda2f7 (commit)
via fcc5a1f450a3a0125e999a8bc9e1d26f207a8153 (commit)
via 71d23aa4207048dc78531ce48e35e6a83a6b62ab (commit)
via bcc0502a221ec06331c2825c5e27874626b32cf1 (commit)
via 6555863f88c4e9865baebe0b55db1f7b00b6214c (commit)
via d3dbda9445dcb699e48457e89b90c3be933ec2b9 (commit)
via 6ce4dde0aeb2a0aa3457f0037be5d549b3e9b966 (commit)
via cdf229b32e2138c7d451eead64d7fdc2d69e94b7 (commit)
via c3a18648a3d7f96325a529f87ed5824183fa0ce5 (commit)
via 30872fc580a3cb357bdd34765eaecc1d61820b16 (commit)
via f2de716ada3aa2c0862f3d7d21ef10d28db90219 (commit)
via 95b1c90380f6b12bf29939b7164fce8d5516d443 (commit)
via ca4c3ad8a436b2c5660959d266c82b692271c158 (commit)
via 8fc7cdd216bead2a98f1c98a6b6dc7a8a3bea4f4 (commit)
via a2d07257bc12397054a57d4190cc61419e572278 (commit)
via 2e92b2f8a977a376fa38e3a51c9646ea9e83c4b8 (commit)
via ce281e646be9f0f273229d94ccd75bf7e08d17cf (commit)
via ca268cc4ca8f7505b996fa3076959b5ef3934658 (commit)
via c4d150ae4528f15fe8f05dbc85a1025abc92e78a (commit)
via ad3dfb04a335ed4c65722063bd351be51dae33b4 (commit)
via 5861ae7cb08e698c7a6c6d053b644f04106ed7a3 (commit)
via 778e7b5aa3c55ffc7947454459fd02263725303d (commit)
via bef9fc00a6c4e6c45922848d7f220ed262e83b1f (commit)
via d622e35a3d7b378f79dc4d587156cbfec3befed9 (commit)
via 433ef14c7c54f255b302ff74213a24bdc298f2a0 (commit)
via 5eeba2034481f043369f9a7f3f86ce606653387e (commit)
via 86ab4d3fabd2e551f90603d81ff2bce2368ea7af (commit)
via 865d62e9e58a3acf270f163a75ba713c134d82d2 (commit)
via 8fdbc3e46da7c31b4a533bbfe5778bf7d68e1bbe (commit)
via aac391dda57b88507b8b10ac4bd1b068d3701b2d (commit)
via 7e561fe2f8d44b9224cf107287f79df14584512b (commit)
via 3b6ddc0b213a61abf826d87351d97de9145a3fc4 (commit)
via 28b01ad5bf72472c824a7b8fc4a8dc394e22e462 (commit)
via 745b08afcdce71ca9b50b2d5a7ffe5d4ffa66091 (commit)
via b509cbb77d31e388df68dfe52709d6edef93df3f (commit)
via d12560d1714fb3a07e56b6903141d82d6081148d (commit)
via ba6927dc78e991f8a5c608beee4c9807895914cd (commit)
via 21718d6ffdc3f782ffa1b5960088786da9b77e4e (commit)
via 20f12e8672c45540cd72bb5df44cf21ff3b6732f (commit)
via 583d7973d8f49c061dee13a14c89cf0846f84721 (commit)
via 7b2536d7a654ecb24d98c3c0814c7384230e81df (commit)
via a3f3377467d511fb0e789957a4b7a9105e4fe0d2 (commit)
via e7d0dbd6ba745bab334aef6e747056c33f5edaa8 (commit)
via 7c1e4d5e1e28e556b1d10a8df8d9486971a3f052 (commit)
via 4929dc565823e49c94b1efea1543ba23d9745c9f (commit)
via c7bb38c99c9afa049c7336ea3f827aa41a1b2ea0 (commit)
via 1c269cbdc76f5dc2baeb43387c4d7ccc6dc863d2 (commit)
via 98e93921ae905aefef6646fc8839e3f4a30a37e1 (commit)
via 1ec7e1ccd24b25501902e0fc29fddf400f2ebdb1 (commit)
via 47b51ddc032a458b42454c3ed774bf26ef4254c1 (commit)
via c139d4bf6b30d7ad9325c7a621911c9455826f6b (commit)
via d8c55247d888cd9f5e2e474e49f8bd97b96623cf (commit)
via ba876505740d4782b58169848605af49325b11ed (commit)
via 4d505b0cef54209575173d52e4f9a3e6e244dab3 (commit)
via 6c611b5c04a5484df7269a603be4f00c4f7fa7f2 (commit)
via 0355bddc92f6df66ef50b920edd6ec3b27920d61 (commit)
via 62a61edffac3ebdd91fec693fe2c1a94785ddb25 (commit)
via 68b9571be6f2370798951b05968d07688e96d56d (commit)
via dec73bbd6dedb0068efe90ee8d77c020778b38db (commit)
via 6ff2a83cb7a6c04a258e84818257fe6eda9634a6 (commit)
via 682ea37cfb7e20366521fd48fc98826a21344942 (commit)
via e1e592789ebc8806b9a8767af95c41c1ec2d5a14 (commit)
via 4f42307f123f7ed147b537430e0f2e9a1c665e8e (commit)
via afa5624c2c3503df1f152f82278f1b9dba19b533 (commit)
via 88c0d241fe05e5ea91b10f046f307177cc2f5bc5 (commit)
via 3ceeab28d48c23ac561a2ed75a57a8f4aa153858 (commit)
via 888bcbc103826ce8de73b29c3e8bf48d5925fe27 (commit)
via 8d3f576ca98cdd6e821cf76464cd342d42d941a3 (commit)
via 13668e95ca6bbb07128babb14f1772bfefcb09a8 (commit)
via eddf905784249ab6949e6186f2676f9d627b089c (commit)
via b4111d2495797a6a9738df6dda3b9db696c5388b (commit)
via 4a484575725500dd766516377eda41daaa17f402 (commit)
via ddfc6892916bc041e53b79a690abbed10ff99056 (commit)
via af0d35e501aab417b9b032069ae1cb8841debab4 (commit)
via cf5b24f110a927685226e8ef41378a847b002357 (commit)
via 5a7c1928eb5b70c2a9739650961bd4e32b6b26ed (commit)
via 238735e15837b8dcb878bbdb627ea4b61682db60 (commit)
via f9a697ab99914d58e7e135ca069b3d5a06c00511 (commit)
via d6c0273c617498a8bee3a813e013837e7c16b7e6 (commit)
via 99fdcbeaa5ea2a5432fc47f39c5ed40f4850b843 (commit)
via a263e7d8bc90224bb6acf8b096d6ce8c87c8647a (commit)
via 320bafb306878cd9f13ba9703a0d4573fb645341 (commit)
via 0b53561c3b937c5d2585a3c62876b600800815bb (commit)
via e111d142cba584e410c5e385c10b714715f55dc4 (commit)
via ac453e66538072059954b8ca3e3d53bfc7c8cef3 (commit)
via 3cc446d3ed8a1b6c899ee19faeda2c41a4b5bdb2 (commit)
via 3e6c2a9c09722a48fe3e6c8a1ee35724a9397360 (commit)
via de3c708f962db8fe15287c9a5704d3aa8b257b03 (commit)
via 9b90408108142c710c2adb403e61af374fe1b24c (commit)
via 00cb2ff77044b185fe80dcf3f577a9b4793638b0 (commit)
via 00b37501ae500c81657b1727dfff0105c2202f07 (commit)
via 7b794844b6afc77cf05bb93828477fe5cc48408d (commit)
via 75b29aaa4aabf843b0d80400eb2cf8c39c4dd8f0 (commit)
via d27da40718b797aca37ad5bab7215592a089627a (commit)
via 7362cbdfc230a2f8deee2933b78e23bdb4892e98 (commit)
via 48846bf7b70cc48e317aabc554a4dacef89b2d46 (commit)
via 501462d7b9850ddca6a3d0a2c7043e3fa0923759 (commit)
via 044c080dd3fc084f3ee7dcdcc70c8dc328bee9df (commit)
via 1cd8ba5e307c77ae9bc2563569366c43623bbc75 (commit)
via 8599f0c0c2ebe7043dd65458a2302837f7c43895 (commit)
via 902005dceae646aefc03c2005e1ff2896efb909c (commit)
via fa743a8d8303433152e7c93bfc8aca1a2aa9cf0e (commit)
via 4434d7bef7a127ad8fb7e9dc6a43c9bd9e6601d1 (commit)
via c7a0fffa73e28d0d28b3706a9bc6b6e1ed9d2a7b (commit)
via 344410fec60755f6b5cb2348ec9e7b67068f31ae (commit)
via e88330e1dbfed90776b634513372f71caa96ac5f (commit)
via 6f9b0595718f8f7fd5324a6252207d29c40836b2 (commit)
via d11a387719a4ea69946801e4c865323f4b9016a3 (commit)
via 88d4219ba95fa853b07c3397aeb4c2e6567e50c0 (commit)
via 8da3cbf0ec4fcd563b8e779038a38811a77dece8 (commit)
via 66bb0f76db68b8f96fc4ac819f9c07c7f8a404e6 (commit)
via 26b876a067e285be526793254f9422067a89e071 (commit)
via be4ec3ec23084ca94e72a60ddb1a2d4250ade5cd (commit)
via d58451bac9dd51a562a24032d013e1eacc5a3fde (commit)
via 6b09fa3b6e19b73f82940664802158baaca0297d (commit)
via 1f7ffbad521f059f611876c27d8373f355ca8c40 (commit)
via 0add6c7b1047219eda3f1d7fa13340da61cd96b5 (commit)
via 3b1fef1e85522e061114beb6bd9013a51da16c08 (commit)
via 3772748aa192829099877ac1c1e43e43b691df16 (commit)
via 7dab055fe9854655b43338485ec8a960dea94080 (commit)
via 78533f09dbf43b91578392dc8cee6700b3db7d2b (commit)
via 5d8d976fe843af90f06dc9ff48408e96a51a0316 (commit)
from 1eb73e619aae14a927a7970cc4cdd2a7fb1d362a (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 -----------------------------------------------------------------
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 516 +-
configure.ac | 15 +-
doc/Doxyfile | 6 +-
src/bin/Makefile.am | 2 +-
src/bin/auth/Makefile.am | 5 +-
src/bin/auth/auth_config.cc | 347 +
src/bin/auth/{config.h => auth_config.h} | 0
src/bin/auth/auth_srv.cc | 7 +-
src/bin/auth/auth_srv.h | 31 +-
src/bin/auth/benchmarks/Makefile.am | 3 +-
src/bin/auth/benchmarks/query_bench.cc | 8 +-
src/bin/auth/common.cc | 36 +
src/bin/auth/common.h | 11 +-
src/bin/auth/config.cc | 347 -
src/bin/auth/main.cc | 24 +-
src/bin/auth/tests/Makefile.am | 9 +-
src/bin/auth/tests/auth_srv_unittest.cc | 3 +-
src/bin/auth/tests/command_unittest.cc | 6 +-
src/bin/auth/tests/common_unittest.cc | 96 +
src/bin/auth/tests/config_unittest.cc | 5 +-
src/bin/bind10/bind10.8 | 41 +-
src/bin/bind10/bind10.py.in | 40 +-
src/bin/bind10/bind10.xml | 59 +-
src/bin/bind10/bob.spec | 5 +
src/bin/bind10/tests/Makefile.am | 3 +-
src/bin/bind10/tests/bind10_test.py.in | 88 +-
src/bin/resolver/Makefile.am | 3 +
src/bin/resolver/main.cc | 6 +-
src/bin/resolver/resolver.cc | 8 +-
src/bin/resolver/resolver.h | 42 +-
src/bin/resolver/response_scrubber.cc | 2 +-
src/bin/resolver/response_scrubber.h | 4 +-
src/bin/resolver/tests/Makefile.am | 1 +
src/bin/resolver/tests/resolver_config_unittest.cc | 6 +-
.../resolver/tests/response_scrubber_unittest.cc | 4 +-
src/bin/sockcreator/Makefile.am | 18 +
src/bin/sockcreator/README | 49 +
src/bin/sockcreator/main.cc | 26 +
src/bin/sockcreator/sockcreator.cc | 151 +
src/bin/sockcreator/sockcreator.h | 100 +
src/bin/sockcreator/tests/Makefile.am | 25 +
src/bin/sockcreator/tests/run_unittests.cc | 22 +
src/bin/sockcreator/tests/sockcreator_tests.cc | 273 +
src/bin/stats/b10-stats.8 | 19 +-
src/bin/stats/b10-stats.xml | 6 +-
src/bin/stats/stats.py.in | 12 +-
src/bin/stats/tests/b10-stats_test.py | 11 +-
src/bin/xfrout/tests/Makefile.am | 4 +-
src/bin/xfrout/tests/xfrout_test.py | 437 --
src/bin/xfrout/tests/xfrout_test.py.in | 469 ++
src/bin/xfrout/xfrout.py.in | 41 +-
src/bin/zonemgr/tests/zonemgr_test.py | 132 +-
src/bin/zonemgr/zonemgr.py.in | 72 +-
src/bin/zonemgr/zonemgr.spec.pre.in | 26 +
src/lib/Makefile.am | 4 +-
src/lib/asiodns/Makefile.am | 34 +
src/lib/asiodns/README | 157 +
src/lib/asiodns/asiodef.cc | 39 +
src/lib/asiodns/asiodef.h | 23 +
src/lib/asiodns/asiodef.msg | 56 +
src/lib/asiodns/asiodns.h | 23 +
src/lib/asiodns/dns_answer.h | 77 +
src/lib/asiodns/dns_lookup.h | 85 +
src/lib/asiodns/dns_server.h | 157 +
src/lib/asiodns/dns_service.cc | 201 +
src/lib/asiodns/dns_service.h | 114 +
src/lib/asiodns/io_fetch.cc | 407 ++
src/lib/asiodns/io_fetch.h | 204 +
src/lib/asiodns/tcp_server.cc | 244 +
src/lib/asiodns/tcp_server.h | 124 +
src/lib/asiodns/tests/Makefile.am | 50 +
src/lib/asiodns/tests/dns_server_unittest.cc | 503 ++
src/lib/asiodns/tests/io_fetch_unittest.cc | 728 +++
src/lib/asiodns/tests/io_service_unittest.cc | 118 +
.../{asiolink => asiodns}/tests/run_unittests.cc | 0
src/lib/asiodns/udp_server.cc | 325 +
src/lib/asiodns/udp_server.h | 108 +
src/lib/asiolink/Makefile.am | 10 -
src/lib/asiolink/README | 160 -
src/lib/asiolink/asiodef.cc | 37 -
src/lib/asiolink/asiodef.h | 21 -
src/lib/asiolink/asiodef.msg | 56 -
src/lib/asiolink/asiolink.h | 9 -
src/lib/asiolink/dns_answer.h | 73 -
src/lib/asiolink/dns_lookup.h | 83 -
src/lib/asiolink/dns_server.h | 155 -
src/lib/asiolink/dns_service.cc | 200 -
src/lib/asiolink/dns_service.h | 112 -
src/lib/asiolink/dummy_io_cb.h | 2 +
src/lib/asiolink/interval_timer.cc | 4 +-
src/lib/asiolink/interval_timer.h | 4 +-
src/lib/asiolink/io_address.cc | 4 +-
src/lib/asiolink/io_address.h | 4 +-
src/lib/asiolink/io_asio_socket.h | 3 +-
src/lib/asiolink/io_endpoint.cc | 4 +-
src/lib/asiolink/io_endpoint.h | 4 +-
src/lib/asiolink/io_error.h | 4 +-
src/lib/asiolink/io_fetch.cc | 381 --
src/lib/asiolink/io_fetch.h | 179 -
src/lib/asiolink/io_message.h | 4 +-
src/lib/asiolink/io_service.cc | 4 +-
src/lib/asiolink/io_service.h | 4 +-
src/lib/asiolink/io_socket.cc | 6 +-
src/lib/asiolink/io_socket.h | 2 +
src/lib/asiolink/simple_callback.h | 4 +-
src/lib/asiolink/tcp_endpoint.h | 4 +-
src/lib/asiolink/tcp_server.cc | 242 -
src/lib/asiolink/tcp_server.h | 120 -
src/lib/asiolink/tcp_socket.h | 2 +
src/lib/asiolink/tests/Makefile.am | 3 -
src/lib/asiolink/tests/dns_server_unittest.cc | 502 --
src/lib/asiolink/tests/interval_timer_unittest.cc | 2 +-
src/lib/asiolink/tests/io_address_unittest.cc | 2 +-
src/lib/asiolink/tests/io_endpoint_unittest.cc | 2 +-
src/lib/asiolink/tests/io_fetch_unittest.cc | 725 ---
src/lib/asiolink/tests/io_service_unittest.cc | 116 -
src/lib/asiolink/tests/io_socket_unittest.cc | 2 +-
src/lib/asiolink/tests/tcp_endpoint_unittest.cc | 2 +-
src/lib/asiolink/tests/tcp_socket_unittest.cc | 2 +-
src/lib/asiolink/tests/udp_endpoint_unittest.cc | 2 +-
src/lib/asiolink/tests/udp_socket_unittest.cc | 2 +-
src/lib/asiolink/udp_endpoint.h | 4 +-
src/lib/asiolink/udp_server.cc | 322 -
src/lib/asiolink/udp_server.h | 106 -
src/lib/asiolink/udp_socket.h | 2 +
src/lib/datasrc/tests/rbtree_unittest.cc | 2 +-
src/lib/dns/Makefile.am | 1 +
src/lib/dns/python/edns_python.cc | 11 +-
src/lib/dns/python/message_python.cc | 35 +-
src/lib/dns/python/messagerenderer_python.cc | 16 +-
src/lib/dns/python/name_python.cc | 54 +-
src/lib/dns/python/question_python.cc | 2 +-
src/lib/dns/python/rcode_python.cc | 10 +-
src/lib/dns/python/rrclass_python.cc | 11 +-
src/lib/dns/python/rrttl_python.cc | 8 +-
src/lib/dns/python/rrtype_python.cc | 12 +-
src/lib/dns/python/tests/edns_python_test.py | 13 +-
src/lib/dns/python/tests/message_python_test.py | 28 +-
.../python/tests/messagerenderer_python_test.py | 5 +
src/lib/dns/python/tests/name_python_test.py | 19 +-
src/lib/dns/python/tests/question_python_test.py | 2 +-
src/lib/dns/python/tests/rcode_python_test.py | 19 +-
src/lib/dns/python/tests/rrclass_python_test.py | 9 +-
src/lib/dns/python/tests/rrttl_python_test.py | 10 +-
src/lib/dns/python/tests/rrtype_python_test.py | 16 +-
src/lib/dns/rdata.cc | 3 +-
src/lib/dns/rdata.h | 11 +
src/lib/dns/rdata/generic/rp_17.cc | 125 +
src/lib/dns/rdata/generic/rp_17.h | 88 +
src/lib/dns/rdata/template.cc | 2 +-
src/lib/dns/rdata/template.h | 2 +-
src/lib/dns/tests/Makefile.am | 3 +-
src/lib/dns/tests/rdata_rp_unittest.cc | 163 +
src/lib/dns/tests/testdata/Makefile.am | 8 +
src/lib/dns/tests/testdata/gen-wiredata.py.in | 35 +-
src/lib/dns/tests/testdata/rdata_rp_fromWire1.spec | 6 +
src/lib/dns/tests/testdata/rdata_rp_fromWire2.spec | 12 +
src/lib/dns/tests/testdata/rdata_rp_fromWire3.spec | 7 +
src/lib/dns/tests/testdata/rdata_rp_fromWire4.spec | 7 +
src/lib/dns/tests/testdata/rdata_rp_fromWire5.spec | 7 +
src/lib/dns/tests/testdata/rdata_rp_fromWire6.spec | 7 +
src/lib/dns/tests/testdata/rdata_rp_toWire1.spec | 8 +
src/lib/dns/tests/testdata/rdata_rp_toWire2.spec | 14 +
src/lib/nsas/glue_hints.cc | 2 +-
src/lib/nsas/nameserver_entry.cc | 2 +-
src/lib/nsas/tests/address_entry_unittest.cc | 2 +-
src/lib/nsas/tests/nameserver_address_unittest.cc | 4 +-
src/lib/nsas/tests/nameserver_entry_unittest.cc | 2 +-
src/lib/nsas/tests/zone_entry_unittest.cc | 2 +-
src/lib/python/isc/config/ccsession.py | 3 +
src/lib/python/isc/config/config_data.py | 4 +-
src/lib/python/isc/config/tests/ccsession_test.py | 13 +-
.../python/isc/config/tests/config_data_test.py | 4 +-
.../isc/config/tests/unittest_fakesession.py | 9 +-
src/lib/resolve/recursive_query.cc | 44 +-
src/lib/resolve/recursive_query.h | 65 +-
src/lib/resolve/resolver_callback.h | 8 +-
src/lib/resolve/tests/Makefile.am | 1 +
src/lib/resolve/tests/recursive_query_unittest.cc | 7 +-
.../resolve/tests/recursive_query_unittest_2.cc | 29 +-
.../resolve/tests/resolver_callback_unittest.cc | 8 +-
src/lib/server_common/portconfig.cc | 7 +-
src/lib/server_common/portconfig.h | 6 +-
src/lib/server_common/tests/Makefile.am | 3 +-
src/lib/server_common/tests/portconfig_unittest.cc | 4 +-
src/lib/testutils/mockups.h | 4 +-
src/lib/testutils/srv_test.cc | 4 +-
src/lib/util/Makefile.am | 4 +-
src/lib/util/buffer.h | 132 +-
src/lib/util/io/Makefile.am | 18 +
src/lib/util/io/fd.cc | 70 +
src/lib/util/io/fd.h | 61 +
src/lib/util/io/fd_share.cc | 139 +
src/lib/util/io/fd_share.h | 65 +
src/lib/util/io/fdshare_python.cc | 97 +
src/lib/util/io/tests/Makefile.am | 25 +
src/lib/util/io/tests/fd_share_tests.cc | 74 +
src/lib/util/io/tests/fd_tests.cc | 66 +
src/lib/util/io/tests/run_unittests.cc | 22 +
src/lib/util/locks.h | 5 -
src/lib/util/tests/buffer_unittest.cc | 49 +
src/lib/util/unittests/Makefile.am | 9 +
src/lib/util/unittests/README | 5 +
src/lib/util/unittests/fork.cc | 145 +
src/lib/util/unittests/fork.h | 52 +
src/lib/xfr/Makefile.am | 14 +-
src/lib/xfr/fd_share.cc | 137 -
src/lib/xfr/fd_share.h | 42 -
src/lib/xfr/fdshare_python.cc | 84 -
src/lib/xfr/python_xfr.cc | 32 -
src/lib/xfr/xfrout_client.cc | 5 +-
tests/Makefile.am | 2 +-
tests/tools/Makefile.am | 1 +
tests/tools/badpacket/Makefile.am | 28 +
tests/tools/badpacket/README | 53 +
tests/tools/badpacket/badpacket.cc | 62 +
tests/tools/badpacket/command_options.cc | 333 +
tests/tools/badpacket/command_options.h | 162 +
tests/tools/badpacket/header_flags.h | 102 +
tests/tools/badpacket/option_info.cc | 114 +
tests/tools/badpacket/option_info.h | 174 +
tests/tools/badpacket/scan.cc | 310 +
tests/tools/badpacket/scan.h | 198 +
tests/tools/badpacket/tests/Makefile.am | 31 +
.../badpacket/tests/command_options_unittest.cc | 300 +
.../tools/badpacket/tests/header_flags_unittest.cc | 141 +
.../tools/badpacket/tests/option_info_unittest.cc | 161 +
tests/tools/badpacket/tests/run_unittests.cc | 24 +
tests/tools/badpacket/version.h | 26 +
tools/query_cmp/README | 27 +
tools/query_cmp/queries/dquery01 | 394 ++
tools/query_cmp/queries/dquery01_no-type | 316 +
tools/query_cmp/queries/dquery01_non-terminal | 317 +
tools/query_cmp/queries/dquery01_nxdomain | 316 +
tools/query_cmp/src/lib/compare_rrset.py | 285 +
tools/query_cmp/src/lib/handledns.py | 284 +
tools/query_cmp/src/lib/read_query.py | 93 +
tools/query_cmp/src/query_two_server.py | 102 +
tools/query_cmp/zonefile/example.com.txt | 1298 ++++
tools/query_cmp/zonefile/example.com.txt.signed | 6858 ++++++++++++++++++++
240 files changed, 20700 insertions(+), 5352 deletions(-)
create mode 100644 src/bin/auth/auth_config.cc
rename src/bin/auth/{config.h => auth_config.h} (100%)
create mode 100644 src/bin/auth/common.cc
delete mode 100644 src/bin/auth/config.cc
create mode 100644 src/bin/auth/tests/common_unittest.cc
create mode 100644 src/bin/sockcreator/Makefile.am
create mode 100644 src/bin/sockcreator/README
create mode 100644 src/bin/sockcreator/main.cc
create mode 100644 src/bin/sockcreator/sockcreator.cc
create mode 100644 src/bin/sockcreator/sockcreator.h
create mode 100644 src/bin/sockcreator/tests/Makefile.am
create mode 100644 src/bin/sockcreator/tests/run_unittests.cc
create mode 100644 src/bin/sockcreator/tests/sockcreator_tests.cc
delete mode 100644 src/bin/xfrout/tests/xfrout_test.py
create mode 100644 src/bin/xfrout/tests/xfrout_test.py.in
create mode 100644 src/lib/asiodns/Makefile.am
create mode 100644 src/lib/asiodns/README
create mode 100644 src/lib/asiodns/asiodef.cc
create mode 100644 src/lib/asiodns/asiodef.h
create mode 100644 src/lib/asiodns/asiodef.msg
create mode 100644 src/lib/asiodns/asiodns.h
create mode 100644 src/lib/asiodns/dns_answer.h
create mode 100644 src/lib/asiodns/dns_lookup.h
create mode 100644 src/lib/asiodns/dns_server.h
create mode 100644 src/lib/asiodns/dns_service.cc
create mode 100644 src/lib/asiodns/dns_service.h
create mode 100644 src/lib/asiodns/io_fetch.cc
create mode 100644 src/lib/asiodns/io_fetch.h
create mode 100644 src/lib/asiodns/tcp_server.cc
create mode 100644 src/lib/asiodns/tcp_server.h
create mode 100644 src/lib/asiodns/tests/Makefile.am
create mode 100644 src/lib/asiodns/tests/dns_server_unittest.cc
create mode 100644 src/lib/asiodns/tests/io_fetch_unittest.cc
create mode 100644 src/lib/asiodns/tests/io_service_unittest.cc
copy src/lib/{asiolink => asiodns}/tests/run_unittests.cc (100%)
create mode 100644 src/lib/asiodns/udp_server.cc
create mode 100644 src/lib/asiodns/udp_server.h
delete mode 100644 src/lib/asiolink/asiodef.cc
delete mode 100644 src/lib/asiolink/asiodef.h
delete mode 100644 src/lib/asiolink/asiodef.msg
delete mode 100644 src/lib/asiolink/dns_answer.h
delete mode 100644 src/lib/asiolink/dns_lookup.h
delete mode 100644 src/lib/asiolink/dns_server.h
delete mode 100644 src/lib/asiolink/dns_service.cc
delete mode 100644 src/lib/asiolink/dns_service.h
delete mode 100644 src/lib/asiolink/io_fetch.cc
delete mode 100644 src/lib/asiolink/io_fetch.h
delete mode 100644 src/lib/asiolink/tcp_server.cc
delete mode 100644 src/lib/asiolink/tcp_server.h
delete mode 100644 src/lib/asiolink/tests/dns_server_unittest.cc
delete mode 100644 src/lib/asiolink/tests/io_fetch_unittest.cc
delete mode 100644 src/lib/asiolink/tests/io_service_unittest.cc
delete mode 100644 src/lib/asiolink/udp_server.cc
delete mode 100644 src/lib/asiolink/udp_server.h
create mode 100644 src/lib/dns/rdata/generic/rp_17.cc
create mode 100644 src/lib/dns/rdata/generic/rp_17.h
create mode 100644 src/lib/dns/tests/rdata_rp_unittest.cc
create mode 100644 src/lib/dns/tests/testdata/rdata_rp_fromWire1.spec
create mode 100644 src/lib/dns/tests/testdata/rdata_rp_fromWire2.spec
create mode 100644 src/lib/dns/tests/testdata/rdata_rp_fromWire3.spec
create mode 100644 src/lib/dns/tests/testdata/rdata_rp_fromWire4.spec
create mode 100644 src/lib/dns/tests/testdata/rdata_rp_fromWire5.spec
create mode 100644 src/lib/dns/tests/testdata/rdata_rp_fromWire6.spec
create mode 100644 src/lib/dns/tests/testdata/rdata_rp_toWire1.spec
create mode 100644 src/lib/dns/tests/testdata/rdata_rp_toWire2.spec
create mode 100644 src/lib/util/io/Makefile.am
create mode 100644 src/lib/util/io/fd.cc
create mode 100644 src/lib/util/io/fd.h
create mode 100644 src/lib/util/io/fd_share.cc
create mode 100644 src/lib/util/io/fd_share.h
create mode 100644 src/lib/util/io/fdshare_python.cc
create mode 100644 src/lib/util/io/tests/Makefile.am
create mode 100644 src/lib/util/io/tests/fd_share_tests.cc
create mode 100644 src/lib/util/io/tests/fd_tests.cc
create mode 100644 src/lib/util/io/tests/run_unittests.cc
create mode 100644 src/lib/util/unittests/Makefile.am
create mode 100644 src/lib/util/unittests/README
create mode 100644 src/lib/util/unittests/fork.cc
create mode 100644 src/lib/util/unittests/fork.h
delete mode 100644 src/lib/xfr/fd_share.cc
delete mode 100644 src/lib/xfr/fd_share.h
delete mode 100644 src/lib/xfr/fdshare_python.cc
delete mode 100644 src/lib/xfr/python_xfr.cc
create mode 100644 tests/tools/Makefile.am
create mode 100644 tests/tools/badpacket/Makefile.am
create mode 100644 tests/tools/badpacket/README
create mode 100644 tests/tools/badpacket/badpacket.cc
create mode 100644 tests/tools/badpacket/command_options.cc
create mode 100644 tests/tools/badpacket/command_options.h
create mode 100644 tests/tools/badpacket/header_flags.h
create mode 100644 tests/tools/badpacket/option_info.cc
create mode 100644 tests/tools/badpacket/option_info.h
create mode 100644 tests/tools/badpacket/scan.cc
create mode 100644 tests/tools/badpacket/scan.h
create mode 100644 tests/tools/badpacket/tests/Makefile.am
create mode 100644 tests/tools/badpacket/tests/command_options_unittest.cc
create mode 100644 tests/tools/badpacket/tests/header_flags_unittest.cc
create mode 100644 tests/tools/badpacket/tests/option_info_unittest.cc
create mode 100644 tests/tools/badpacket/tests/run_unittests.cc
create mode 100644 tests/tools/badpacket/version.h
create mode 100644 tools/query_cmp/README
create mode 100644 tools/query_cmp/queries/dquery01
create mode 100644 tools/query_cmp/queries/dquery01_no-type
create mode 100644 tools/query_cmp/queries/dquery01_non-terminal
create mode 100644 tools/query_cmp/queries/dquery01_nxdomain
create mode 100755 tools/query_cmp/src/lib/compare_rrset.py
create mode 100755 tools/query_cmp/src/lib/handledns.py
create mode 100755 tools/query_cmp/src/lib/read_query.py
create mode 100755 tools/query_cmp/src/query_two_server.py
create mode 100644 tools/query_cmp/zonefile/example.com.txt
create mode 100644 tools/query_cmp/zonefile/example.com.txt.signed
-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index a85332b..c6b8337 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,70 +1,133 @@
- 210. [bug] jerry
+220. [func] stephen
+ Added the 'badpacket' program for testing; it sends a set of
+ (potentially) bad packets to a nameserver and prints the responses.
+ (Trac #703, git 1b666838b6c0fe265522b30971e878d9f0d21fde)
+
+219. [func] ocean
+ src/lib: move some dns related code out of asiolink library to
+ asiodns library
+ (Trac #751, git 262ac6c6fc61224d54705ed4c700dadb606fcb1c)
+
+218. [func] jinmei
+ src/lib/dns: added support for RP RDATA.
+ (Trac #806, git 4e47d5f6b692c63c907af6681a75024450884a88)
+
+217. [bug] jerry
+ src/lib/dns/python: Use a signed version of larger size of integer and
+ perform more strict range checks with PyArg_ParseTuple() in case of
+ overflows.
+ (Trac #363, git ce281e646be9f0f273229d94ccd75bf7e08d17cf)
+
+216. [func] vorner
+ The BIND10_XFROUT_SOCKET_FILE environment variable can be
+ used to specify which socket should be used for communication
+ between b10-auth and b10-xfrout. Mostly for testing reasons.
+ (Trac #615, git 28b01ad5bf72472c824a7b8fc4a8dc394e22e462)
+
+215. [func] vorner
+ A new process, b10-sockcreator, is added, which will create
+ sockets for the rest of the system. It is the only part
+ which will need to keep the root privileges. However, only
+ the process exists, nothing can talk to it yet.
+ (Trac #366, git b509cbb77d31e388df68dfe52709d6edef93df3f)
+
+214. [func]* vorner
+ Zone manager no longer thinks it is secondary master for
+ all zones in the database. They are listed in
+ Zonemgr/secondary_zones configuration variable (in the form
+ [{"name": "example.com", "class": "IN"}]).
+ (Trac #670, git 7c1e4d5e1e28e556b1d10a8df8d9486971a3f052)
+
+213. [bug] naokikambe
+ Solved incorrect datetime of "bind10.boot_time" and also
+ added a new command "sendstats" for Bob. This command is
+ to send statistics data to the stats daemon immediately.
+ The solved problem is that statistics data doesn't surely
+ reach to the daemon because Bob sent statistics data to
+ the daemon while it is starting. So the daemon invokes the
+ command for Bob after it starts up. This command is also
+ useful for resending statistics data via bindctl manually.
+ (Trac #521, git 1c269cbdc76f5dc2baeb43387c4d7ccc6dc863d2)
+
+212. [bug] naokikambe
+ Fixed that the ModuleCCSession object may group_unsubscribe in the
+ closed CC session in being deleted.
+ (Trac #698, git 0355bddc92f6df66ef50b920edd6ec3b27920d61)
+
+211. [func] shane
+ Implement "--brittle" option, which causes the server to exit
+ if any of BIND 10's processes dies.
+ (Trac #788, git 88c0d241fe05e5ea91b10f046f307177cc2f5bc5)
+
+210. [bug] jerry
src/bin/auth: fixed a bug where type ANY queries don't provide
additional glue records for ANSWER section.
(Trac #699, git 510924ebc57def8085cc0e5413deda990b2abeee)
- 209. [func] jelte
+bind10-devel-20110322 released on March 22, 2011
+
+209. [func] jelte
Resolver now uses the NSAS when looking for a nameserver to
query for any specific zone. This also includes keeping track of
the RTT for that nameserver.
(Trac #495, git 76022a7e9f3ff339f0f9f10049aa85e5784d72c5)
- 208. [bug]* jelte
+208. [bug]* jelte
Resolver now answers REFUSED on queries that are not for class IN.
This includes the various CH TXT queries, which will be added
later.
(git 012f9e78dc611c72ea213f9bd6743172e1a2ca20)
- 207. [func] jelte
+207. [func] jelte
Resolver now starts listening on localhost:53 if no configuration
is set.
(Trac #471, git 1960b5becbba05570b9c7adf5129e64338659f07)
- 206. [func] shane
+206. [func] shane
Add the ability to list the running BIND 10 processes using the
command channel. To try this, use "Boss show_processes".
(Trac #648, git 451bbb67c2b5d544db2f7deca4315165245d2b3b)
- 205. [bug] jinmei
+205. [bug] jinmei
b10-auth, src/lib/datasrc: fixed a bug where b10-auth could return
an empty additional section for delegation even if some glue is
crucial when it fails to find some other glue records in its data
source.
(Trac #646, git 6070acd1c5b2f7a61574eda4035b93b40aab3e2b)
- 204. [bug] jinmei
+204. [bug] jinmei
b10-auth, src/lib/datasrc: class ANY queries were not handled
correctly in the generic data source (mainly for sqlite3). It
could crash b10-auth in the worst case, and could result in
incorrect responses in some other cases.
(Trac #80, git c65637dd41c8d94399bd3e3cee965b694b633339)
- 203. [bug] zhang likun
+203. [bug] zhang likun
Fix resolver cache memory leak: when cache is destructed, rrset
and message entries in it are not destructed properly.
(Trac #643, git aba4c4067da0dc63c97c6356dc3137651755ffce)
- 202. [func] vorner
+202. [func] vorner
It is possible to specify a different directory where we look for
configuration files (by -p) and different configuration file to
use (-c). Also, it is possible to specify the port on which
cmdctl should listen (--cmdctl-port).
(Trac #615, git 5514dd78f2d61a222f3069fc94723ca33fb3200b)
- 201. [bug] jerry
+201. [bug] jerry
src/bin/bindctl: bindctl doesn't show traceback on shutdown.
(Trac #588, git 662e99ef050d98e86614c4443326568a0b5be437)
- 200. [bug] Jelte
+200. [bug] Jelte
Fixed a bug where incoming TCP connections were not closed.
(Trac #589, git 1d88daaa24e8b1ab27f28be876f40a144241e93b)
- 199. [func] ocean
+199. [func] ocean
Cache negative responses (NXDOMAIN/NODATA) from authoritative
server for recursive resolver.
(Trac #493, git f8fb852bc6aef292555063590c361f01cf29e5ca)
- 198. [bug] jinmei
+198. [bug] jinmei
b10-auth, src/lib/datasrc: fixed a bug where hot spot cache failed
to reuse cached SOA for negative responses. Due to this bug
b10-auth returned SERVFAIL when it was expected to return a
@@ -72,42 +135,42 @@
the zone.
(Trac #626, git 721a53160c15e8218f6798309befe940b9597ba0)
- 197. [bug] zhang likun
+197. [bug] zhang likun
Remove expired message and rrset entries when looking up them
in cache, touch or remove the rrset entry in cache properly
when doing lookup or update.
(Trac #661, git 9efbe64fe3ff22bb5fba46de409ae058f199c8a7)
- 196. [bug] jinmei
+196. [bug] jinmei
b10-auth, src/lib/datasrc: the backend of the in-memory data
source could not handle the root name. As a result b10-auth could
not work as a root server when using the in-memory data source.
(Trac #683, git 420ec42bd913fb83da37b26b75faae49c7957c46)
- 195. [func] stephen
+195. [func] stephen
Resolver will now re-try a query over TCP if a response to a UDP
query has the TC bit set.
(Trac #499, git 4c05048ba059b79efeab53498737abe94d37ee07)
- 194. [bug] vorner
+194. [bug] vorner
Solved a 100% CPU usage problem after switching addresses in b10-auth
(and possibly, but unconfirmed, in b10-resolver). It was caused by
repeated reads/accepts on closed socket (the bug was in the code for a
long time, recent changes made it show).
(Trac #657, git e0863720a874d75923ea66adcfbf5b2948efb10a)
- 193. [func]* jreed
+193. [func]* jreed
Listen on the IPv6 (::) and IPv4 (0.0.0.0) wildcard addresses
for b10-auth. This returns to previous behavior prior to
change #184. Document the listen_on configuration in manual.
(Trac #649, git 65a77d8fde64d464c75917a1ab9b6b3f02640ca6)
- 192. [func]* jreed
+192. [func]* jreed
Listen on standard domain port 53 for b10-auth and
b10-resolver.
(Trac #617, #618, git 137a6934a14cf0c5b5c065e910b8b364beb0973f)
- 191. [func] jinmei
+191. [func] jinmei
Imported system test framework of BIND 9. It can be run by
'make systest' at the top source directory. Notes: currently it
doesn't work when built in a separate tree. It also requires
@@ -117,51 +180,51 @@
to the specified file.
(Trac #606, git 6ac000df85625f5921e8895a1aafff5e4be3ba9c)
- 190. [func] jelte
+190. [func] jelte
Resolver now sets random qids on outgoing queries using
the boost::mt19937 prng.
(Trac #583, git 5222b51a047d8f2352bc9f92fd022baf1681ed81)
- 189. [bug] jreed
+189. [bug] jreed
Do not install the log message compiler.
(Trac #634, git eb6441aca464980d00e3ff827cbf4195c5a7afc5)
- 188. [bug] zhang likun
+188. [bug] zhang likun
Make the rrset trust level ranking algorithm used by
isc::cache::MessageEntry::getRRsetTrustLevel() follow RFC2181
section 5.4.1.
(Trac #595 git 19197b5bc9f2955bd6a8ca48a2d04472ed696e81)
- 187. [bug] zhang likun
+187. [bug] zhang likun
Fix the assert error in class isc::cache::RRsetCache by adding the
check for empty pointer and test case for it.
(Trac #638, git 54e61304131965c4a1d88c9151f8697dcbb3ce12)
- 186. [bug] jelte
+186. [bug] jelte
b10-resolver could stop with an assertion failure on certain kinds
of messages (there was a problem in error message creation). This
fixes that.
(Trac #607, git 25a5f4ec755bc09b54410fcdff22691283147f32)
- 185. [bug] vorner
+185. [bug] vorner
Tests use port from private range (53210), lowering chance of
a conflict with something else (eg. running bind 10).
(Trac #523, git 301da7d26d41e64d87c0cf72727f3347aa61fb40)
- 184. [func]* vorner
+184. [func]* vorner
Listening address and port configuration of b10-auth is the same as
for b10-resolver now. That means, it is configured through bindctl
at runtime, in the Auth/listen_on list, not through command line
arguments.
(Trac #575, #576, git f06ce638877acf6f8e1994962bf2dbfbab029edf)
- 183. [bug] jerry
+183. [bug] jerry
src/bin/xfrout: Enable parallel sessions between xfrout server and
muti-Auth. The session needs to be created only on the first time
or if an error occur.
(Trac #419, git 1d60afb59e9606f312caef352ecb2fe488c4e751)
- 182. [func] jinmei
+182. [func] jinmei
Support cppcheck for static code check on C++ code. If cppcheck
is available, 'make cppcheck' on the top source directory will run
the checker and should cleanly complete with an exit code of 0
@@ -171,46 +234,46 @@
the git repository.
(Trac #613, git b973f67520682b63ef38b1451d309be9f4f4b218)
- 181. [func] feng
+181. [func] feng
Add stop interface into dns server, so we can stop each running
server individually. With it, user can reconfigure her running server
with different ip address or port.
(Trac #388, git 6df94e2db856c1adc020f658cc77da5edc967555)
- 180. [build] jreed
+180. [build] jreed
Fix custom DESTDIR for make install. Patch from Jan Engelhardt.
(Trac #629, git 5ac67ede03892a5eacf42ce3ace1e4e376164c9f)
bind10-devel-20110224 released on February 24, 2011
- 179. [func] vorner
+179. [func] vorner
It is possible to start and stop resolver and authoritative
server without restart of the whole system. Change of the
configuration (Boss/start_auth and Boss/start_resolver) is
enough.
(Trac #565, git 0ac0b4602fa30852b0d86cc3c0b4730deb1a58fe)
- 178. [func] jelte
+178. [func] jelte
Resolver now makes (limited) use of the cache
(Trac #491, git 8b41f77f0099ddc7ca7d34d39ad8c39bb1a8363c)
- 177. [func] stephen
+177. [func] stephen
The upstream fetch code in asiolink is now protocol agnostic to
allow for the addition of fallback to TCP if a fetch response
indicates truncation.
(Trac #554, git 9739cbce2eaffc7e80640db58a8513295cf684de)
- 176. [func] zhang likun
+176. [func] likun
src/lib/cache: Rename one interface: from lookupClosestRRset()
to lookupDeepestNS(), and remove one parameter of it.
(Trac #492, git ecbfb7cf929d62a018dd4cdc7a841add3d5a35ae)
- 175. [bug] jerry
+175. [bug] jerry
src/bin/xfrout: Xfrout use the case-sensitive mode to compress
names in an AXFR massage.
(Trac #253, git 004e382616150f8a2362e94d3458b59bb2710182)
- 174. [bug]* jinmei
+174. [bug]* jinmei
src/lib/dns: revised dnssectime functions so that they don't rely
on the time_t type (whose size varies on different systems, which
can lead to subtle bugs like some form of "year 2038 problem").
@@ -219,74 +282,74 @@ bind10-devel-20110224 released on February 24, 2011
should be minimal because these functions are mostly private.
(Trac #61, git 09ece8cdd41c0f025e8b897b4883885d88d4ba5d)
- 173. [bug] jerry
+173. [bug] jerry
python/isc/notify: A notify_out test fails without network
connectivity, encapsulate the socket behavior using a mock
socket class to fix it.
(Trac #346, git 319debfb957641f311102739a15059f8453c54ce)
- 172. [func] jelte
+172. [func] jelte
Improved the bindctl cli in various ways, mainly concerning
list and map item addressing, the correct display of actual values,
and internal help.
(Trac #384, git e5fb3bc1ed5f3c0aec6eb40a16c63f3d0fc6a7b2)
- 171. [func] feng, jerry, jinmei, vorner
+171. [func] vorner
b10-auth, src/lib/datasrc: in memory data source now works as a
complete data source for authoritative DNS servers and b10-auth
uses it. It still misses major features, however, including
DNSSEC support and zone transfer.
- (Last trac #553, but many more,
+ (Last Trac #553, but many more,
git 6f031a09a248e7684723c000f3e8cc981dcdb349)
- 170. [bug] jinmei
+170. [bug] jinmei
Tightened validity checks in the NSEC3 constructors, both "from
"text" and "from wire". Specifically, wire data containing
invalid type bitmaps or invalid lengths of salt or hash is now
correctly rejected.
(Trac #117, git 9c690982f24fef19c747a72f43c4298333a58f48)
- 169. [func] zhang likun, jelte
+169. [func] jelte
Added a basic implementation for a resolver cache (though not
used yet).
(Trac #449, git 8aa3b2246ae095bbe7f855fd11656ae3bdb98986)
- 168. [bug] vorner
+168. [bug] vorner
Boss no longer has the -f argument, which was undocumented and
stayed as a relict of previous versions, currently causing only
strange behaviour.
(Trac #572, git 17f237478961005707d649a661cc72a4a0d612d4)
- 167. [bug] naokikambe
+167. [bug] naokikambe
Fixed failure of termination of msgq_test.py with python3
- coverage(3.3.1)
+ coverage (3.3.1).
(Trac #573, git 0e6a18e12f61cc482e07078776234f32605312e5)
- 166. [func] jelte
+166. [func] jelte
The resolver now sends back a SERVFAIL when there is a client
timeout (timeout_client config setting), but it will not stop
resolving (until there is a lookup timeout or a result).
(Trac #497 and #489, git af0e5cd93bebb27cb5c4457f7759d12c8bf953a6)
- 165. [func] jelte
+165. [func] jelte
The resolver now handles CNAMEs, it will follow them, and include
them in the answer. The maximum length of CNAME chains that is
supported is 16.
(Trac #497, git af0e5cd93bebb27cb5c4457f7759d12c8bf953a6)
- 164. [bug] y-aharen
+164. [bug] y-aharen
IntervalTimer: Modified the interface to accept interval in
milliseconds. It shortens the time of the tests of IntervalTimer.
(Trac #452, git c9f6acc81e24c4b8f0eb351123dc7b43f64e0914)
- 163. [func] vorner
+163. [func] vorner
The pimpl design pattern is used in UDPServer, with a shared
pointer. This makes it smaller to copy (which is done a lot as a
sideeffect of being coroutine) and speeds applications of this
class (notably b10-auth) up by around 10%.
(Trac #537, git 94cb95b1d508541201fc064302ba836164d3cbe6)
- 162. [func] stephen
+162. [func] stephen
Added C++ logging, allowing logging at different severities.
Code specifies the message to be logged via a symbol, and the
logging code picks up the message from an in-built dictionary.
@@ -295,13 +358,13 @@ bind10-devel-20110224 released on February 24, 2011
to create message header files and supply the default messages.
(Trac #438, git 7b1606cea7af15dc71f5ec1d70d958b00aa98af7)
- 161. [func] stephen
+161. [func] stephen
Added ResponseScrubber class to examine response from
a server and to remove out-of-bailiwick RRsets. Also
does cross-section checks to ensure consistency.
(Trac #496, git b9296ca023cc9e76cda48a7eeebb0119166592c5)
- 160. [func] jelte
+160. [func] jelte
Updated the resolver to take 3 different timeout values;
timeout_query for outstanding queries we sent while resolving
timeout_client for sending an answer back to the client
@@ -309,14 +372,14 @@ bind10-devel-20110224 released on February 24, 2011
(currently 2 and 3 have the same final effect)
(Trac #489, git 578ea7f4ba94dc0d8a3d39231dad2be118e125a2)
- 159. [func] smann
+159. [func] smann
The resolver now has a configurable set of root servers to start
resolving at (called root_addresses). By default these are not
(yet) filled in. If empty, a hardcoded address for f-root will be
used right now.
(Trac #483, git a07e078b4feeb01949133fc88c9939254c38aa7c)
- 158. [func] jelte
+158. [func] jelte
The Resolver module will now do (very limited) resolving, if not
set to forwarding mode (i.e. if the configuration option
forward_addresses is left empty). It only supports referrals that
@@ -324,24 +387,24 @@ bind10-devel-20110224 released on February 24, 2011
of authoritative answers.
(Trac #484, git 7b84de4c0e11f4a070e038ca4f093486e55622af)
- 157. [bug] vorner
+157. [bug] vorner
One frozen process no longer freezes the whole b10-msgq. It caused the
whole system to stop working.
(Trac #420, git 93697f58e4d912fa87bc7f9a591c1febc9e0d139)
- 156. [func] stephen
+156. [func] stephen
Added ResponseClassifier class to examine response from
a server and classify it into one of several categories.
(Trac #487, git 18491370576e7438c7893f8551bbb8647001be9c)
bind10-devel-20110120 released on January 20, 2011
- 155. [doc] jreed
+155. [doc] jreed
Miscellaneous documentation improvements for man pages and
the guide, including auth, resolver, stats, xfrout, and
zonemgr. (git c14c4741b754a1eb226d3bdc3a7abbc4c5d727c0)
- 154. [bug] jinmei
+154. [bug] jinmei
b10-xfrin/b10-zonemgr: Fixed a bug where these programs didn't
receive command responses from CC sessions. Eventually the
receive buffer became full, and many other components that rely
@@ -350,12 +413,12 @@ bind10-devel-20110120 released on January 20, 2011
to revisit it for cleaner fix later.
(Trac #516, git 62c72fcdf4617e4841e901408f1e7961255b8194)
- 153. [bug] jelte
+153. [bug] jelte
b10-cfgmgr: Fixed a bug where configuration updates sometimes
lost previous settings in the configuration manager.
(Trac #427, git 2df894155657754151e0860e2ca9cdbed7317c70)
- 152. [func]* jinmei
+152. [func]* jinmei
b10-auth: Added new configuration variable "statistics-interval"
to allow the user to change the timer interval for periodic
statistics updates. The update can also be disabled by setting
@@ -364,46 +427,47 @@ bind10-devel-20110120 released on January 20, 2011
sending statistics and stop responding to queries as a result.
(Trac #513, git 285c5ee3d5582ed6df02d1aa00387f92a74e3695)
- 151. [bug] smann
+151. [bug] smann
lib/log/dummylog.h:
- lib/log/dummylog.cc: Modify dlog so that it takes an optional 2nd
- argument of type bool (true or false). This flag, if set, will cause
- the message to be printed whether or not -v is chosen.
- (trac #432, git 880220478c3e8702d56d761b1e0b21b77d08ee5a)
+ lib/log/dummylog.cc: Modify dlog so that it takes an optional
+ 2nd argument of type bool (true or false). This flag, if
+ set, will cause the message to be printed whether or not
+ -v is chosen.
+ (Trac #432, git 880220478c3e8702d56d761b1e0b21b77d08ee5a)
- 150. [bug] jelte
+150. [bug] jelte
b10-cfgmgr: No longer save the configuration on exit. Configuration
is already saved if it is changed successfully, so writing it on
exit (and hence, when nothing has changed too) is unnecessary and
may even cause problems.
(Trac #435, git fd7baa38c08d54d5b5f84930c1684c436d2776dc)
- 149. [bug] jelte
+149. [bug] jelte
bindctl: Check if the user session has disappeared (either by a
timeout or by a server restart), and reauthenticate if so. This
fixes the 'cmdctl not running' problem.
- (trac #431, git b929be82fec5f92e115d8985552f84b4fdd385b9)
+ (Trac #431, git b929be82fec5f92e115d8985552f84b4fdd385b9)
- 148. [func] jelte
+148. [func] jelte
bindctl: Command results are now pretty-printed (i.e. printed in
a more readable form). Empty results are no longer printed at all
(used to print '{}'), and the message
'send the command to cmd-ctrl' has also been removed.
(git 3954c628c13ec90722a2d8816f52a380e0065bae)
- 147. [bug] jinmei
+147. [bug] jinmei
python/isc/config: Fixed a bug that importing custom configuration
(in b10-config.db) of a remote module didn't work.
(Trac #478, git ea4a481003d80caf2bff8d0187790efd526d72ca)
- 146. [func] jelte
+146. [func] jelte
Command arguments were not validated internally against their
specifications. This change fixes that (on the C++ side, Python
side depends on an as yet planned addition). Note: this is only
an added internal check, the cli already checks format.
(Trac #473, git 5474eba181cb2fdd80e2b2200e072cd0a13a4e52)
- 145. [func]* jinmei
+145. [func]* jinmei
b10-auth: added a new command 'loadzone' for (re)loading a
specific zone. The command syntax is generic but it is currently
only feasible for class IN in memory data source. To reload a
@@ -412,7 +476,7 @@ bind10-devel-20110120 released on January 20, 2011
(Trac #467 git 4f7e1f46da1046de527ab129a88f6aad3dba7562
from 1d7d3918661ba1c6a8b1e40d8fcbc5640a84df12)
- 144. [build] jinmei
+144. [build] jinmei
Introduced a workaround for clang++ build on FreeBSD (and probably
some other OSes). If building BIND 10 fails with clang++ due to
a link error about "__dso_handle", try again from the configure
@@ -423,23 +487,23 @@ bind10-devel-20110120 released on January 20, 2011
variable by hand.
(Trac #474, git cfde436fbd7ddf3f49cbbd153999656e8ca2a298)
- 143. [build] jinmei
+143. [build] jinmei
Fixed build problems with clang++ in unit tests due to recent
changes. No behavior change. (Trac #448, svn r4133)
- 142. [func] jinmei
+142. [func] jinmei
b10-auth: updated query benchmark so that it can test in memory
data source. Also fixed a bug that the output buffer isn't
cleared after query processing, resulting in misleading results
or program crash. This is a regression due to change #135.
(Trac #465, svn r4103)
- 141. [bug] jinmei
+141. [bug] jinmei
b10-auth: Fixed a bug that the authoritative server includes
trailing garbage data in responses. This is a regression due to
change #135. (Trac #462, svn r4081)
- 140. [func] y-aharen
+140. [func] y-aharen
src/bin/auth: Added a feature to count queries and send counter
values to statistics periodically. To support it, added wrapping
class of asio::deadline_timer to use as interval timer.
@@ -450,14 +514,14 @@ bind10-devel-20110120 released on January 20, 2011
counters to b10-stats immediately.
(Trac #347, svn r4026)
- 139. [build] jreed
+139. [build] jreed
Introduced configure option and make targets for generating
Python code coverage report. This adds new make targets:
report-python-coverage and clean-python-coverage. The C++
code coverage targets were renamed to clean-cpp-coverage
and report-cpp-coverage. (Trac #362, svn r4023)
- 138. [func]* jinmei
+138. [func]* jinmei
b10-auth: added a configuration interface to support in memory
data sources. For example, the following command to bindctl
will configure a memory data source containing the "example.com"
@@ -474,70 +538,70 @@ bind10-devel-20110120 released on January 20, 2011
future versions.
(Trac #446, svn r3998)
- 137. [bug] jreed
+137. [bug] jreed
Fix run_*.sh scripts that are used for development testing
so they use a msgq socket file in the build tree.
(Trac #226, svn r3989)
- 136. [bug] jelte
+136. [bug] jelte
bindctl (and the configuration manager in general) now no longer
accepts 'unknown' data; i.e. data for modules that it does not know
about, or configuration items that are not specified in the .spec
files.
(Trac #202, svn r3967)
- 135. [func] each
+135. [func] each
Add b10-resolver. This is an example recursive server that
currently does forwarding only and no caching.
(Trac #327, svn r3903)
- 134. [func] vorner
+134. [func] vorner
b10-resolver supports timeouts and retries in forwarder mode.
(Trac #401, svn r3660)
- 133. [func] vorner
+133. [func] vorner
New temporary logging function available in isc::log. It is used by
b10-resolver.
(Trac #393, r3602)
- 132. [func] vorner
+132. [func] vorner
The b10-resolver is configured through config manager.
It has "listen_on" and "forward_addresses" options.
(Trac #389, r3448)
- 131. [func] feng, jerry
+131. [func] jerry
src/lib/datasrc: Introduced two template classes RBTree and RBNode
to provide the generic map with domain name as key and anything as
the value. Because of some unresolved design issue, the new classes
are only intended to be used by memory zone and zone table.
(Trac #397, svn r3890)
- 130. [func] jerry
+130. [func] jerry
src/lib/datasrc: Introduced a new class MemoryDataSrc to provide
the general interface for memory data source. For the initial
implementation, we don't make it a derived class of AbstractDataSrc
- because the interface is so different(we'll eventually consider this
- as part of the generalization work).
+ because the interface is so different (we'll eventually
+ consider this as part of the generalization work).
(Trac #422, svn r3866)
- 129. [func] jinmei
+129. [func] jinmei
src/lib/dns: Added new functions masterLoad() for loading master
zone files. The initial implementation can only parse a limited
form of master files, but BIND 9's named-compilezone can convert
any valid zone file into the acceptable form.
(Trac #423, svn r3857)
- 128. [build] vorner
+128. [build] vorner
Test for query name = '.', type = DS to authoritative nameserver
for root zone was added.
(Trac #85, svn r3836)
- 127. [bug] stephen
+127. [bug] stephen
During normal operation process termination and resurrection messages
are now output regardless of the state of the verbose flag.
(Trac #229, svn r3828)
- 126. [func] stephen, vorner, ocean
+126. [func] ocean
The Nameserver Address Store (NSAS) component has been added. It takes
care of choosing an IP address of a nameserver when a zone needs to be
contacted.
@@ -545,38 +609,38 @@ bind10-devel-20110120 released on January 20, 2011
bind10-devel-20101201 released on December 01, 2010
- 125. [func] jelte
+125. [func] jelte
Added support for addressing individual list items in bindctl
configuration commands; If you have an element that is a list, you
- can use foo[X] to address a specific item, where X is an integer
+ can use foo[X] integer
(starting at 0)
(Trac #405, svn r3739)
- 124. [bug] jreed
+124. [bug] jreed
Fix some wrong version reporting. Now also show the version
for the component and BIND 10 suite. (Trac #302, svn r3696)
- 123. [bug] jelte
+123. [bug] jelte
src/bin/bindctl printed values had the form of python literals
(e.g. 'True'), while the input requires valid JSON (e.g. 'true').
Output changed to JSON format for consistency. (svn r3694)
- 122. [func] stephen
+122. [func] stephen
src/bin/bind10: Added configuration options to Boss to determine
whether to start the authoritative server, recursive server (or
both). A dummy program has been provided for test purposes.
(Trac #412, svn r3676)
- 121. [func] jinmei
+121. [func] jinmei
src/lib/dns: Added support for TSIG RDATA. At this moment this is
not much of real use, however, because no protocol support was
added yet. It will soon be added. (Trac #372, svn r3649)
- 120. [func] jinmei
+120. [func] jinmei
src/lib/dns: introduced two new classes, TSIGKey and TSIGKeyRing,
to manage TSIG keys. (Trac #381, svn r3622)
- 119. [bug] jinmei
+119. [bug] jinmei
The master file parser of the python datasrc module incorrectly
regarded a domain name beginning with a decimal number as a TTL
specification. This confused b10-loadzone and had it reject to
@@ -586,158 +650,158 @@ bind10-devel-20101201 released on December 01, 2010
from a TTL specification. This is part of a more general issue
and will be addressed in Trac #413. (Trac #411, svn r3599)
- 118. [func] jinmei
+118. [func] jinmei
src/lib/dns: changed the interface of
AbstractRRset::getRdataIterator() so that the internal
cursor would point to the first RDATA automatically. This
will be a more intuitive and less error prone behavior.
This is a backward compatible change. (Trac #410, r3595)
- 117. [func] jinmei
+117. [func] jinmei
src/lib/datasrc: added new zone and zone table classes for the
support of in memory data source. This is an intermediate step to
the bigger feature, and is not yet actually usable in practice.
(Trac #399, svn r3590)
- 116. [bug] jerry
+116. [bug] jerry
src/bin/xfrout: Xfrout and Auth will communicate by long tcp
connection, Auth needs to make a new connection only on the first
time or if an error occurred.
(Trac #299, svn r3482)
- 115. [func]* jinmei
+115. [func]* jinmei
src/lib/dns: Changed DNS message flags and section names from
separate classes to simpler enums, considering the balance between
type safety and usability. API has been changed accordingly.
More documentation and tests were provided with these changes.
(Trac #358, r3439)
- 114. [build] jinmei
+114. [build] jinmei
Supported clang++. Note: Boost >= 1.44 is required.
(Trac #365, svn r3383)
- 113. [func]* zhanglikun
+113. [func]* zhanglikun
Folder name 'utils'(the folder in /src/lib/python/isc/) has been
renamed to 'util'. Programs that used 'import isc.utils.process'
now need to use 'import isc.util.process'. The folder
/src/lib/python/isc/Util is removed since it isn't used by any
program. (Trac #364, r3382)
- 112. [func] zhang likun
+112. [func] zhang likun
Add one mixin class to override the naive serve_forever() provided
in python library socketserver. Instead of polling for shutdown
every poll_interval seconds, one socketpair is used to wake up
the waiting server. (Trac #352, svn r3366)
- 111. [bug]* zhanglikun, Michal Vaner
+111. [bug]* Vaner
Make sure process xfrin/xfrout/zonemgr/cmdctl can be stopped
properly when user enter "ctrl+c" or 'Boss shutdown' command
through bindctl. The ZonemgrRefresh.run_timer and
NotifyOut.dispatcher spawn a thread themselves.
(Trac #335, svn r3273)
- 110. [func] Michal Vaner
+110. [func] Vaner
Added isc.net.check module to check ip addresses and ports for
correctness and isc.net.addr to hold IP address. The bind10, xfrin
and cmdctl programs are modified to use it.
(Trac #353, svn r3240)
- 109. [func] naokikambe
+109. [func] naokikambe
Added the initial version of the stats module for the statistics
feature of BIND 10, which supports the restricted features and
items and reports via bindctl command. (Trac #191, r3218)
Added the document of the stats module, which is about how stats
module collects the data (Trac #170, [wiki:StatsModule])
- 108. [func] jerry
+108. [func] jerry
src/bin/zonemgr: Provide customizable configurations for
lowerbound_refresh, lowerbound_retry, max_transfer_timeout and
jitter_scope. (Trac #340, r3205)
- 107. [func] zhang likun
+107. [func] likun
Remove the parameter 'db_file' for command 'retransfer' of
xfrin module. xfrin.spec will not be generated by script.
(Trac #329, r3171)
- 106. [bug] zhang likun
+106. [bug] likun
When xfrin can't connect with one zone's master, it should tell
the bad news to zonemgr, so that zonemgr can reset the timer for
that zone. (Trac #329, r3170)
- 105. [bug] Michal Vaner
+105. [bug] Vaner
Python processes: they no longer take 100% CPU while idle
due to a busy loop in reading command session in a nonblocking way.
(Trac #349, svn r3153), (Trac #382, svn r3294)
- 104. [bug] jerry
+104. [bug] jerry
bin/zonemgr: zonemgr should be attempting to refresh expired zones.
(Trac #336, r3139)
- 103. [bug] jerry
+103. [bug] jerry
lib/python/isc/log: Fixed an issue with python logging,
python log shouldn't die with OSError. (Trac #267, r3137)
- 102. [build] jinmei
+102. [build] jinmei
Disable threads in ASIO to minimize build time dependency.
(Trac #345, r3100)
- 101. [func] jinmei
+101. [func] jinmei
src/lib/dns: Completed Opcode and Rcode implementation with more
tests and documentation. API is mostly the same but the
validation was a bit tightened. (Trac #351, svn r3056)
- 100. [func] Michal Vaner
+100. [func] Vaner
Python processes: support naming of python processes so
they're not all called python3.
(Trac #322, svn r3052)
- 99. [func]* jinmei
+99. [func]* jinmei
Introduced a separate EDNS class to encapsulate EDNS related
information more cleanly. The related APIs are changed a bit,
although it won't affect most of higher level applications.
(Trac #311, svn r3020)
- 98. [build] jinmei
+98. [build] jinmei
The ./configure script now tries to search some common include
paths for boost header files to minimize the need for explicit
configuration with --with-boost-include. (Trac #323, svn r3006)
- 97. [func] jinmei
+97. [func] jinmei
Added a micro benchmark test for query processing of b10-auth.
(Trac #308, svn r2982)
- 96. [bug] jinmei
+96. [bug] jinmei
Fixed two small issues with configure: Do not set CXXFLAGS so that
it can be customized; Make sure --disable-static works.
(Trac #325, r2976)
bind10-devel-20100917 released on September 17, 2010
- 95. [doc] jreed
+95. [doc] jreed
Add b10-zonemgr manual page. Update other docs to introduce
this secondary manager. (Trac #341, svn r2951)
- 95. [bug] jreed
+95. [bug] jreed
bin/xfrout and bin/zonemgr: Fixed some stderr output.
(Trac #342, svn r2949)
- 94. [bug] jelte
+94. [bug] jelte
bin/xfrout: Fixed a problem in xfrout where only 2 or 3 RRs
were used per DNS message in the xfrout stream.
(Trac #334, r2931)
- 93. [bug] jinmei
+93. [bug] jinmei
lib/datasrc: A DS query could crash the library (and therefore,
e.g. the authoritative server) if some RR of the same apex name
is stored in the hot spot cache. (Trac #307, svn r2923)
- 92. [func]* jelte
+92. [func]* jelte
libdns_python (the python wrappers for libdns++) has been renamed
to pydnspp (Python DNS++). Programs and libraries that used
'import libdns_python' now need to use 'import pydnspp'.
(Trac #314, r2902)
- 91. [func]* jinmei
+91. [func]* jinmei
lib/cc: Use const pointers and const member functions for the API
as much as possible for safer operations. Basically this does not
change the observable behavior, but some of the API were changed
@@ -745,36 +809,36 @@ bind10-devel-20100917 released on September 17, 2010
copies, but at this moment the overhead is deemed acceptable.
(Trac #310, r2803)
- 90. [build] jinmei
+90. [build] jinmei
(Darwin/Mac OS X specific) Specify DYLD_LIBRARY_PATH for tests and
experimental run under the source tree. Without this loadable
python modules refer to installation paths, which may confuse the
operation due to version mismatch or even trigger run time errors
due to missing libraries. (Trac #313, r2782)
- 89. [build] jinmei
+89. [build] jinmei
Generate b10-config.db for tests at build time so that the source
tree does not have to be writable. (Trac #315, r2776)
- 88. [func] jelte
+88. [func] jelte
Blocking reads on the msgq command channel now have a timeout
(defaults to 4 seconds, modifiable as needed by modules).
Because of this, modules will no longer block indefinitely
if they are waiting for a message that is not sent for whatever
reason. (Trac #296, r2761)
- 87. [func] zhanglikun
+87. [func] zhanglikun
lib/python/isc/notifyout: Add the feature of notify-out, when
zone axfr/ixfr finishing, the server will notify its slaves.
(Trac #289, svn r2737)
- 86. [func] jerry
+86. [func] jerry
bin/zonemgr: Added zone manager module. The zone manager is one
of the co-operating processes of BIND10, which keeps track of
timers and other information necessary for BIND10 to act as a
slave. (Trac #215, svn r2737)
- 85. [build]* jinmei
+85. [build]* jinmei
Build programs using dynamic link by default. A new configure
option --enable-static-link is provided to force static link for
executable programs. Statically linked programs can be run on a
@@ -783,34 +847,34 @@ bind10-devel-20100917 released on September 17, 2010
bind10-devel-20100812 released on August 12, 2010
- 84. [bug] jinmei, jerry
+84. [bug] jinmei, jerry
This is a quick fix patch for the issue: AXFR fails half the
time because of connection problems. xfrout client will make
a new connection every time. (Trac #299, svn r2697)
- 83. [build]* jreed
+83. [build]* jreed
The configure --with-boost-lib option is removed. It was not
used since the build included ASIO. (svn r2684)
- 82. [func] jinmei
+82. [func] jinmei
bin/auth: Added -u option to change the effective process user
of the authoritative server after invocation. The same option to
the boss process will be propagated to b10-auth, too.
(Trac #268, svn r2675)
- 81. [func] jinmei
+81. [func] jinmei
Added a C++ framework for micro benchmark tests. A supplemental
library functions to build query data for the tests were also
provided. (Trac #241, svn r2664)
- 80. [bug] jelte
+80. [bug] jelte
bindctl no longer accepts configuration changes for unknown or
non-running modules (for the latter, this is until we have a
way to verify those options, at which point it'll be allowed
again).
(Trac #99, r2657)
- 79. [func] feng, jinmei
+79. [func] feng, jinmei
Refactored the ASIO link interfaces to move incoming XFR and
NOTIFY processing to the auth server class. Wrapper classes for
ASIO specific concepts were also provided, so that other BIND 10
@@ -822,7 +886,7 @@ bind10-devel-20100812 released on August 12, 2010
Note: Right now, NOTIFY doesn't actually trigger subsequent zone
transfer due to security reasons. (Trac #221, r2565)
- 78. [bug] jinmei
+78. [bug] jinmei
lib/dns: Fixed miscellaneous bugs in the base32 (hex) and hex
(base16) implementation, including incorrect padding handling,
parser failure in decoding with a SunStudio build, missing
@@ -833,44 +897,44 @@ bind10-devel-20100812 released on August 12, 2010
libdns++, so we don't consider it a backward incompatible change.
(Trac #256, r2549)
- 77. [func] zhanglikun
+77. [func] zhanglikun
Make error message be more friendly when running cmdctl and it's
- already running(listening on same port)(Trac #277, r2540)
+ already running (listening on same port)(Trac #277, r2540)
- 76. [bug] jelte
+76. [bug] jelte
Fixed a bug in the handling of 'remote' config modules (i.e.
modules that peek at the configuration of other modules), where
they answered 'unknown command' to commands for those other
modules. (Trac #278, r2506)
- 75. [bug] jinmei
+75. [bug] jinmei
Fixed a bug in the sqlite3 data source where temporary strings
could be referenced after destruction. It caused various lookup
failures with SunStudio build. (Trac #288, r2494)
- 74. [func]* jinmei
+74. [func]* jinmei
Refactored the cc::Session class by introducing an abstract base
class. Test code can use their own derived mock class so that
tests can be done without establishing a real CC session. This
change also modified some public APIs, mainly in the config
module. (Trac #275, r2459)
- 73. [bug] jelte
+73. [bug] jelte
Fixed a bug where in bindctl, locally changed settings were
reset when the list of running modules is updated. (Trac #285,
r2452)
- 72. [build] jinmei
+72. [build] jinmei
Added -R when linking python wrapper modules to libpython when
possible. This helps build BIND 10 on platforms that install
libpython whose path is unknown to run-time loader. NetBSD is a
known such platform. (Trac #148, r2427)
- 71. [func] each
+71. [func] each
Add "-a" (address) option to bind10 to specify an address for
the auth server to listen on.
- 70. [func] each
+70. [func] each
Added a hot-spot cache to libdatasrc to speed up access to
repeatedly-queried data and reduce the number of queries to
the underlying database; this should substantially improve
@@ -880,22 +944,22 @@ bind10-devel-20100812 released on August 12, 2010
bind10-devel-20100701 released on July 1, 2010
- 69. [func]* jelte
+69. [func]* jelte
Added python wrappers for libdns++ (isc::dns), and libxfr. This
removes the dependency on Boost.Python. The wrappers don't
completely implement all functionality, but the high-level API
is wrapped, and current modules use it now.
(Trac #181, svn r2361)
- 68. [func] zhanglikun
- Add options -c(--certificate-chain) to bindctl. Override class
+68. [func] zhanglikun
+ Add options -c (--certificate-chain) to bindctl. Override class
HTTPSConnection to support server certificate validation.
Add support to cmdctl.spec file, now there are three configurable
items for cmdctl: 'key_file', 'cert_file' and 'accounts_file',
all of them can be changed in runtime.
(Trac #127, svn r2357)
- 67. [func] zhanglikun
+67. [func] zhanglikun
Make bindctl's command parser only do minimal check.
Parameter value can be a sequence of non-space characters,
or a string surrounded by quotation marks (these marks can
@@ -906,13 +970,13 @@ bind10-devel-20100701 released on July 1, 2010
avoid using Exception to catch all exceptions.
(Trac #220, svn r2356)
- 66. [bug] each
+66. [bug] each
Check for duplicate RRsets before inserting data into a message
section; this, among other things, will prevent multiple copies
of the same CNAME from showing up when there's a loop. (Trac #69,
svn r2350)
- 65. [func] shentingting
+65. [func] shentingting
Various loadzone improvements: allow optional comment for
$TTL, allow optional origin and comment for $INCLUDE, allow
optional comment for $ORIGIN, support BIND9 extension of
@@ -923,71 +987,71 @@ bind10-devel-20100701 released on July 1, 2010
formats to load.
(Trac #197, #199, #244, #161, #198, #174, #175, svn r2340)
- 64. [func] jerry
+64. [func] jerry
Added python logging framework. It is for testing and
experimenting with logging ideas. Currently, it supports
three channels (file, syslog and stderr) and five levels
(debug, info, warning, error and critical).
(Trac #176, svn r2338)
- 63. [func] shane
+63. [func] shane
Added initial support for setuid(), using the "-u" flag. This will
be replaced in the future, but for now provides a reasonable
starting point.
(Trac #180, svn r2330)
- 62. [func] jelte
+62. [func] jelte
bin/xfrin: Use the database_file as configured in Auth to transfers
bin/xfrout: Use the database_file as configured in Auth to transfers
- 61. [bug] jelte
+61. [bug] jelte
bin/auth: Enable b10-auth to be launched in source tree
(i.e. use a zone database file relative to that)
- 60. [build] jinmei
+60. [build] jinmei
Supported SunStudio C++ compiler. Note: gtest still doesn't work.
(Trac #251, svn r2310)
- 59. [bug] jinmei
+59. [bug] jinmei
lib/datasrc,bin/auth: The authoritative server could return a
SERVFAIL with a partial answer if it finds a data source broken
while looking for an answer. This can happen, for example, if a
zone that doesn't have an NS RR is configured and loaded as a
sqlite3 data source. (Trac #249, r2286)
- 58. [bug] jinmei
+58. [bug] jinmei
Worked around an interaction issue between ASIO and standard C++
library headers. Without this ASIO didn't work: sometimes the
application crashes, sometimes it blocked in the ASIO module.
(Trac #248, svn r2187, r2190)
- 57. [func] jinmei
+57. [func] jinmei
lib/datasrc: used a simpler version of Name::split (change 31) for
better readability. No behavior change. (Trac #200, svn r2159)
- 56. [func]* jinmei
+56. [func]* jinmei
lib/dns: renamed the library name to libdns++ to avoid confusion
with the same name of library of BIND 9.
(Trac #190, svn r2153)
- 55. [bug] shane
+55. [bug] shane
bin/xfrout: xfrout exception on Ctrl-C now no longer generates
exception for 'Interrupted system call'
(Track #136, svn r2147)
- 54. [bug] zhanglikun
+54. [bug] zhanglikun
bin/xfrout: Enable b10-xfrout can be launched in source
code tree.
(Trac #224, svn r2103)
- 53. [bug] zhanglikun
+53. [bug] zhanglikun
bin/bindctl: Generate a unique session ID by using
socket.gethostname() instead of socket.gethostbyname(),
since the latter one could make bindctl stall if its own
host name can't be resolved.
(Trac #228, svn r2096)
- 52. [func] zhanglikun
+52. [func] zhanglikun
bin/xfrout: When xfrout is launched, check whether the
socket file is being used by one running xfrout process,
if it is, exit from python. If the file isn't a socket file
@@ -997,210 +1061,210 @@ bind10-devel-20100701 released on July 1, 2010
bind10-devel-20100602 released on June 2, 2010
- 51. [build] jelte
+51. [build] jelte
lib/python: Add bind10_config.py module for paths and
possibly other configure-time variables. Allow some components
to find spec files in build tree when ran from source.
(Trac #223)
- 50. [bug] zhanglikun
+50. [bug] zhanglikun
bin/xfrin: a regression in xfrin: it can't communicate with
a remote server. (Trac #218, svn r2038)
- 49. [func]* jelte
+49. [func]* jelte
Use unix domain sockets for msgq. For b10-msgq, the command
line options --msgq-port and -m were removed. For bind10,
the -msgq-port option was removed, and the -m command line
option was changed to be a filename (instead of port number).
(Trac #183, svn r2009)
- 48. [func] jelte
+48. [func] jelte
bin/auth: Use asio's io_service for the msgq handling.
(svn r2007)
- 47. [func] zhanglikun
+47. [func] zhanglikun
bin/cmdctl: Add value/type check for commands sent to
cmdctl. (Trac #201, svn r1959)
- 46. [func] zhanglikun
+46. [func] zhanglikun
lib/cc: Fix real type data encoding/decoding. (Trac #193,
svn r1959)
- 45. [func] zhanglikun
+45. [func] zhanglikun
bin/bind10: Pass verbose option to more modules. (Trac
#205, svn r1957)
- 44. [build] jreed
+44. [build] jreed
Install headers for libdns and libexception. (Trac #68,
svn r1941)
- 43. [func] jelte
+43. [func] jelte
lib/cc: Message queuing on cc channel. (Trac #58, svn r1870)
- 42. [func] jelte
+42. [func] jelte
lib/python/isc/config: Make temporary file with python
tempfile module instead of manual with fixed name. (Trac
#184, svn r1859)
- 41. [func] jelte
+41. [func] jelte
Module descriptions in spec files. (Trac #90, svn r1856)
- 40. [build] jreed
+40. [build] jreed
Report detected features and configure settings at end of
configure output. (svn r1836)
- 39. [func]* each
+39. [func]* each
Renamed libauth to libdatasrc.
- 38. [bug] zhanglikun
+38. [bug] zhanglikun
Send command 'shutdown' to Xfrin and Xfrout when boss receive SIGINT.
Remove unused socket file when Xfrout process exits. Make sure Xfrout
exit by itself when it receives SIGINT, instead of being killed by the
signal SIGTERM or SIGKILL sent from boss.
(Trac #135, #151, #134, svn r1797)
- 37. [build] jinmei
+37. [build] jinmei
Check for the availability of python-config. (Trac #159,
svn r1794)
- 36. [func] shane
+36. [func] shane
bin/bind10: Miscellaneous code cleanups and improvements.
(Trac #40, svn r2012)
- 35. [bug] jinmei
+35. [bug] jinmei
bin/bindctl: fixed a bug that it didn't accept IPv6 addresses as
command arguments. (Trac #219, svn r2022)
- 34. [bug] jinmei
+34. [bug] jinmei
bin/xfrin: fixed several small bugs with many additional unit
tests. Fixes include: IPv6 transport support, resource leak,
and non IN class support. (Trac #185, svn r2000)
- 33. [bug] each
+33. [bug] each
bin/auth: output now prepended with "[b10-auth]" (Trac
#109, svn r1985)
- 32. [func]* each
+32. [func]* each
bin/auth: removed custom query-processing code, changed
boost::asio code to use plain asio instead, and added asio
headers to the source tree. This allows building without
using an external boost library. (Trac #163, svn r1983)
- 31. [func] jinmei
+31. [func] jinmei
lib/dns: added a separate signature for Name::split() as a
convenient wrapper for common usage. (Trac #49, svn r1903)
- 30. [bug] jinmei
+30. [bug] jinmei
lib/dns: parameter validation of Name::split() was not sufficient,
and invalid parameters could cause integer overflow and make the
library crash. (Trac #177, svn r1806)
bind10-devel-20100421 released on April 21, 2010
- 29. [build]
+29. [build] jreed
Enable Python unit tests for "make check". (svn r1762)
- 28. [bug]
+28. [bug] jreed
Fix msgq CC test so it can find its module. (svn r1751)
- 27. [build]
+27. [build] jelte
Add missing copyright license statements to various source
files. (svn r1750)
- 26. [func]
+26. [func] jelte
Use PACKAGE_STRING (name + version) from config.h instead
of hard-coded value in CH TXT version.bind replies (Trac
#114, svn r1749)
- 25. [func]*
+25. [func]* jreed
Renamed msgq to b10-msgq. (Trac #25, svn r1747, r1748)
- 24. [func]
+24. [func] jinmei
Support case-sensitive name compression in MessageRenderer.
(Trac #142, svn r1704)
- 23. [func]
+23. [func] jinmei
Support a simple name with possible compression. (svn r1701)
- 22. [func]
+22. [func] zhanglikun
b10-xfrout for AXFR-out support added. (svn r1629, r1630)
- 21. [bug]
+21. [bug] zhanglikun
Make log message more readable when xfrin failed. (svn
r1697)
- 20. [bug]
+20. [bug] jinmei
Keep stderr for child processes if -v is specified. (svn
r1690, r1698)
- 19. [bug]
+19. [bug] jinmei
Allow bind10 boss to pass environment variables from parent.
(svn r1689)
- 18. [bug]
+18. [bug] jinmei
Xfrin warn if bind10_dns load failed. (svn r1688)
- 17. [bug]
+17. [bug] jinmei
Use sqlite3_ds.load() in xfrin module and catch Sqlite3DSError
explicitly. (svn r1684)
- 16. [func]*
+16. [func]* zhanglikun
Removed print_message and print_settings configuration
commands from Xfrin. (Trac #136, svn r1682)
- 15. [func]*
+15. [func]* jinmei
Changed zone loader/updater so trailing dot is not required.
(svn r1681)
- 14. [bug]
+14. [bug] shane
Change shutdown to actually SIGKILL properly. (svn r1675)
- 13. [bug]
+13. [bug] jinmei
Don't ignore other RRs than SOA even if the second SOA is
found. (svn r1674)
- 12. [build]
+12. [build] jreed
Fix tests and testdata so can be used from a read-only
source directory.
- 11. [build]
+11. [build] jreed
Make sure python tests scripts are included in tarball.
(svn r1648)
- 10. [build]
+10. [build] jinmei
Improve python detection for configure. (svn r1622)
- 9. [build]
+9. [build] jinmei
Automake the python binding of libdns. (svn r1617)
- 8. [bug]
+8. [bug] zhanglikun
Fix log errors which may cause xfrin module to crash. (svn
r1613)
- 7. [func]
+7. [func] zhanglikun
New API for inserting zone data to sqlite3 database for
AXFR-in. (svn r1612, r1613)
- 6. [bug]
+6. [bug] jreed
More code review, miscellaneous cleanups, style guidelines,
and new and improved unit tests added.
- 5. [doc]
+5. [doc] jreed
Manual page cleanups and improvements.
- 4. [bug]
+4. [bug] jinmei
NSEC RDATA fixes for buffer overrun lookups, incorrect
boundary checks, spec-non-conformant behaviors. (svn r1611)
- 3. [bug]
+3. [bug] jelte
Remove a re-raise of an exception that should only have
been included in an error answer on the cc channel. (svn
r1601)
- 2. [bug]
+2. [bug] mgraff
Removed unnecessary sleep() from ccsession.cc. (svn r1528)
- 1. [build]*
+1. [build]* jreed
The configure --with-boostlib option changed to --with-boost-lib.
bind10-devel-20100319 released on March 19, 2010
@@ -1219,10 +1283,10 @@ LEGEND
unless it's deemed to be impossible or very hard to keep
compatibility to fix the bug.
[build] compilation and installation infrastructure change.
-[doc] update to documentation. This shouldn't change run time behavior.
+[doc] update to documentation. This shouldn't change run time behavior.
[func] new feature. In some cases this may be a backward incompatible
change, which would require a bump of major version.
-[security] security hole fix. This is no different than a general bug fix
- except that it will be handled as confidential and will cause
+[security] security hole fix. This is no different than a general bug
+ fix except that it will be handled as confidential and will cause
security patch releases.
*: Backward incompatible or operational change.
diff --git a/configure.ac b/configure.ac
index aac4abe..369080a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -624,6 +624,8 @@ AC_CONFIG_FILES([Makefile
src/bin/auth/benchmarks/Makefile
src/bin/resolver/Makefile
src/bin/resolver/tests/Makefile
+ src/bin/sockcreator/Makefile
+ src/bin/sockcreator/tests/Makefile
src/bin/xfrin/Makefile
src/bin/xfrin/tests/Makefile
src/bin/xfrout/Makefile
@@ -642,6 +644,8 @@ AC_CONFIG_FILES([Makefile
src/lib/Makefile
src/lib/asiolink/Makefile
src/lib/asiolink/tests/Makefile
+ src/lib/asiodns/Makefile
+ src/lib/asiodns/tests/Makefile
src/lib/bench/Makefile
src/lib/bench/example/Makefile
src/lib/bench/tests/Makefile
@@ -667,6 +671,11 @@ AC_CONFIG_FILES([Makefile
src/lib/config/Makefile
src/lib/config/tests/Makefile
src/lib/config/tests/testdata/Makefile
+ src/lib/util/Makefile
+ src/lib/util/io/Makefile
+ src/lib/util/io/tests/Makefile
+ src/lib/util/unittests/Makefile
+ src/lib/util/tests/Makefile
src/lib/dns/Makefile
src/lib/dns/tests/Makefile
src/lib/dns/tests/testdata/Makefile
@@ -677,8 +686,6 @@ AC_CONFIG_FILES([Makefile
src/lib/datasrc/Makefile
src/lib/datasrc/tests/Makefile
src/lib/xfr/Makefile
- src/lib/util/Makefile
- src/lib/util/tests/Makefile
src/lib/log/Makefile
src/lib/log/compiler/Makefile
src/lib/log/tests/Makefile
@@ -694,6 +701,9 @@ AC_CONFIG_FILES([Makefile
src/lib/server_common/tests/Makefile
tests/Makefile
tests/system/Makefile
+ tests/tools/Makefile
+ tests/tools/badpacket/Makefile
+ tests/tools/badpacket/tests/Makefile
])
AC_OUTPUT([doc/version.ent
src/bin/cfgmgr/b10-cfgmgr.py
@@ -708,6 +718,7 @@ AC_OUTPUT([doc/version.ent
src/bin/xfrout/xfrout.py
src/bin/xfrout/xfrout.spec.pre
src/bin/xfrout/tests/xfrout_test
+ src/bin/xfrout/tests/xfrout_test.py
src/bin/xfrout/run_b10-xfrout.sh
src/bin/resolver/resolver.spec.pre
src/bin/resolver/spec_config.h.pre
diff --git a/doc/Doxyfile b/doc/Doxyfile
index 46aa178..83e85b8 100644
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -568,7 +568,11 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-INPUT = ../src/lib/cc ../src/lib/config ../src/lib/dns ../src/lib/exceptions ../src/lib/datasrc ../src/bin/auth ../src/bin/resolver ../src/lib/bench ../src/lib/log ../src/lib/asiolink/ ../src/lib/nsas ../src/lib/testutils ../src/lib/cache ../src/lib/server_common/
+INPUT = ../src/lib/cc ../src/lib/config ../src/lib/dns \
+ ../src/lib/exceptions ../src/lib/datasrc ../src/bin/auth \
+ ../src/bin/resolver ../src/lib/bench ../src/lib/log ../src/lib/asiolink/ \
+ ../src/lib/nsas ../src/lib/testutils ../src/lib/cache \
+ ../src/lib/server_common/ ../src/bin/sockcreator/ ../src/lib/util/
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am
index 1768ce7..23d660c 100644
--- a/src/bin/Makefile.am
+++ b/src/bin/Makefile.am
@@ -1,4 +1,4 @@
SUBDIRS = bind10 bindctl cfgmgr loadzone msgq host cmdctl auth xfrin xfrout \
- usermgr zonemgr stats tests resolver
+ usermgr zonemgr stats tests resolver sockcreator
check-recursive: all-recursive
diff --git a/src/bin/auth/Makefile.am b/src/bin/auth/Makefile.am
index cdfc55e..56dc348 100644
--- a/src/bin/auth/Makefile.am
+++ b/src/bin/auth/Makefile.am
@@ -39,9 +39,9 @@ pkglibexec_PROGRAMS = b10-auth
b10_auth_SOURCES = query.cc query.h
b10_auth_SOURCES += auth_srv.cc auth_srv.h
b10_auth_SOURCES += change_user.cc change_user.h
-b10_auth_SOURCES += config.cc config.h
+b10_auth_SOURCES += auth_config.cc auth_config.h
b10_auth_SOURCES += command.cc command.h
-b10_auth_SOURCES += common.h
+b10_auth_SOURCES += common.h common.cc
b10_auth_SOURCES += statistics.cc statistics.h
b10_auth_SOURCES += main.cc
b10_auth_LDADD = $(top_builddir)/src/lib/datasrc/libdatasrc.la
@@ -49,6 +49,7 @@ b10_auth_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
b10_auth_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
b10_auth_LDADD += $(top_builddir)/src/lib/cc/libcc.la
b10_auth_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
+b10_auth_LDADD += $(top_builddir)/src/lib/asiodns/libasiodns.la
b10_auth_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
b10_auth_LDADD += $(top_builddir)/src/lib/nsas/libnsas.la
b10_auth_LDADD += $(top_builddir)/src/lib/xfr/libxfr.la
diff --git a/src/bin/auth/auth_config.cc b/src/bin/auth/auth_config.cc
new file mode 100644
index 0000000..7929d80
--- /dev/null
+++ b/src/bin/auth/auth_config.cc
@@ -0,0 +1,347 @@
+// Copyright (C) 2010 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 <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <boost/foreach.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <dns/name.h>
+#include <dns/rrclass.h>
+
+#include <cc/data.h>
+
+#include <datasrc/memory_datasrc.h>
+#include <datasrc/zonetable.h>
+
+#include <auth/auth_srv.h>
+#include <auth/auth_config.h>
+#include <auth/common.h>
+
+#include <server_common/portconfig.h>
+
+using namespace std;
+using boost::shared_ptr;
+using namespace isc::dns;
+using namespace isc::data;
+using namespace isc::datasrc;
+using namespace isc::server_common::portconfig;
+
+namespace {
+// Forward declaration
+AuthConfigParser*
+createAuthConfigParser(AuthSrv& server, const std::string& config_id,
+ bool internal);
+
+/// A derived \c AuthConfigParser class for the "datasources" configuration
+/// identifier.
+class DatasourcesConfig : public AuthConfigParser {
+public:
+ DatasourcesConfig(AuthSrv& server) : server_(server) {}
+ virtual void build(ConstElementPtr config_value);
+ virtual void commit();
+private:
+ AuthSrv& server_;
+ vector<shared_ptr<AuthConfigParser> > datasources_;
+ set<string> configured_sources_;
+};
+
+void
+DatasourcesConfig::build(ConstElementPtr config_value) {
+ BOOST_FOREACH(ConstElementPtr datasrc_elem, config_value->listValue()) {
+ // The caller is supposed to perform syntax-level checks, but we'll
+ // do minimum level of validation ourselves so that we won't crash due
+ // to a buggy application.
+ ConstElementPtr datasrc_type = datasrc_elem->get("type");
+ if (!datasrc_type) {
+ isc_throw(AuthConfigError, "Missing data source type");
+ }
+
+ if (configured_sources_.find(datasrc_type->stringValue()) !=
+ configured_sources_.end()) {
+ isc_throw(AuthConfigError, "Data source type '" <<
+ datasrc_type->stringValue() << "' already configured");
+ }
+
+ shared_ptr<AuthConfigParser> datasrc_config =
+ shared_ptr<AuthConfigParser>(
+ createAuthConfigParser(server_, string("datasources/") +
+ datasrc_type->stringValue(),
+ true));
+ datasrc_config->build(datasrc_elem);
+ datasources_.push_back(datasrc_config);
+
+ configured_sources_.insert(datasrc_type->stringValue());
+ }
+}
+
+void
+DatasourcesConfig::commit() {
+ // XXX a short term workaround: clear all data sources and then reset
+ // to new ones so that we can remove data sources that don't exist in
+ // the new configuration and have been used in the server.
+ // This could be inefficient and requires knowledge about
+ // server implementation details, and isn't scalable wrt the number of
+ // data source types, and should eventually be improved.
+ // Currently memory data source for class IN is the only possibility.
+ server_.setMemoryDataSrc(RRClass::IN(), AuthSrv::MemoryDataSrcPtr());
+
+ BOOST_FOREACH(shared_ptr<AuthConfigParser> datasrc_config, datasources_) {
+ datasrc_config->commit();
+ }
+}
+
+/// A derived \c AuthConfigParser class for the memory type datasource
+/// configuration. It does not correspond to the configuration syntax;
+/// it's instantiated for internal use.
+class MemoryDatasourceConfig : public AuthConfigParser {
+public:
+ MemoryDatasourceConfig(AuthSrv& server) :
+ server_(server),
+ rrclass_(0) // XXX: dummy initial value
+ {}
+ virtual void build(ConstElementPtr config_value);
+ virtual void commit() {
+ server_.setMemoryDataSrc(rrclass_, memory_datasrc_);
+ }
+private:
+ AuthSrv& server_;
+ RRClass rrclass_;
+ AuthSrv::MemoryDataSrcPtr memory_datasrc_;
+};
+
+void
+MemoryDatasourceConfig::build(ConstElementPtr config_value) {
+ // XXX: apparently we cannot retrieve the default RR class from the
+ // module spec. As a temporary workaround we hardcode the default value.
+ ConstElementPtr rrclass_elem = config_value->get("class");
+ rrclass_ = RRClass(rrclass_elem ? rrclass_elem->stringValue() : "IN");
+
+ // We'd eventually optimize building zones (in case of reloading) by
+ // selectively loading fresh zones. Right now we simply check the
+ // RR class is supported by the server implementation.
+ server_.getMemoryDataSrc(rrclass_);
+ memory_datasrc_ = AuthSrv::MemoryDataSrcPtr(new MemoryDataSrc());
+
+ ConstElementPtr zones_config = config_value->get("zones");
+ if (!zones_config) {
+ // XXX: Like the RR class, we cannot retrieve the default value here,
+ // so we assume an empty zone list in this case.
+ return;
+ }
+
+ BOOST_FOREACH(ConstElementPtr zone_config, zones_config->listValue()) {
+ ConstElementPtr origin = zone_config->get("origin");
+ if (!origin) {
+ isc_throw(AuthConfigError, "Missing zone origin");
+ }
+ ConstElementPtr file = zone_config->get("file");
+ if (!file) {
+ isc_throw(AuthConfigError, "Missing zone file for zone: "
+ << origin->str());
+ }
+ shared_ptr<MemoryZone> new_zone(new MemoryZone(rrclass_,
+ Name(origin->stringValue())));
+ const result::Result result = memory_datasrc_->addZone(new_zone);
+ if (result == result::EXIST) {
+ isc_throw(AuthConfigError, "zone "<< origin->str()
+ << " already exists");
+ }
+
+ /*
+ * TODO: Once we have better reloading of configuration (something
+ * else than throwing everything away and loading it again), we will
+ * need the load method to be split into some kind of build and
+ * commit/abort parts.
+ */
+ new_zone->load(file->stringValue());
+ }
+}
+
+/// A derived \c AuthConfigParser class for the "statistics-internal"
+/// configuration identifier.
+class StatisticsIntervalConfig : public AuthConfigParser {
+public:
+ StatisticsIntervalConfig(AuthSrv& server) :
+ server_(server), interval_(0)
+ {}
+ virtual void build(ConstElementPtr config_value) {
+ const int32_t config_interval = config_value->intValue();
+ if (config_interval < 0) {
+ isc_throw(AuthConfigError, "Negative statistics interval value: "
+ << config_interval);
+ }
+ if (config_interval > 86400) {
+ isc_throw(AuthConfigError, "Statistics interval value "
+ << config_interval
+ << " must be equal to or shorter than 86400");
+ }
+ interval_ = config_interval;
+ }
+ virtual void commit() {
+ // setStatisticsTimerInterval() is not 100% exception free. But
+ // exceptions should happen only in a very rare situation, so we
+ // let them be thrown and subsequently regard them as a fatal error.
+ server_.setStatisticsTimerInterval(interval_);
+ }
+private:
+ AuthSrv& server_;
+ uint32_t interval_;
+};
+
+/// A special parser for testing: it throws from commit() despite the
+/// suggested convention of the class interface.
+class ThrowerCommitConfig : public AuthConfigParser {
+public:
+ virtual void build(ConstElementPtr) {} // ignore param, do nothing
+ virtual void commit() {
+ throw 10;
+ }
+};
+
+/**
+ * \brief Configuration parser for listen_on.
+ *
+ * It parses and sets the listening addresses of the server.
+ *
+ * It acts in unusual way. Since actually binding (changing) the sockets
+ * is an operation that is expected to throw often, it shouldn't happen
+ * in commit. Thefere we do it in build. But if the config is not committed
+ * then, we would have it wrong. So we store the old addresses and if
+ * commit is not called before destruction of the object, we return the
+ * old addresses (which is the same kind of dangerous operation, but it is
+ * expected that if we just managed to bind some and had the old ones binded
+ * before, it should work).
+ *
+ * We might do something better in future (like open only the ports that are
+ * extra, put them in in commit and close the old ones), but that's left out
+ * for now.
+ */
+class ListenAddressConfig : public AuthConfigParser {
+public:
+ ListenAddressConfig(AuthSrv& server) :
+ server_(server)
+ { }
+ ~ ListenAddressConfig() {
+ if (rollbackAddresses_.get() != NULL) {
+ server_.setListenAddresses(*rollbackAddresses_);
+ }
+ }
+private:
+ typedef auto_ptr<AddressList> AddrListPtr;
+public:
+ virtual void build(ConstElementPtr config) {
+ AddressList newAddresses = parseAddresses(config, "listen_on");
+ AddrListPtr old(new AddressList(server_.getListenAddresses()));
+ server_.setListenAddresses(newAddresses);
+ /*
+ * Set the rollback addresses only after successful setting of the
+ * new addresses, so we don't try to rollback if the setup is
+ * unsuccessful (the above can easily throw).
+ */
+ rollbackAddresses_ = old;
+ }
+ virtual void commit() {
+ rollbackAddresses_.release();
+ }
+private:
+ AuthSrv& server_;
+ /**
+ * This is the old address list, if we expect to roll back. When we commit,
+ * this is set to NULL.
+ */
+ AddrListPtr rollbackAddresses_;
+};
+
+// This is a generalized version of create function that can create
+// an AuthConfigParser object for "internal" use.
+AuthConfigParser*
+createAuthConfigParser(AuthSrv& server, const std::string& config_id,
+ bool internal)
+{
+ // For the initial implementation we use a naive if-else blocks for
+ // simplicity. In future we'll probably generalize it using map-like
+ // data structure, and may even provide external register interface so
+ // that it can be dynamically customized.
+ if (config_id == "datasources") {
+ return (new DatasourcesConfig(server));
+ } else if (config_id == "statistics-interval") {
+ return (new StatisticsIntervalConfig(server));
+ } else if (internal && config_id == "datasources/memory") {
+ return (new MemoryDatasourceConfig(server));
+ } else if (config_id == "listen_on") {
+ return (new ListenAddressConfig(server));
+ } else if (config_id == "_commit_throw") {
+ // This is for testing purpose only and should not appear in the
+ // actual configuration syntax. While this could crash the caller
+ // as a result, the server implementation is expected to perform
+ // syntax level validation and should be safe in practice. In future,
+ // we may introduce dynamic registration of configuration parsers,
+ // and then this test can be done in a cleaner and safer way.
+ return (new ThrowerCommitConfig());
+ } else {
+ isc_throw(AuthConfigError, "Unknown configuration identifier: " <<
+ config_id);
+ }
+}
+} // end of unnamed namespace
+
+AuthConfigParser*
+createAuthConfigParser(AuthSrv& server, const std::string& config_id) {
+ return (createAuthConfigParser(server, config_id, false));
+}
+
+void
+configureAuthServer(AuthSrv& server, ConstElementPtr config_set) {
+ if (!config_set) {
+ isc_throw(AuthConfigError,
+ "Null pointer is passed to configuration parser");
+ }
+
+ typedef shared_ptr<AuthConfigParser> ParserPtr;
+ vector<ParserPtr> parsers;
+ typedef pair<string, ConstElementPtr> ConfigPair;
+ try {
+ BOOST_FOREACH(ConfigPair config_pair, config_set->mapValue()) {
+ // We should eventually integrate the sqlite3 DB configuration to
+ // this framework, but to minimize diff we begin with skipping that
+ // part.
+ if (config_pair.first == "database_file") {
+ continue;
+ }
+
+ ParserPtr parser(createAuthConfigParser(server,
+ config_pair.first));
+ parser->build(config_pair.second);
+ parsers.push_back(parser);
+ }
+ } catch (const AuthConfigError& ex) {
+ throw; // simply rethrowing it
+ } catch (const isc::Exception& ex) {
+ isc_throw(AuthConfigError, "Server configuration failed: " <<
+ ex.what());
+ }
+
+ try {
+ BOOST_FOREACH(ParserPtr parser, parsers) {
+ parser->commit();
+ }
+ } catch (...) {
+ throw FatalError("Unrecoverable error: "
+ "a configuration parser threw in commit");
+ }
+}
diff --git a/src/bin/auth/auth_config.h b/src/bin/auth/auth_config.h
new file mode 100644
index 0000000..6f18810
--- /dev/null
+++ b/src/bin/auth/auth_config.h
@@ -0,0 +1,202 @@
+// Copyright (C) 2010 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 <string>
+
+#include <exceptions/exceptions.h>
+
+#include <cc/data.h>
+
+#ifndef __CONFIG_H
+#define __CONFIG_H 1
+
+class AuthSrv;
+
+/// An exception that is thrown if an error occurs while configuring an
+/// \c AuthSrv object.
+class AuthConfigError : public isc::Exception {
+public:
+ AuthConfigError(const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) {}
+};
+
+/// The abstract base class that represents a single configuration identifier
+/// for an \c AuthSrv object.
+///
+/// In general, each top level configuration identifier for \c AuthSrv is
+/// expected to have its own derived class of this base class.
+/// For example, for the following configuration:
+/// \code { "param1": 10, "param2": { "subparam1": "foo", "subparam2": [] } }
+/// \endcode
+/// "param1" and "param2" are top level identifiers, and would correspond to
+/// derived \c AuthConfigParser classes.
+/// "subparam1" and/or "subparam2" may also have dedicated derived classes.
+///
+/// These derived classes are hidden inside the implementation; applications
+/// are not expected to (and in fact cannot) instantiate them directly.
+///
+/// Each derived class is generally expected to be constructed with an
+/// \c AuthSrv object to be configured and hold a reference to the server
+/// throughout the configuration process.
+/// For each derived class, the \c build() method parses the configuration
+/// value for the corresponding identifier and prepares new configuration
+/// value(s) to be applied to the server. This method may throw an exception
+/// when it encounters an error.
+/// The \c commit() method actually applies the new configuration value
+/// to the server. It's basically not expected to throw an exception;
+/// any configuration operations that can fail (such as ones involving
+/// resource allocation) should be done in \c build().
+///
+/// When the destructor is called before \c commit(), the destructor is
+/// supposed to make sure the state of the \c AuthSrv object is the same
+/// as that before it starts building the configuration value.
+/// If \c build() doesn't change the server state (which is recommended)
+/// the destructor doesn't have to do anything special in this regard.
+/// This is a key to ensure the strong exception guarantee (see also
+/// the description of \c configureAuthServer()).
+class AuthConfigParser {
+ ///
+ /// \name Constructors and Destructor
+ ///
+ /// Note: The copy constructor and the assignment operator are
+ /// intentionally defined as private to make it explicit that this is a
+ /// pure base class.
+ //@{
+private:
+ AuthConfigParser(const AuthConfigParser& source);
+ AuthConfigParser& operator=(const AuthConfigParser& source);
+protected:
+ /// \brief The default constructor.
+ ///
+ /// This is intentionally defined as \c protected as this base class should
+ /// never be instantiated (except as part of a derived class).
+ AuthConfigParser() {}
+public:
+ /// The destructor.
+ virtual ~AuthConfigParser() {}
+ //@}
+
+ /// Prepare configuration value.
+ ///
+ /// This method parses the "value part" of the configuration identifier
+ /// that corresponds to this derived class and prepares a new value to
+ /// apply to the server.
+ /// In the above example, the derived class for the identifier "param1"
+ /// would be passed an data \c Element storing an integer whose value
+ /// is 10, and would record that value internally;
+ /// the derived class for the identifier "param2" would be passed a
+ /// map element and (after parsing) convert it into some internal
+ /// data structure.
+ ///
+ /// This method must validate the given value both in terms of syntax
+ /// and semantics of the configuration, so that the server will be
+ /// validly configured at the time of \c commit(). Note: the given
+ /// configuration value is normally syntactically validated, but the
+ /// \c build() implementation must also expect invalid input. If it
+ /// detects an error it may throw an exception of a derived class
+ /// of \c isc::Exception.
+ ///
+ /// Preparing a configuration value will often require resource
+ /// allocation. If it fails, it may throw a corresponding standard
+ /// exception.
+ ///
+ /// This method is not expected to be called more than once. Although
+ /// multiple calls are not prohibited by the interface, the behavior
+ /// is undefined.
+ ///
+ /// \param config_value The configuration value for the identifier
+ /// corresponding to the derived class.
+ virtual void build(isc::data::ConstElementPtr config_value) = 0;
+
+ /// Apply the prepared configuration value to the server.
+ ///
+ /// This method is expected to be exception free, and, as a consequence,
+ /// it should normally not involve resource allocation.
+ /// Typically it would simply perform exception free assignment or swap
+ /// operation on the value prepared in \c build().
+ /// In some cases, however, it may be very difficult to meet this
+ /// condition in a realistic way, while the failure case should really
+ /// be very rare. In such a case it may throw, and, if the parser is
+ /// called via \c configureAuthServer(), the caller will convert the
+ /// exception as a fatal error.
+ ///
+ /// This method is expected to be called after \c build(), and only once.
+ /// The result is undefined otherwise.
+ virtual void commit() = 0;
+};
+
+/// Configure an \c AuthSrv object with a set of configuration values.
+///
+/// This function parses configuration information stored in \c config_set
+/// and configures the \c server by applying the configuration to it.
+/// It provides the strong exception guarantee as long as the underlying
+/// derived class implementations of \c AuthConfigParser meet the assumption,
+/// that is, it ensures that either configuration is fully applied or the
+/// state of the server is intact.
+///
+/// If a syntax or semantics level error happens during the configuration
+/// (such as malformed configuration or invalid configuration parameter),
+/// this function throws an exception of class \c AuthConfigError.
+/// If the given configuration requires resource allocation and it fails,
+/// a corresponding standard exception will be thrown.
+/// Other exceptions may also be thrown, depending on the implementation of
+/// the underlying derived class of \c AuthConfigError.
+/// In any case the strong guarantee is provided as described above except
+/// in the very rare cases where the \c commit() method of a parser throws
+/// an exception. If that happens this function converts the exception
+/// into a \c FatalError exception and rethrows it. This exception is
+/// expected to be caught at the highest level of the application to terminate
+/// the program gracefully.
+///
+/// \param server The \c AuthSrv object to be configured.
+/// \param config_set A JSON style configuration to apply to \c server.
+void configureAuthServer(AuthSrv& server,
+ isc::data::ConstElementPtr config_set);
+
+/// Create a new \c AuthConfigParser object for a given configuration
+/// identifier.
+///
+/// It internally identifies an appropriate derived class for the given
+/// identifier and creates a new instance of that class. The caller can
+/// then configure the \c server regarding the identifier by calling
+/// the \c build() and \c commit() methods of the returned object.
+///
+/// In practice, this function is only expected to be used as a backend of
+/// \c configureAuthServer() and is not supposed to be called directly
+/// by applications. It is publicly available mainly for testing purposes.
+/// When called directly, the created object must be deleted by the caller.
+/// Note: this means if this module and the caller use incompatible sets of
+/// new/delete, it may cause unexpected strange failure. We could avoid that
+/// by providing a separate deallocation function or by using a smart pointer,
+/// but since the expected usage of this function is very limited (i.e. for
+/// our own testing purposes) it would be an overkilling. We therefore prefer
+/// simplicity and keeping the interface intuitive.
+///
+/// If the resource allocation for the new object fails, a corresponding
+/// standard exception will be thrown. Otherwise this function is not
+/// expected to throw an exception, unless the constructor of the underlying
+/// derived class implementation (unexpectedly) throws.
+///
+/// \param server The \c AuthSrv object to be configured.
+/// \param config_id The configuration identifier for which a parser object
+/// is to be created.
+/// \return A pointer to an \c AuthConfigParser object.
+AuthConfigParser* createAuthConfigParser(AuthSrv& server,
+ const std::string& config_id);
+
+#endif // __CONFIG_H
+
+// Local Variables:
+// mode: c++
+// End:
diff --git a/src/bin/auth/auth_srv.cc b/src/bin/auth/auth_srv.cc
index 297d509..a863ef3 100644
--- a/src/bin/auth/auth_srv.cc
+++ b/src/bin/auth/auth_srv.cc
@@ -53,7 +53,7 @@
#include <xfr/xfrout_client.h>
#include <auth/common.h>
-#include <auth/config.h>
+#include <auth/auth_config.h>
#include <auth/auth_srv.h>
#include <auth/query.h>
#include <auth/statistics.h>
@@ -70,7 +70,8 @@ using namespace isc::dns::rdata;
using namespace isc::data;
using namespace isc::config;
using namespace isc::xfr;
-using namespace asiolink;
+using namespace isc::asiolink;
+using namespace isc::asiodns;
using namespace isc::server_common::portconfig;
class AuthSrvImpl {
@@ -768,6 +769,6 @@ AuthSrv::setListenAddresses(const AddressList& addresses) {
}
void
-AuthSrv::setDNSService(asiolink::DNSService& dnss) {
+AuthSrv::setDNSService(isc::asiodns::DNSService& dnss) {
dnss_ = &dnss;
}
diff --git a/src/bin/auth/auth_srv.h b/src/bin/auth/auth_srv.h
index 8ccd4dc..88f00c1 100644
--- a/src/bin/auth/auth_srv.h
+++ b/src/bin/auth/auth_srv.h
@@ -23,6 +23,15 @@
#include <cc/data.h>
#include <config/ccsession.h>
+#include <dns/message.h>
+#include <util/buffer.h>
+
+#include <asiodns/dns_server.h>
+#include <asiodns/dns_lookup.h>
+#include <asiodns/dns_answer.h>
+#include <asiolink/io_message.h>
+#include <asiolink/io_service.h>
+#include <asiolink/simple_callback.h>
#include <asiolink/asiolink.h>
#include <server_common/portconfig.h>
@@ -107,10 +116,10 @@ public:
/// \param server Pointer to the \c DNSServer
///
/// \throw isc::Unexpected Protocol type of \a message is unexpected
- void processMessage(const asiolink::IOMessage& io_message,
+ void processMessage(const isc::asiolink::IOMessage& io_message,
isc::dns::MessagePtr message,
isc::util::OutputBufferPtr buffer,
- asiolink::DNSServer* server);
+ isc::asiodns::DNSServer* server);
/// \brief Set verbose flag
///
@@ -193,16 +202,16 @@ public:
void setConfigSession(isc::config::ModuleCCSession* config_session);
/// \brief Return this object's ASIO IO Service queue
- asiolink::IOService& getIOService();
+ isc::asiolink::IOService& getIOService();
/// \brief Return pointer to the DNS Lookup callback function
- asiolink::DNSLookup* getDNSLookupProvider() const { return (dns_lookup_); }
+ isc::asiodns::DNSLookup* getDNSLookupProvider() const { return (dns_lookup_); }
/// \brief Return pointer to the DNS Answer callback function
- asiolink::DNSAnswer* getDNSAnswerProvider() const { return (dns_answer_); }
+ isc::asiodns::DNSAnswer* getDNSAnswerProvider() const { return (dns_answer_); }
/// \brief Return pointer to the Checkin callback function
- asiolink::SimpleCallback* getCheckinProvider() const { return (checkin_); }
+ isc::asiolink::SimpleCallback* getCheckinProvider() const { return (checkin_); }
/// \brief Set or update the size (number of slots) of hot spot cache.
///
@@ -363,15 +372,15 @@ public:
const;
/// \brief Assign an ASIO DNS Service queue to this Auth object
- void setDNSService(asiolink::DNSService& dnss);
+ void setDNSService(isc::asiodns::DNSService& dnss);
private:
AuthSrvImpl* impl_;
- asiolink::SimpleCallback* checkin_;
- asiolink::DNSLookup* dns_lookup_;
- asiolink::DNSAnswer* dns_answer_;
- asiolink::DNSService* dnss_;
+ isc::asiolink::SimpleCallback* checkin_;
+ isc::asiodns::DNSLookup* dns_lookup_;
+ isc::asiodns::DNSAnswer* dns_answer_;
+ isc::asiodns::DNSService* dnss_;
};
#endif // __AUTH_SRV_H
diff --git a/src/bin/auth/benchmarks/Makefile.am b/src/bin/auth/benchmarks/Makefile.am
index 3078dd5..a569147 100644
--- a/src/bin/auth/benchmarks/Makefile.am
+++ b/src/bin/auth/benchmarks/Makefile.am
@@ -10,7 +10,7 @@ noinst_PROGRAMS = query_bench
query_bench_SOURCES = query_bench.cc
query_bench_SOURCES += ../query.h ../query.cc
query_bench_SOURCES += ../auth_srv.h ../auth_srv.cc
-query_bench_SOURCES += ../config.h ../config.cc
+query_bench_SOURCES += ../auth_config.h ../auth_config.cc
query_bench_SOURCES += ../statistics.h ../statistics.cc
query_bench_LDADD = $(top_builddir)/src/lib/dns/libdns++.la
@@ -22,6 +22,7 @@ query_bench_LDADD += $(top_builddir)/src/lib/cc/libcc.la
query_bench_LDADD += $(top_builddir)/src/lib/xfr/libxfr.la
query_bench_LDADD += $(top_builddir)/src/lib/log/liblog.la
query_bench_LDADD += $(top_builddir)/src/lib/nsas/libnsas.la
+query_bench_LDADD += $(top_builddir)/src/lib/asiodns/libasiodns.la
query_bench_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
query_bench_LDADD += $(top_builddir)/src/lib/server_common/libserver_common.la
query_bench_LDADD += $(SQLITE_LIBS)
diff --git a/src/bin/auth/benchmarks/query_bench.cc b/src/bin/auth/benchmarks/query_bench.cc
index 6421862..ba2e7b2 100644
--- a/src/bin/auth/benchmarks/query_bench.cc
+++ b/src/bin/auth/benchmarks/query_bench.cc
@@ -12,6 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+#include <config.h>
+
#include <stdlib.h>
#include <iostream>
@@ -31,9 +33,10 @@
#include <xfr/xfrout_client.h>
#include <auth/auth_srv.h>
-#include <auth/config.h>
+#include <auth/auth_config.h>
#include <auth/query.h>
+#include <asiodns/asiodns.h>
#include <asiolink/asiolink.h>
using namespace std;
@@ -44,7 +47,8 @@ using namespace isc::dns;
using namespace isc::util;
using namespace isc::xfr;
using namespace isc::bench;
-using namespace asiolink;
+using namespace isc::asiodns;
+using namespace isc::asiolink;
namespace {
// Commonly used constant:
diff --git a/src/bin/auth/common.cc b/src/bin/auth/common.cc
new file mode 100644
index 0000000..35381a1
--- /dev/null
+++ b/src/bin/auth/common.cc
@@ -0,0 +1,36 @@
+// Copyright (C) 2009-2011 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 <auth/common.h>
+#include <auth/spec_config.h>
+#include <stdlib.h>
+
+using std::string;
+
+string getXfroutSocketPath() {
+ if (getenv("B10_FROM_BUILD") != NULL) {
+ if (getenv("B10_FROM_SOURCE_LOCALSTATEDIR")) {
+ return (string(getenv("B10_FROM_SOURCE_LOCALSTATEDIR")) +
+ "/auth_xfrout_conn");
+ } else {
+ return (string(getenv("B10_FROM_BUILD")) + "/auth_xfrout_conn");
+ }
+ } else {
+ if (getenv("BIND10_XFROUT_SOCKET_FILE")) {
+ return (getenv("BIND10_XFROUT_SOCKET_FILE"));
+ } else {
+ return (UNIX_SOCKET_FILE);
+ }
+ }
+}
diff --git a/src/bin/auth/common.h b/src/bin/auth/common.h
index 6af09fb..b913593 100644
--- a/src/bin/auth/common.h
+++ b/src/bin/auth/common.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2009-2011 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
@@ -29,6 +29,15 @@ public:
{}
};
+/// \short Get the path of socket to talk to xfrout
+///
+/// It takes some environment variables into account (B10_FROM_BUILD,
+/// B10_FROM_SOURCE_LOCALSTATEDIR and BIND10_XFROUT_SOCKET_FILE). It
+/// also considers the installation prefix.
+///
+/// The logic should be the same as in b10-xfrout, so they find each other.
+std::string getXfroutSocketPath();
+
#endif // __COMMON_H
// Local Variables:
diff --git a/src/bin/auth/config.cc b/src/bin/auth/config.cc
deleted file mode 100644
index f289ca0..0000000
--- a/src/bin/auth/config.cc
+++ /dev/null
@@ -1,347 +0,0 @@
-// Copyright (C) 2010 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 <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <boost/foreach.hpp>
-#include <boost/shared_ptr.hpp>
-
-#include <dns/name.h>
-#include <dns/rrclass.h>
-
-#include <cc/data.h>
-
-#include <datasrc/memory_datasrc.h>
-#include <datasrc/zonetable.h>
-
-#include <auth/auth_srv.h>
-#include <auth/config.h>
-#include <auth/common.h>
-
-#include <server_common/portconfig.h>
-
-using namespace std;
-using boost::shared_ptr;
-using namespace isc::dns;
-using namespace isc::data;
-using namespace isc::datasrc;
-using namespace isc::server_common::portconfig;
-
-namespace {
-// Forward declaration
-AuthConfigParser*
-createAuthConfigParser(AuthSrv& server, const std::string& config_id,
- bool internal);
-
-/// A derived \c AuthConfigParser class for the "datasources" configuration
-/// identifier.
-class DatasourcesConfig : public AuthConfigParser {
-public:
- DatasourcesConfig(AuthSrv& server) : server_(server) {}
- virtual void build(ConstElementPtr config_value);
- virtual void commit();
-private:
- AuthSrv& server_;
- vector<shared_ptr<AuthConfigParser> > datasources_;
- set<string> configured_sources_;
-};
-
-void
-DatasourcesConfig::build(ConstElementPtr config_value) {
- BOOST_FOREACH(ConstElementPtr datasrc_elem, config_value->listValue()) {
- // The caller is supposed to perform syntax-level checks, but we'll
- // do minimum level of validation ourselves so that we won't crash due
- // to a buggy application.
- ConstElementPtr datasrc_type = datasrc_elem->get("type");
- if (!datasrc_type) {
- isc_throw(AuthConfigError, "Missing data source type");
- }
-
- if (configured_sources_.find(datasrc_type->stringValue()) !=
- configured_sources_.end()) {
- isc_throw(AuthConfigError, "Data source type '" <<
- datasrc_type->stringValue() << "' already configured");
- }
-
- shared_ptr<AuthConfigParser> datasrc_config =
- shared_ptr<AuthConfigParser>(
- createAuthConfigParser(server_, string("datasources/") +
- datasrc_type->stringValue(),
- true));
- datasrc_config->build(datasrc_elem);
- datasources_.push_back(datasrc_config);
-
- configured_sources_.insert(datasrc_type->stringValue());
- }
-}
-
-void
-DatasourcesConfig::commit() {
- // XXX a short term workaround: clear all data sources and then reset
- // to new ones so that we can remove data sources that don't exist in
- // the new configuration and have been used in the server.
- // This could be inefficient and requires knowledge about
- // server implementation details, and isn't scalable wrt the number of
- // data source types, and should eventually be improved.
- // Currently memory data source for class IN is the only possibility.
- server_.setMemoryDataSrc(RRClass::IN(), AuthSrv::MemoryDataSrcPtr());
-
- BOOST_FOREACH(shared_ptr<AuthConfigParser> datasrc_config, datasources_) {
- datasrc_config->commit();
- }
-}
-
-/// A derived \c AuthConfigParser class for the memory type datasource
-/// configuration. It does not correspond to the configuration syntax;
-/// it's instantiated for internal use.
-class MemoryDatasourceConfig : public AuthConfigParser {
-public:
- MemoryDatasourceConfig(AuthSrv& server) :
- server_(server),
- rrclass_(0) // XXX: dummy initial value
- {}
- virtual void build(ConstElementPtr config_value);
- virtual void commit() {
- server_.setMemoryDataSrc(rrclass_, memory_datasrc_);
- }
-private:
- AuthSrv& server_;
- RRClass rrclass_;
- AuthSrv::MemoryDataSrcPtr memory_datasrc_;
-};
-
-void
-MemoryDatasourceConfig::build(ConstElementPtr config_value) {
- // XXX: apparently we cannot retrieve the default RR class from the
- // module spec. As a temporary workaround we hardcode the default value.
- ConstElementPtr rrclass_elem = config_value->get("class");
- rrclass_ = RRClass(rrclass_elem ? rrclass_elem->stringValue() : "IN");
-
- // We'd eventually optimize building zones (in case of reloading) by
- // selectively loading fresh zones. Right now we simply check the
- // RR class is supported by the server implementation.
- server_.getMemoryDataSrc(rrclass_);
- memory_datasrc_ = AuthSrv::MemoryDataSrcPtr(new MemoryDataSrc());
-
- ConstElementPtr zones_config = config_value->get("zones");
- if (!zones_config) {
- // XXX: Like the RR class, we cannot retrieve the default value here,
- // so we assume an empty zone list in this case.
- return;
- }
-
- BOOST_FOREACH(ConstElementPtr zone_config, zones_config->listValue()) {
- ConstElementPtr origin = zone_config->get("origin");
- if (!origin) {
- isc_throw(AuthConfigError, "Missing zone origin");
- }
- ConstElementPtr file = zone_config->get("file");
- if (!file) {
- isc_throw(AuthConfigError, "Missing zone file for zone: "
- << origin->str());
- }
- shared_ptr<MemoryZone> new_zone(new MemoryZone(rrclass_,
- Name(origin->stringValue())));
- const result::Result result = memory_datasrc_->addZone(new_zone);
- if (result == result::EXIST) {
- isc_throw(AuthConfigError, "zone "<< origin->str()
- << " already exists");
- }
-
- /*
- * TODO: Once we have better reloading of configuration (something
- * else than throwing everything away and loading it again), we will
- * need the load method to be split into some kind of build and
- * commit/abort parts.
- */
- new_zone->load(file->stringValue());
- }
-}
-
-/// A derived \c AuthConfigParser class for the "statistics-internal"
-/// configuration identifier.
-class StatisticsIntervalConfig : public AuthConfigParser {
-public:
- StatisticsIntervalConfig(AuthSrv& server) :
- server_(server), interval_(0)
- {}
- virtual void build(ConstElementPtr config_value) {
- const int32_t config_interval = config_value->intValue();
- if (config_interval < 0) {
- isc_throw(AuthConfigError, "Negative statistics interval value: "
- << config_interval);
- }
- if (config_interval > 86400) {
- isc_throw(AuthConfigError, "Statistics interval value "
- << config_interval
- << " must be equal to or shorter than 86400");
- }
- interval_ = config_interval;
- }
- virtual void commit() {
- // setStatisticsTimerInterval() is not 100% exception free. But
- // exceptions should happen only in a very rare situation, so we
- // let them be thrown and subsequently regard them as a fatal error.
- server_.setStatisticsTimerInterval(interval_);
- }
-private:
- AuthSrv& server_;
- uint32_t interval_;
-};
-
-/// A special parser for testing: it throws from commit() despite the
-/// suggested convention of the class interface.
-class ThrowerCommitConfig : public AuthConfigParser {
-public:
- virtual void build(ConstElementPtr) {} // ignore param, do nothing
- virtual void commit() {
- throw 10;
- }
-};
-
-/**
- * \brief Configuration parser for listen_on.
- *
- * It parses and sets the listening addresses of the server.
- *
- * It acts in unusual way. Since actually binding (changing) the sockets
- * is an operation that is expected to throw often, it shouldn't happen
- * in commit. Thefere we do it in build. But if the config is not committed
- * then, we would have it wrong. So we store the old addresses and if
- * commit is not called before destruction of the object, we return the
- * old addresses (which is the same kind of dangerous operation, but it is
- * expected that if we just managed to bind some and had the old ones binded
- * before, it should work).
- *
- * We might do something better in future (like open only the ports that are
- * extra, put them in in commit and close the old ones), but that's left out
- * for now.
- */
-class ListenAddressConfig : public AuthConfigParser {
-public:
- ListenAddressConfig(AuthSrv& server) :
- server_(server)
- { }
- ~ ListenAddressConfig() {
- if (rollbackAddresses_.get() != NULL) {
- server_.setListenAddresses(*rollbackAddresses_);
- }
- }
-private:
- typedef auto_ptr<AddressList> AddrListPtr;
-public:
- virtual void build(ConstElementPtr config) {
- AddressList newAddresses = parseAddresses(config, "listen_on");
- AddrListPtr old(new AddressList(server_.getListenAddresses()));
- server_.setListenAddresses(newAddresses);
- /*
- * Set the rollback addresses only after successful setting of the
- * new addresses, so we don't try to rollback if the setup is
- * unsuccessful (the above can easily throw).
- */
- rollbackAddresses_ = old;
- }
- virtual void commit() {
- rollbackAddresses_.release();
- }
-private:
- AuthSrv& server_;
- /**
- * This is the old address list, if we expect to roll back. When we commit,
- * this is set to NULL.
- */
- AddrListPtr rollbackAddresses_;
-};
-
-// This is a generalized version of create function that can create
-// an AuthConfigParser object for "internal" use.
-AuthConfigParser*
-createAuthConfigParser(AuthSrv& server, const std::string& config_id,
- bool internal)
-{
- // For the initial implementation we use a naive if-else blocks for
- // simplicity. In future we'll probably generalize it using map-like
- // data structure, and may even provide external register interface so
- // that it can be dynamically customized.
- if (config_id == "datasources") {
- return (new DatasourcesConfig(server));
- } else if (config_id == "statistics-interval") {
- return (new StatisticsIntervalConfig(server));
- } else if (internal && config_id == "datasources/memory") {
- return (new MemoryDatasourceConfig(server));
- } else if (config_id == "listen_on") {
- return (new ListenAddressConfig(server));
- } else if (config_id == "_commit_throw") {
- // This is for testing purpose only and should not appear in the
- // actual configuration syntax. While this could crash the caller
- // as a result, the server implementation is expected to perform
- // syntax level validation and should be safe in practice. In future,
- // we may introduce dynamic registration of configuration parsers,
- // and then this test can be done in a cleaner and safer way.
- return (new ThrowerCommitConfig());
- } else {
- isc_throw(AuthConfigError, "Unknown configuration identifier: " <<
- config_id);
- }
-}
-} // end of unnamed namespace
-
-AuthConfigParser*
-createAuthConfigParser(AuthSrv& server, const std::string& config_id) {
- return (createAuthConfigParser(server, config_id, false));
-}
-
-void
-configureAuthServer(AuthSrv& server, ConstElementPtr config_set) {
- if (!config_set) {
- isc_throw(AuthConfigError,
- "Null pointer is passed to configuration parser");
- }
-
- typedef shared_ptr<AuthConfigParser> ParserPtr;
- vector<ParserPtr> parsers;
- typedef pair<string, ConstElementPtr> ConfigPair;
- try {
- BOOST_FOREACH(ConfigPair config_pair, config_set->mapValue()) {
- // We should eventually integrate the sqlite3 DB configuration to
- // this framework, but to minimize diff we begin with skipping that
- // part.
- if (config_pair.first == "database_file") {
- continue;
- }
-
- ParserPtr parser(createAuthConfigParser(server,
- config_pair.first));
- parser->build(config_pair.second);
- parsers.push_back(parser);
- }
- } catch (const AuthConfigError& ex) {
- throw; // simply rethrowing it
- } catch (const isc::Exception& ex) {
- isc_throw(AuthConfigError, "Server configuration failed: " <<
- ex.what());
- }
-
- try {
- BOOST_FOREACH(ParserPtr parser, parsers) {
- parser->commit();
- }
- } catch (...) {
- throw FatalError("Unrecoverable error: "
- "a configuration parser threw in commit");
- }
-}
diff --git a/src/bin/auth/config.h b/src/bin/auth/config.h
deleted file mode 100644
index 6f18810..0000000
--- a/src/bin/auth/config.h
+++ /dev/null
@@ -1,202 +0,0 @@
-// Copyright (C) 2010 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 <string>
-
-#include <exceptions/exceptions.h>
-
-#include <cc/data.h>
-
-#ifndef __CONFIG_H
-#define __CONFIG_H 1
-
-class AuthSrv;
-
-/// An exception that is thrown if an error occurs while configuring an
-/// \c AuthSrv object.
-class AuthConfigError : public isc::Exception {
-public:
- AuthConfigError(const char* file, size_t line, const char* what) :
- isc::Exception(file, line, what) {}
-};
-
-/// The abstract base class that represents a single configuration identifier
-/// for an \c AuthSrv object.
-///
-/// In general, each top level configuration identifier for \c AuthSrv is
-/// expected to have its own derived class of this base class.
-/// For example, for the following configuration:
-/// \code { "param1": 10, "param2": { "subparam1": "foo", "subparam2": [] } }
-/// \endcode
-/// "param1" and "param2" are top level identifiers, and would correspond to
-/// derived \c AuthConfigParser classes.
-/// "subparam1" and/or "subparam2" may also have dedicated derived classes.
-///
-/// These derived classes are hidden inside the implementation; applications
-/// are not expected to (and in fact cannot) instantiate them directly.
-///
-/// Each derived class is generally expected to be constructed with an
-/// \c AuthSrv object to be configured and hold a reference to the server
-/// throughout the configuration process.
-/// For each derived class, the \c build() method parses the configuration
-/// value for the corresponding identifier and prepares new configuration
-/// value(s) to be applied to the server. This method may throw an exception
-/// when it encounters an error.
-/// The \c commit() method actually applies the new configuration value
-/// to the server. It's basically not expected to throw an exception;
-/// any configuration operations that can fail (such as ones involving
-/// resource allocation) should be done in \c build().
-///
-/// When the destructor is called before \c commit(), the destructor is
-/// supposed to make sure the state of the \c AuthSrv object is the same
-/// as that before it starts building the configuration value.
-/// If \c build() doesn't change the server state (which is recommended)
-/// the destructor doesn't have to do anything special in this regard.
-/// This is a key to ensure the strong exception guarantee (see also
-/// the description of \c configureAuthServer()).
-class AuthConfigParser {
- ///
- /// \name Constructors and Destructor
- ///
- /// Note: The copy constructor and the assignment operator are
- /// intentionally defined as private to make it explicit that this is a
- /// pure base class.
- //@{
-private:
- AuthConfigParser(const AuthConfigParser& source);
- AuthConfigParser& operator=(const AuthConfigParser& source);
-protected:
- /// \brief The default constructor.
- ///
- /// This is intentionally defined as \c protected as this base class should
- /// never be instantiated (except as part of a derived class).
- AuthConfigParser() {}
-public:
- /// The destructor.
- virtual ~AuthConfigParser() {}
- //@}
-
- /// Prepare configuration value.
- ///
- /// This method parses the "value part" of the configuration identifier
- /// that corresponds to this derived class and prepares a new value to
- /// apply to the server.
- /// In the above example, the derived class for the identifier "param1"
- /// would be passed an data \c Element storing an integer whose value
- /// is 10, and would record that value internally;
- /// the derived class for the identifier "param2" would be passed a
- /// map element and (after parsing) convert it into some internal
- /// data structure.
- ///
- /// This method must validate the given value both in terms of syntax
- /// and semantics of the configuration, so that the server will be
- /// validly configured at the time of \c commit(). Note: the given
- /// configuration value is normally syntactically validated, but the
- /// \c build() implementation must also expect invalid input. If it
- /// detects an error it may throw an exception of a derived class
- /// of \c isc::Exception.
- ///
- /// Preparing a configuration value will often require resource
- /// allocation. If it fails, it may throw a corresponding standard
- /// exception.
- ///
- /// This method is not expected to be called more than once. Although
- /// multiple calls are not prohibited by the interface, the behavior
- /// is undefined.
- ///
- /// \param config_value The configuration value for the identifier
- /// corresponding to the derived class.
- virtual void build(isc::data::ConstElementPtr config_value) = 0;
-
- /// Apply the prepared configuration value to the server.
- ///
- /// This method is expected to be exception free, and, as a consequence,
- /// it should normally not involve resource allocation.
- /// Typically it would simply perform exception free assignment or swap
- /// operation on the value prepared in \c build().
- /// In some cases, however, it may be very difficult to meet this
- /// condition in a realistic way, while the failure case should really
- /// be very rare. In such a case it may throw, and, if the parser is
- /// called via \c configureAuthServer(), the caller will convert the
- /// exception as a fatal error.
- ///
- /// This method is expected to be called after \c build(), and only once.
- /// The result is undefined otherwise.
- virtual void commit() = 0;
-};
-
-/// Configure an \c AuthSrv object with a set of configuration values.
-///
-/// This function parses configuration information stored in \c config_set
-/// and configures the \c server by applying the configuration to it.
-/// It provides the strong exception guarantee as long as the underlying
-/// derived class implementations of \c AuthConfigParser meet the assumption,
-/// that is, it ensures that either configuration is fully applied or the
-/// state of the server is intact.
-///
-/// If a syntax or semantics level error happens during the configuration
-/// (such as malformed configuration or invalid configuration parameter),
-/// this function throws an exception of class \c AuthConfigError.
-/// If the given configuration requires resource allocation and it fails,
-/// a corresponding standard exception will be thrown.
-/// Other exceptions may also be thrown, depending on the implementation of
-/// the underlying derived class of \c AuthConfigError.
-/// In any case the strong guarantee is provided as described above except
-/// in the very rare cases where the \c commit() method of a parser throws
-/// an exception. If that happens this function converts the exception
-/// into a \c FatalError exception and rethrows it. This exception is
-/// expected to be caught at the highest level of the application to terminate
-/// the program gracefully.
-///
-/// \param server The \c AuthSrv object to be configured.
-/// \param config_set A JSON style configuration to apply to \c server.
-void configureAuthServer(AuthSrv& server,
- isc::data::ConstElementPtr config_set);
-
-/// Create a new \c AuthConfigParser object for a given configuration
-/// identifier.
-///
-/// It internally identifies an appropriate derived class for the given
-/// identifier and creates a new instance of that class. The caller can
-/// then configure the \c server regarding the identifier by calling
-/// the \c build() and \c commit() methods of the returned object.
-///
-/// In practice, this function is only expected to be used as a backend of
-/// \c configureAuthServer() and is not supposed to be called directly
-/// by applications. It is publicly available mainly for testing purposes.
-/// When called directly, the created object must be deleted by the caller.
-/// Note: this means if this module and the caller use incompatible sets of
-/// new/delete, it may cause unexpected strange failure. We could avoid that
-/// by providing a separate deallocation function or by using a smart pointer,
-/// but since the expected usage of this function is very limited (i.e. for
-/// our own testing purposes) it would be an overkilling. We therefore prefer
-/// simplicity and keeping the interface intuitive.
-///
-/// If the resource allocation for the new object fails, a corresponding
-/// standard exception will be thrown. Otherwise this function is not
-/// expected to throw an exception, unless the constructor of the underlying
-/// derived class implementation (unexpectedly) throws.
-///
-/// \param server The \c AuthSrv object to be configured.
-/// \param config_id The configuration identifier for which a parser object
-/// is to be created.
-/// \return A pointer to an \c AuthConfigParser object.
-AuthConfigParser* createAuthConfigParser(AuthSrv& server,
- const std::string& config_id);
-
-#endif // __CONFIG_H
-
-// Local Variables:
-// mode: c++
-// End:
diff --git a/src/bin/auth/main.cc b/src/bin/auth/main.cc
index b47395f..a6db762 100644
--- a/src/bin/auth/main.cc
+++ b/src/bin/auth/main.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2009-2011 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
@@ -12,6 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+#include <config.h>
+
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
@@ -38,10 +40,11 @@
#include <auth/spec_config.h>
#include <auth/common.h>
-#include <auth/config.h>
+#include <auth/auth_config.h>
#include <auth/command.h>
#include <auth/change_user.h>
#include <auth/auth_srv.h>
+#include <asiodns/asiodns.h>
#include <asiolink/asiolink.h>
#include <log/dummylog.h>
@@ -52,7 +55,8 @@ using namespace isc::config;
using namespace isc::dns;
using namespace isc::util;
using namespace isc::xfr;
-using namespace asiolink;
+using namespace isc::asiolink;
+using namespace isc::asiodns;
namespace {
@@ -122,19 +126,7 @@ main(int argc, char* argv[]) {
bool xfrin_session_established = false; // XXX (see Trac #287)
bool statistics_session_established = false; // XXX (see Trac #287)
ModuleCCSession* config_session = NULL;
- string xfrout_socket_path;
- if (getenv("B10_FROM_BUILD") != NULL) {
- if (getenv("B10_FROM_SOURCE_LOCALSTATEDIR")) {
- xfrout_socket_path = string("B10_FROM_SOURCE_LOCALSTATEDIR") +
- "/auth_xfrout_conn";
- } else {
- xfrout_socket_path = string(getenv("B10_FROM_BUILD")) +
- "/auth_xfrout_conn";
- }
- } else {
- xfrout_socket_path = UNIX_SOCKET_FILE;
- }
- XfroutClient xfrout_client(xfrout_socket_path);
+ XfroutClient xfrout_client(getXfroutSocketPath());
try {
string specfile;
if (getenv("B10_FROM_BUILD")) {
diff --git a/src/bin/auth/tests/Makefile.am b/src/bin/auth/tests/Makefile.am
index 7d489a1..026dde3 100644
--- a/src/bin/auth/tests/Makefile.am
+++ b/src/bin/auth/tests/Makefile.am
@@ -1,4 +1,5 @@
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CPPFLAGS += -I$(top_builddir)/src/bin # for generated spec_config.h header
AM_CPPFLAGS += -I$(top_builddir)/src/lib/dns -I$(top_srcdir)/src/bin
AM_CPPFLAGS += -I$(top_builddir)/src/lib/cc
AM_CPPFLAGS += $(BOOST_INCLUDES)
@@ -16,18 +17,23 @@ CLEANFILES = *.gcno *.gcda
TESTS =
if HAVE_GTEST
+
+BUILT_SOURCES = ../spec_config.h
TESTS += run_unittests
run_unittests_SOURCES = $(top_srcdir)/src/lib/dns/tests/unittest_util.h
run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.cc
run_unittests_SOURCES += ../auth_srv.h ../auth_srv.cc
run_unittests_SOURCES += ../query.h ../query.cc
run_unittests_SOURCES += ../change_user.h ../change_user.cc
-run_unittests_SOURCES += ../config.h ../config.cc
+run_unittests_SOURCES += ../auth_config.h ../auth_config.cc
run_unittests_SOURCES += ../command.h ../command.cc
+run_unittests_SOURCES += ../common.h ../common.cc
+run_unittests_SOURCES += ../spec_config.h
run_unittests_SOURCES += ../statistics.h ../statistics.cc
run_unittests_SOURCES += auth_srv_unittest.cc
run_unittests_SOURCES += config_unittest.cc
run_unittests_SOURCES += command_unittest.cc
+run_unittests_SOURCES += common_unittest.cc
run_unittests_SOURCES += query_unittest.cc
run_unittests_SOURCES += change_user_unittest.cc
run_unittests_SOURCES += statistics_unittest.cc
@@ -39,6 +45,7 @@ run_unittests_LDADD += $(SQLITE_LIBS)
run_unittests_LDADD += $(top_builddir)/src/lib/testutils/libtestutils.la
run_unittests_LDADD += $(top_builddir)/src/lib/datasrc/libdatasrc.la
run_unittests_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
+run_unittests_LDADD += $(top_builddir)/src/lib/asiodns/libasiodns.la
run_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
run_unittests_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
run_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.la
diff --git a/src/bin/auth/tests/auth_srv_unittest.cc b/src/bin/auth/tests/auth_srv_unittest.cc
index 4ac7352..a77f7e6 100644
--- a/src/bin/auth/tests/auth_srv_unittest.cc
+++ b/src/bin/auth/tests/auth_srv_unittest.cc
@@ -45,7 +45,8 @@ using namespace isc::util;
using namespace isc::dns::rdata;
using namespace isc::data;
using namespace isc::xfr;
-using namespace asiolink;
+using namespace isc::asiodns;
+using namespace isc::asiolink;
using namespace isc::testutils;
using namespace isc::server_common::portconfig;
using isc::UnitTestUtil;
diff --git a/src/bin/auth/tests/command_unittest.cc b/src/bin/auth/tests/command_unittest.cc
index f788d9e..3fdd086 100644
--- a/src/bin/auth/tests/command_unittest.cc
+++ b/src/bin/auth/tests/command_unittest.cc
@@ -12,6 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+#include <config.h>
+
#include <cassert>
#include <cstdlib>
#include <string>
@@ -32,7 +34,7 @@
#include <datasrc/memory_datasrc.h>
#include <auth/auth_srv.h>
-#include <auth/config.h>
+#include <auth/auth_config.h>
#include <auth/command.h>
#include <asiolink/asiolink.h>
@@ -97,7 +99,7 @@ AuthConmmandTest::stopServer() {
}
TEST_F(AuthConmmandTest, shutdown) {
- asiolink::IntervalTimer itimer(server.getIOService());
+ isc::asiolink::IntervalTimer itimer(server.getIOService());
itimer.setup(boost::bind(&AuthConmmandTest::stopServer, this), 1);
server.getIOService().run();
EXPECT_EQ(0, rcode);
diff --git a/src/bin/auth/tests/common_unittest.cc b/src/bin/auth/tests/common_unittest.cc
new file mode 100644
index 0000000..9b18142
--- /dev/null
+++ b/src/bin/auth/tests/common_unittest.cc
@@ -0,0 +1,96 @@
+// Copyright (C) 2011 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 <gtest/gtest.h>
+#include <auth/common.h>
+#include <auth/spec_config.h>
+#include <vector>
+#include <string>
+#include <cstdio>
+#include <boost/foreach.hpp>
+
+using std::pair;
+using std::vector;
+using std::string;
+
+namespace {
+
+class Paths : public ::testing::Test {
+private:
+ typedef pair<string, string*> Environ;
+ vector<Environ> restoreEnviron;
+public:
+ void TearDown() {
+ // Restore the original environment
+ BOOST_FOREACH(const Environ &env, restoreEnviron) {
+ if (env.second == NULL) {
+ EXPECT_EQ(0, unsetenv(env.first.c_str())) <<
+ "Couldn't restore environment, results of other tests"
+ "are uncertain";
+ } else {
+ EXPECT_EQ(0, setenv(env.first.c_str(), env.second->c_str(),
+ 1)) << "Couldn't restore environment, "
+ "results of other tests are uncertain";
+ }
+ }
+ }
+protected:
+ // Sets a temporary value into environment. If value is empty, it deletes
+ // the variable from environment (just for simplicity).
+ void setEnv(const string& name, const string& value) {
+ // Backup the original environment
+ char* env(getenv(name.c_str()));
+ restoreEnviron.push_back(Environ(name, env == NULL ? NULL :
+ new string(env)));
+ // Set the new value
+ if (value.empty()) {
+ EXPECT_EQ(0, unsetenv(name.c_str()));
+ } else {
+ EXPECT_EQ(0, setenv(name.c_str(), value.c_str(), 1));
+ }
+ }
+ // Test getXfroutSocketPath under given environment
+ void testXfrout(const string& fromBuild, const string& localStateDir,
+ const string& socketFile, const string& expected)
+ {
+ setEnv("B10_FROM_BUILD", fromBuild);
+ setEnv("B10_FROM_SOURCE_LOCALSTATEDIR", localStateDir);
+ setEnv("BIND10_XFROUT_SOCKET_FILE", socketFile);
+ EXPECT_EQ(expected, getXfroutSocketPath());
+ }
+};
+
+// Test that when we have no special environment, we get the default from prefix
+TEST_F(Paths, xfroutNoEnv) {
+ testXfrout("", "", "", UNIX_SOCKET_FILE);
+}
+
+// Override by B10_FROM_BUILD
+TEST_F(Paths, xfroutFromBuild) {
+ testXfrout("/from/build", "", "/wrong/path",
+ "/from/build/auth_xfrout_conn");
+}
+
+// Override by B10_FROM_SOURCE_LOCALSTATEDIR
+TEST_F(Paths, xfroutLocalStatedir) {
+ testXfrout("/wrong/path", "/state/dir", "/wrong/path",
+ "/state/dir/auth_xfrout_conn");
+}
+
+// Override by BIND10_XFROUT_SOCKET_FILE explicitly
+TEST_F(Paths, xfroutFromEnv) {
+ testXfrout("", "", "/the/path/to/file", "/the/path/to/file");
+}
+
+}
diff --git a/src/bin/auth/tests/config_unittest.cc b/src/bin/auth/tests/config_unittest.cc
index 8cce0af..7658b84 100644
--- a/src/bin/auth/tests/config_unittest.cc
+++ b/src/bin/auth/tests/config_unittest.cc
@@ -26,7 +26,7 @@
#include <xfr/xfrout_client.h>
#include <auth/auth_srv.h>
-#include <auth/config.h>
+#include <auth/auth_config.h>
#include <auth/common.h>
#include <testutils/mockups.h>
@@ -35,7 +35,8 @@
using namespace isc::dns;
using namespace isc::data;
using namespace isc::datasrc;
-using namespace asiolink;
+using namespace isc::asiodns;
+using namespace isc::asiolink;
namespace {
class AuthConfigTest : public ::testing::Test {
diff --git a/src/bin/bind10/bind10.8 b/src/bin/bind10/bind10.8
index a75136b..d5ab905 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: February 22, 2011
+.\" Date: March 31, 2011
.\" Manual: BIND10
.\" Source: BIND10
.\" Language: English
.\"
-.TH "BIND10" "8" "February 22, 2011" "BIND10" "BIND10"
+.TH "BIND10" "8" "March 31, 2011" "BIND10" "BIND10"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -22,7 +22,7 @@
bind10 \- BIND 10 boss process
.SH "SYNOPSIS"
.HP \w'\fBbind10\fR\ 'u
-\fBbind10\fR [\fB\-m\ \fR\fB\fIfile\fR\fR] [\fB\-n\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-\-msgq\-socket\-file\ \fR\fB\fIfile\fR\fR] [\fB\-\-no\-cache\fR] [\fB\-\-user\ \fR\fB\fIuser\fR\fR] [\fB\-\-pretty\-name\ \fR\fB\fIname\fR\fR] [\fB\-\-verbose\fR]
+\fBbind10\fR [\fB\-c\ \fR\fB\fIconfig\-filename\fR\fR] [\fB\-m\ \fR\fB\fIfile\fR\fR] [\fB\-n\fR] [\fB\-p\ \fR\fB\fIdata_path\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-\-brittle\fR] [\fB\-\-cmdctl\-port\fR\ \fIport\fR] [\fB\-\-config\-file\fR\ \fIconfig\-filename\fR] [\fB\-\-data\-path\fR\ \fIdirectory\fR] [\fB\-\-msgq\-socket\-file\ \fR\fB\fIfile\fR\fR] [\fB\-\-no\-cache\fR] [\fB\-\-pid\-file\fR\ \fIfilename\fR] [\fB\-\-pretty\-name\ \fR\fB\fIname\fR\fR] [\fB\-\-user\ \fR\fB\fIuser\fR\fR] [\fB\-\-verbose\fR]
.SH "DESCRIPTION"
.PP
The
@@ -32,6 +32,34 @@ daemon starts up other BIND 10 required daemons\&. It handles restarting of exit
.PP
The arguments are as follows:
.PP
+\fB\-\-brittle\fR
+.RS 4
+Shutdown if any of the child processes of
+\fBbind10\fR
+exit\&. This is intended to help developers debug the server, and should not be used in production\&.
+.RE
+.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\&.
+.RE
+.PP
+\fB\-\-cmdctl\-port\fR \fIport\fR
+.RS 4
+The
+\fBb10\-cmdctl\fR
+daemon will listen on this port\&. (See
+b10\-cmdctl(8)
+for the default\&.)
+.RE
+.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\&.
+.RE
+.PP
\fB\-m\fR \fIfile\fR, \fB\-\-msgq\-socket\-file\fR \fIfile\fR
.RS 4
The UNIX domain socket file for the
@@ -57,6 +85,13 @@ to run as\&.
must be initially ran as the root user to use this option\&. The default is to run as the current user\&.
.RE
.PP
+\fB\-\-pid\-file\fR \fIfilename\fR
+.RS 4
+If defined, the PID of the
+\fBbind10\fR
+is stored in this file\&. This is used for testing purposes\&.
+.RE
+.PP
\fB\-\-pretty\-name \fR\fB\fIname\fR\fR
.RS 4
The name this process should have in tools like
diff --git a/src/bin/bind10/bind10.py.in b/src/bin/bind10/bind10.py.in
index bd0cd82..e6504e1 100755
--- a/src/bin/bind10/bind10.py.in
+++ b/src/bin/bind10/bind10.py.in
@@ -202,7 +202,7 @@ class BoB:
def __init__(self, msgq_socket_file=None, data_path=None,
config_filename=None, nocache=False, verbose=False, setuid=None,
- username=None, cmdctl_port=None):
+ username=None, cmdctl_port=None, brittle=False):
"""
Initialize the Boss of BIND. This is a singleton (only one can run).
@@ -235,6 +235,7 @@ class BoB:
self.data_path = data_path
self.config_filename = config_filename
self.cmdctl_port = cmdctl_port
+ self.brittle = brittle
def config_handler(self, new_config):
# If this is initial update, don't do anything now, leave it to startup
@@ -296,7 +297,7 @@ class BoB:
def command_handler(self, command, args):
if self.verbose:
- sys.stdout.write("[bind10] Boss got command: " + command + "\n")
+ sys.stdout.write("[bind10] Boss got command: " + str(command) + "\n")
answer = isc.config.ccsession.create_answer(1, "command not implemented")
if type(command) != str:
answer = isc.config.ccsession.create_answer(1, "bad command")
@@ -304,6 +305,15 @@ class BoB:
if command == "shutdown":
self.runnable = False
answer = isc.config.ccsession.create_answer(0)
+ elif command == "sendstats":
+ # send statistics data to the stats daemon immediately
+ cmd = isc.config.ccsession.create_command(
+ 'set', { "stats_data": {
+ 'bind10.boot_time': time.strftime('%Y-%m-%dT%H:%M:%SZ', _BASETIME)
+ }})
+ seq = self.cc_session.group_sendmsg(cmd, 'Stats')
+ self.cc_session.group_recvmsg(True, seq)
+ answer = isc.config.ccsession.create_answer(0)
elif command == "ping":
answer = isc.config.ccsession.create_answer(0, "pong")
elif command == "show_processes":
@@ -710,20 +720,22 @@ class BoB:
if self.verbose:
sys.stdout.write("[bind10] All processes ended, server done.\n")
+ def _get_process_exit_status(self):
+ return os.waitpid(-1, os.WNOHANG)
+
def reap_children(self):
"""Check to see if any of our child processes have exited,
and note this for later handling.
"""
while True:
try:
- (pid, exit_status) = os.waitpid(-1, os.WNOHANG)
+ (pid, exit_status) = self._get_process_exit_status()
except OSError as o:
if o.errno == errno.ECHILD: break
# XXX: should be impossible to get any other error here
raise
if pid == 0: break
if pid in self.processes:
-
# One of the processes we know about. Get information on it.
proc_info = self.processes.pop(pid)
proc_info.restart_schedule.set_run_stop_time()
@@ -747,6 +759,11 @@ class BoB:
sys.stdout.write(
"[bind10] The b10-msgq process died, shutting down.\n")
self.runnable = False
+
+ # If we're in 'brittle' mode, we want to shutdown after
+ # any process dies.
+ if self.brittle:
+ self.runnable = False
else:
sys.stdout.write("[bind10] Unknown child pid %d exited.\n" % pid)
@@ -856,6 +873,8 @@ def parse_args(args=sys.argv[1:], Parser=OptionParser):
parser.add_option("--pid-file", dest="pid_file", type="string",
default=None,
help="file to dump the PID of the BIND 10 process")
+ parser.add_option("--brittle", dest="brittle", action="store_true",
+ help="debugging flag: exit if any component dies")
(options, args) = parser.parse_args(args)
@@ -959,7 +978,7 @@ def main():
# Go bob!
boss_of_bind = BoB(options.msgq_socket_file, options.data_path,
options.config_file, options.nocache, options.verbose,
- setuid, username, options.cmdctl_port)
+ setuid, username, options.cmdctl_port, options.brittle)
startup_result = boss_of_bind.startup()
if startup_result:
sys.stderr.write("[bind10] Error on startup: %s\n" % startup_result)
@@ -967,17 +986,6 @@ def main():
sys.stdout.write("[bind10] BIND 10 started\n")
dump_pid(options.pid_file)
- # send "bind10.boot_time" to b10-stats
- time.sleep(1) # wait a second
- if options.verbose:
- sys.stdout.write("[bind10] send \"bind10.boot_time\" to b10-stats\n")
- cmd = isc.config.ccsession.create_command('set',
- { "stats_data": {
- 'bind10.boot_time': time.strftime('%Y-%m-%dT%H:%M:%SZ', _BASETIME)
- }
- })
- boss_of_bind.cc_session.group_sendmsg(cmd, 'Stats')
-
# In our main loop, we check for dead processes or messages
# on the c-channel.
wakeup_fd = wakeup_pipe[0]
diff --git a/src/bin/bind10/bind10.xml b/src/bin/bind10/bind10.xml
index 6331503..1128264 100644
--- a/src/bin/bind10/bind10.xml
+++ b/src/bin/bind10/bind10.xml
@@ -20,7 +20,7 @@
<refentry>
<refentryinfo>
- <date>February 22, 2011</date>
+ <date>March 31, 2011</date>
</refentryinfo>
<refmeta>
@@ -44,16 +44,21 @@
<refsynopsisdiv>
<cmdsynopsis>
<command>bind10</command>
+ <arg><option>-c <replaceable>config-filename</replaceable></option></arg>
<arg><option>-m <replaceable>file</replaceable></option></arg>
<arg><option>-n</option></arg>
+ <arg><option>-p <replaceable>data_path</replaceable></option></arg>
<arg><option>-u <replaceable>user</replaceable></option></arg>
<arg><option>-v</option></arg>
- <arg><option>-c<replaceable>config-filename</replaceable></option></arg>
- <arg><option>-p<replaceable>data_path</replaceable></option></arg>
+ <arg><option>--brittle</option></arg>
+ <arg><option>--cmdctl-port</option> <replaceable>port</replaceable></arg>
+ <arg><option>--config-file</option> <replaceable>config-filename</replaceable></arg>
+ <arg><option>--data-path</option> <replaceable>directory</replaceable></arg>
<arg><option>--msgq-socket-file <replaceable>file</replaceable></option></arg>
<arg><option>--no-cache</option></arg>
- <arg><option>--user <replaceable>user</replaceable></option></arg>
+ <arg><option>--pid-file</option> <replaceable>filename</replaceable></arg>
<arg><option>--pretty-name <replaceable>name</replaceable></option></arg>
+ <arg><option>--user <replaceable>user</replaceable></option></arg>
<arg><option>--verbose</option></arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -82,9 +87,24 @@
<para>The arguments are as follows:</para>
<variablelist>
+
+ <varlistentry>
+ <term>
+ <option>--brittle</option>
+ </term>
+ <listitem>
+ <para>
+ Shutdown if any of the child processes of
+ <command>bind10</command> exit. This is intended to
+ help developers debug the server, and should not be
+ used in production.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term>
- <option>-c</option><replaceable>config-filename</replaceable>,
+ <option>-c</option> <replaceable>config-filename</replaceable>,
<option>--config-file</option> <replaceable>config-filename</replaceable>
</term>
<listitem>
@@ -97,8 +117,22 @@
<varlistentry>
<term>
- <option>-p</option><replaceable>data-path</replaceable>,
- <option>--data-path</option> <replaceable>data-path</replaceable>
+ <option>--cmdctl-port</option> <replaceable>port</replaceable>
+ </term>
+ <listitem>
+ <para>The <command>b10-cmdctl</command> daemon will listen
+ on this port.
+ (See
+ <refentrytitle>b10-cmdctl</refentrytitle><manvolnum>8</manvolnum>
+ for the default.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>-p</option> <replaceable>directory</replaceable>,
+ <option>--data-path</option> <replaceable>directory</replaceable>
</term>
<listitem>
<para>The path where BIND 10 programs look for various data files.
@@ -134,7 +168,6 @@
<varlistentry>
<term><option>-u</option> <replaceable>user</replaceable>, <option>--user</option> <replaceable>name</replaceable></term>
-
<listitem>
<para>The username for <command>bind10</command> to run as.
<!-- TODO: example more detail. -->
@@ -145,6 +178,16 @@
</varlistentry>
<varlistentry>
+ <term><option>--pid-file</option> <replaceable>filename</replaceable></term>
+ <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>
+
+ <varlistentry>
<term><option>--pretty-name <replaceable>name</replaceable></option></term>
<listitem>
diff --git a/src/bin/bind10/bob.spec b/src/bin/bind10/bob.spec
index c206b34..1184fd1 100644
--- a/src/bin/bind10/bob.spec
+++ b/src/bin/bind10/bob.spec
@@ -23,6 +23,11 @@
"command_args": []
},
{
+ "command_name": "sendstats",
+ "command_description": "Send data to a statistics module at once",
+ "command_args": []
+ },
+ {
"command_name": "ping",
"command_description": "Ping the boss process",
"command_args": []
diff --git a/src/bin/bind10/tests/Makefile.am b/src/bin/bind10/tests/Makefile.am
index d05d977..34d809a 100644
--- a/src/bin/bind10/tests/Makefile.am
+++ b/src/bin/bind10/tests/Makefile.am
@@ -1,5 +1,6 @@
PYCOVERAGE_RUN = @PYCOVERAGE_RUN@
#PYTESTS = args_test.py bind10_test.py
+# NOTE: this has a generated test found in the builddir
PYTESTS = bind10_test.py
EXTRA_DIST = $(PYTESTS)
@@ -14,5 +15,5 @@ endif
echo Running test: $$pytest ; \
env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/bin/bind10 \
BIND10_MSGQ_SOCKET_FILE=$(abs_top_builddir)/msgq_socket \
- $(PYCOVERAGE_RUN) $(abs_srcdir)/$$pytest || exit ; \
+ $(PYCOVERAGE_RUN) $(abs_builddir)/$$pytest || exit ; \
done
diff --git a/src/bin/bind10/tests/bind10_test.py.in b/src/bin/bind10/tests/bind10_test.py.in
index 368fdbd..8432c89 100644
--- a/src/bin/bind10/tests/bind10_test.py.in
+++ b/src/bin/bind10/tests/bind10_test.py.in
@@ -13,7 +13,7 @@
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-from bind10 import ProcessInfo, BoB, parse_args, dump_pid, unlink_pid_file
+from bind10 import ProcessInfo, BoB, parse_args, dump_pid, unlink_pid_file, _BASETIME
# XXX: environment tests are currently disabled, due to the preprocessor
# setup that we have now complicating the environment
@@ -24,6 +24,9 @@ import os
import signal
import socket
from isc.net.addr import IPAddr
+import time
+import isc
+
from isc.testutils.parse_args import TestOptParser, OptsError
class TestProcessInfo(unittest.TestCase):
@@ -123,6 +126,41 @@ class TestBoB(unittest.TestCase):
self.assertEqual(bob.cfg_start_auth, True)
self.assertEqual(bob.cfg_start_resolver, False)
+ def test_command_handler(self):
+ class DummySession():
+ def group_sendmsg(self, msg, group):
+ (self.msg, self.group) = (msg, group)
+ def group_recvmsg(self, nonblock, seq): pass
+ bob = BoB()
+ bob.verbose = True
+ bob.cc_session = DummySession()
+ # a bad command
+ self.assertEqual(bob.command_handler(-1, None),
+ isc.config.ccsession.create_answer(1, "bad command"))
+ # "shutdown" command
+ self.assertEqual(bob.command_handler("shutdown", None),
+ isc.config.ccsession.create_answer(0))
+ self.assertFalse(bob.runnable)
+ # "sendstats" command
+ self.assertEqual(bob.command_handler("sendstats", None),
+ isc.config.ccsession.create_answer(0))
+ self.assertEqual(bob.cc_session.group, "Stats")
+ self.assertEqual(bob.cc_session.msg,
+ isc.config.ccsession.create_command(
+ 'set', { "stats_data": {
+ 'bind10.boot_time': time.strftime('%Y-%m-%dT%H:%M:%SZ', _BASETIME)
+ }}))
+ # "ping" command
+ self.assertEqual(bob.command_handler("ping", None),
+ isc.config.ccsession.create_answer(0, "pong"))
+ # "show_processes" command
+ self.assertEqual(bob.command_handler("show_processes", None),
+ isc.config.ccsession.create_answer(0,
+ bob.get_processes()))
+ # an unknown command
+ self.assertEqual(bob.command_handler("__UNKNOWN__", None),
+ isc.config.ccsession.create_answer(1, "Unknown command"))
+
# Class for testing the BoB without actually starting processes.
# This is used for testing the start/stop components routines and
# the BoB commands.
@@ -156,42 +194,52 @@ class MockBob(BoB):
def start_msgq(self, c_channel_env):
self.msgq = True
self.processes[2] = ProcessInfo('b10-msgq', ['/bin/false'])
+ self.processes[2].pid = 2
def start_cfgmgr(self, c_channel_env):
self.cfgmgr = True
self.processes[3] = ProcessInfo('b10-cfgmgr', ['/bin/false'])
+ self.processes[3].pid = 3
def start_ccsession(self, c_channel_env):
self.ccsession = True
self.processes[4] = ProcessInfo('b10-ccsession', ['/bin/false'])
+ self.processes[4].pid = 4
def start_auth(self, c_channel_env):
self.auth = True
self.processes[5] = ProcessInfo('b10-auth', ['/bin/false'])
+ self.processes[5].pid = 5
def start_resolver(self, c_channel_env):
self.resolver = True
self.processes[6] = ProcessInfo('b10-resolver', ['/bin/false'])
+ self.processes[6].pid = 6
def start_xfrout(self, c_channel_env):
self.xfrout = True
self.processes[7] = ProcessInfo('b10-xfrout', ['/bin/false'])
+ self.processes[7].pid = 7
def start_xfrin(self, c_channel_env):
self.xfrin = True
self.processes[8] = ProcessInfo('b10-xfrin', ['/bin/false'])
+ self.processes[8].pid = 8
def start_zonemgr(self, c_channel_env):
self.zonemgr = True
self.processes[9] = ProcessInfo('b10-zonemgr', ['/bin/false'])
+ self.processes[9].pid = 9
def start_stats(self, c_channel_env):
self.stats = True
self.processes[10] = ProcessInfo('b10-stats', ['/bin/false'])
+ self.processes[10].pid = 10
def start_cmdctl(self, c_channel_env):
self.cmdctl = True
self.processes[11] = ProcessInfo('b10-cmdctl', ['/bin/false'])
+ self.processes[11].pid = 11
# We don't really use all of these stop_ methods. But it might turn out
# someone would add some stop_ method to BoB and we want that one overriden
@@ -550,6 +598,15 @@ class TestParseArgs(unittest.TestCase):
options = parse_args(['--cmdctl-port=1234'], TestOptParser)
self.assertEqual(1234, options.cmdctl_port)
+ def test_brittle(self):
+ """
+ Test we can use the "brittle" flag.
+ """
+ options = parse_args([], TestOptParser)
+ self.assertFalse(options.brittle)
+ options = parse_args(['--brittle'], TestOptParser)
+ self.assertTrue(options.brittle)
+
class TestPIDFile(unittest.TestCase):
def setUp(self):
self.pid_file = '@builddir@' + os.sep + 'bind10.pid'
@@ -597,5 +654,34 @@ class TestPIDFile(unittest.TestCase):
self.assertRaises(IOError, dump_pid,
'nonexistent_dir' + os.sep + 'bind10.pid')
+class TestBrittle(unittest.TestCase):
+ def test_brittle_disabled(self):
+ bob = MockBob()
+ bob.start_all_processes()
+ bob.runnable = True
+
+ bob.reap_children()
+ self.assertTrue(bob.runnable)
+
+ def simulated_exit(self):
+ ret_val = self.exit_info
+ self.exit_info = (0, 0)
+ return ret_val
+
+ def test_brittle_enabled(self):
+ bob = MockBob()
+ bob.start_all_processes()
+ bob.runnable = True
+
+ bob.brittle = True
+ self.exit_info = (5, 0)
+ bob._get_process_exit_status = self.simulated_exit
+
+ old_stdout = sys.stdout
+ sys.stdout = open("/dev/null", "w")
+ bob.reap_children()
+ sys.stdout = old_stdout
+ self.assertFalse(bob.runnable)
+
if __name__ == '__main__':
unittest.main()
diff --git a/src/bin/resolver/Makefile.am b/src/bin/resolver/Makefile.am
index 54e15bd..094e3ad 100644
--- a/src/bin/resolver/Makefile.am
+++ b/src/bin/resolver/Makefile.am
@@ -4,6 +4,8 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin
AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
AM_CPPFLAGS += -I$(top_srcdir)/src/lib/cc -I$(top_builddir)/src/lib/cc
+AM_CPPFLAGS += -I$(top_srcdir)/src/lib/asiodns
+AM_CPPFLAGS += -I$(top_builddir)/src/lib/asiodns
AM_CPPFLAGS += -I$(top_srcdir)/src/lib/asiolink
AM_CPPFLAGS += -I$(top_builddir)/src/lib/asiolink
AM_CPPFLAGS += $(BOOST_INCLUDES)
@@ -45,6 +47,7 @@ b10_resolver_LDADD = $(top_builddir)/src/lib/dns/libdns++.la
b10_resolver_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
b10_resolver_LDADD += $(top_builddir)/src/lib/cc/libcc.la
b10_resolver_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
+b10_resolver_LDADD += $(top_builddir)/src/lib/asiodns/libasiodns.la
b10_resolver_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
b10_resolver_LDADD += $(top_builddir)/src/lib/xfr/libxfr.la
b10_resolver_LDADD += $(top_builddir)/src/lib/log/liblog.la
diff --git a/src/bin/resolver/main.cc b/src/bin/resolver/main.cc
index ac6d441..5103bf9 100644
--- a/src/bin/resolver/main.cc
+++ b/src/bin/resolver/main.cc
@@ -12,6 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+#include <config.h>
+
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
@@ -25,6 +27,7 @@
#include <boost/foreach.hpp>
+#include <asiodns/asiodns.h>
#include <asiolink/asiolink.h>
#include <exceptions/exceptions.h>
@@ -56,7 +59,8 @@ using namespace isc::cc;
using namespace isc::config;
using namespace isc::data;
using isc::log::dlog;
-using namespace asiolink;
+using namespace isc::asiodns;
+using namespace isc::asiolink;
namespace {
diff --git a/src/bin/resolver/resolver.cc b/src/bin/resolver/resolver.cc
index f132a0d..591e214 100644
--- a/src/bin/resolver/resolver.cc
+++ b/src/bin/resolver/resolver.cc
@@ -20,6 +20,7 @@
#include <vector>
#include <cassert>
+#include <asiodns/asiodns.h>
#include <asiolink/asiolink.h>
#include <boost/foreach.hpp>
@@ -56,7 +57,8 @@ using namespace isc::dns;
using namespace isc::data;
using namespace isc::config;
using isc::log::dlog;
-using namespace asiolink;
+using namespace isc::asiodns;
+using namespace isc::asiolink;
using namespace isc::server_common::portconfig;
class ResolverImpl {
@@ -297,7 +299,7 @@ public:
edns_response->setUDPSize(Message::DEFAULT_MAX_EDNS0_UDPSIZE);
answer_message->setEDNS(edns_response);
}
-
+
if (io_message.getSocket().getProtocol() == IPPROTO_UDP) {
if (edns) {
renderer.setLengthLimit(edns->getUDPSize());
@@ -347,7 +349,7 @@ Resolver::~Resolver() {
}
void
-Resolver::setDNSService(asiolink::DNSService& dnss) {
+Resolver::setDNSService(isc::asiodns::DNSService& dnss) {
dnss_ = &dnss;
}
diff --git a/src/bin/resolver/resolver.h b/src/bin/resolver/resolver.h
index 6d3e306..2890dd3 100644
--- a/src/bin/resolver/resolver.h
+++ b/src/bin/resolver/resolver.h
@@ -21,8 +21,16 @@
#include <cc/data.h>
#include <config/ccsession.h>
+#include <dns/message.h>
+#include <util/buffer.h>
-#include <asiolink/asiolink.h>
+#include <asiodns/dns_server.h>
+#include <asiodns/dns_service.h>
+#include <asiodns/dns_lookup.h>
+#include <asiodns/dns_answer.h>
+#include <asiolink/io_message.h>
+#include <asiolink/io_service.h>
+#include <asiolink/simple_callback.h>
#include <nsas/nameserver_address_store.h>
#include <cache/resolver_cache.h>
@@ -74,11 +82,11 @@ public:
/// shall return to the client
/// \param buffer Pointer to an \c OutputBuffer for the resposne
/// \param server Pointer to the \c DNSServer
- void processMessage(const asiolink::IOMessage& io_message,
+ void processMessage(const isc::asiolink::IOMessage& io_message,
isc::dns::MessagePtr query_message,
isc::dns::MessagePtr answer_message,
isc::util::OutputBufferPtr buffer,
- asiolink::DNSServer* server);
+ isc::asiodns::DNSServer* server);
/// \brief Set and get the config session
isc::config::ModuleCCSession* getConfigSession() const;
@@ -88,16 +96,16 @@ public:
isc::data::ConstElementPtr updateConfig(isc::data::ConstElementPtr config);
/// \brief Assign an ASIO IO Service queue to this Resolver object
- void setDNSService(asiolink::DNSService& dnss);
-
+ void setDNSService(isc::asiodns::DNSService& dnss);
+
/// \brief Assign a NameserverAddressStore to this Resolver object
void setNameserverAddressStore(isc::nsas::NameserverAddressStore &nsas);
-
+
/// \brief Assign a cache to this Resolver object
void setCache(isc::cache::ResolverCache& cache);
/// \brief Return this object's ASIO IO Service queue
- asiolink::DNSService& getDNSService() const { return (*dnss_); }
+ isc::asiodns::DNSService& getDNSService() const { return (*dnss_); }
/// \brief Returns this object's NSAS
isc::nsas::NameserverAddressStore& getNameserverAddressStore() const {
@@ -108,15 +116,15 @@ public:
isc::cache::ResolverCache& getResolverCache() const {
return *cache_;
};
-
+
/// \brief Return pointer to the DNS Lookup callback function
- asiolink::DNSLookup* getDNSLookupProvider() { return (dns_lookup_); }
+ isc::asiodns::DNSLookup* getDNSLookupProvider() { return (dns_lookup_); }
/// \brief Return pointer to the DNS Answer callback function
- asiolink::DNSAnswer* getDNSAnswerProvider() { return (dns_answer_); }
+ isc::asiodns::DNSAnswer* getDNSAnswerProvider() { return (dns_answer_); }
/// \brief Return pointer to the Checkin callback function
- asiolink::SimpleCallback* getCheckinProvider() { return (checkin_); }
+ isc::asiolink::SimpleCallback* getCheckinProvider() { return (checkin_); }
/**
* \brief Tell the Resolver that is has already been configured
@@ -230,10 +238,10 @@ public:
private:
ResolverImpl* impl_;
- asiolink::DNSService* dnss_;
- asiolink::SimpleCallback* checkin_;
- asiolink::DNSLookup* dns_lookup_;
- asiolink::DNSAnswer* dns_answer_;
+ isc::asiodns::DNSService* dnss_;
+ isc::asiolink::SimpleCallback* checkin_;
+ isc::asiodns::DNSLookup* dns_lookup_;
+ isc::asiodns::DNSAnswer* dns_answer_;
isc::nsas::NameserverAddressStore* nsas_;
isc::cache::ResolverCache* cache_;
// This value is initally false, and will be set to true
@@ -244,6 +252,6 @@ private:
#endif // __RESOLVER_H
-// Local Variables:
+// Local Variables:
// mode: c++
-// End:
+// End:
diff --git a/src/bin/resolver/response_scrubber.cc b/src/bin/resolver/response_scrubber.cc
index 060a8b1..93bd808 100644
--- a/src/bin/resolver/response_scrubber.cc
+++ b/src/bin/resolver/response_scrubber.cc
@@ -26,7 +26,7 @@ using namespace std;
// Compare addresses etc.
ResponseScrubber::Category ResponseScrubber::addressCheck(
- const asiolink::IOEndpoint& to, const asiolink::IOEndpoint& from)
+ const isc::asiolink::IOEndpoint& to, const isc::asiolink::IOEndpoint& from)
{
if (from.getProtocol() == to.getProtocol()) {
if (from.getAddress() == to.getAddress()) {
diff --git a/src/bin/resolver/response_scrubber.h b/src/bin/resolver/response_scrubber.h
index 680aa5a..c59ac15 100644
--- a/src/bin/resolver/response_scrubber.h
+++ b/src/bin/resolver/response_scrubber.h
@@ -282,8 +282,8 @@ public:
///
/// \return SUCCESS if the two endpoints match, otherwise an error status
/// indicating what was incorrect.
- static Category addressCheck(const asiolink::IOEndpoint& to,
- const asiolink::IOEndpoint& from);
+ static Category addressCheck(const isc::asiolink::IOEndpoint& to,
+ const isc::asiolink::IOEndpoint& from);
/// \brief Check QID
///
diff --git a/src/bin/resolver/tests/Makefile.am b/src/bin/resolver/tests/Makefile.am
index b85c223..444358b 100644
--- a/src/bin/resolver/tests/Makefile.am
+++ b/src/bin/resolver/tests/Makefile.am
@@ -31,6 +31,7 @@ run_unittests_LDADD += $(SQLITE_LIBS)
run_unittests_LDADD += $(top_builddir)/src/lib/testutils/libtestutils.la
run_unittests_LDADD += $(top_builddir)/src/lib/datasrc/libdatasrc.la
run_unittests_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
+run_unittests_LDADD += $(top_builddir)/src/lib/asiodns/libasiodns.la
run_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
run_unittests_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
run_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.la
diff --git a/src/bin/resolver/tests/resolver_config_unittest.cc b/src/bin/resolver/tests/resolver_config_unittest.cc
index 2fa62e5..70e856d 100644
--- a/src/bin/resolver/tests/resolver_config_unittest.cc
+++ b/src/bin/resolver/tests/resolver_config_unittest.cc
@@ -12,12 +12,15 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+#include <config.h>
+
#include <string>
#include <gtest/gtest.h>
#include <cc/data.h>
+#include <asiodns/asiodns.h>
#include <asiolink/asiolink.h>
#include <resolver/resolver.h>
@@ -29,7 +32,8 @@
using namespace std;
using namespace isc::data;
using namespace isc::testutils;
-using namespace asiolink;
+using namespace isc::asiodns;
+using namespace isc::asiolink;
using isc::UnitTestUtil;
namespace {
diff --git a/src/bin/resolver/tests/response_scrubber_unittest.cc b/src/bin/resolver/tests/response_scrubber_unittest.cc
index 1dc6639..eff5598 100644
--- a/src/bin/resolver/tests/response_scrubber_unittest.cc
+++ b/src/bin/resolver/tests/response_scrubber_unittest.cc
@@ -41,6 +41,7 @@
// Class for endpoint checks. The family of the endpoint is set in the
// constructor; the address family by the string provided for the address.
+namespace isc {
namespace asiolink {
class GenericEndpoint : public IOEndpoint {
@@ -73,13 +74,14 @@ private:
short protocol_; // Protocol of the endpoint
};
}
+}
using namespace asio::ip;
using namespace isc::dns;
using namespace rdata;
using namespace isc::dns::rdata::generic;
using namespace isc::dns::rdata::in;
-using namespace asiolink;
+using namespace isc::asiolink;
// Test class
diff --git a/src/bin/sockcreator/Makefile.am b/src/bin/sockcreator/Makefile.am
new file mode 100644
index 0000000..1ac4640
--- /dev/null
+++ b/src/bin/sockcreator/Makefile.am
@@ -0,0 +1,18 @@
+SUBDIRS = tests
+
+AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+
+AM_CXXFLAGS = $(B10_CXXFLAGS)
+
+if USE_STATIC_LINK
+AM_LDFLAGS = -static
+endif
+
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+
+CLEANFILES = *.gcno *.gcda
+
+pkglibexec_PROGRAMS = b10-sockcreator
+
+b10_sockcreator_SOURCES = sockcreator.cc sockcreator.h main.cc
+b10_sockcreator_LDADD = $(top_builddir)/src/lib/util/io/libutil_io.la
diff --git a/src/bin/sockcreator/README b/src/bin/sockcreator/README
new file mode 100644
index 0000000..4dbbee7
--- /dev/null
+++ b/src/bin/sockcreator/README
@@ -0,0 +1,49 @@
+The socket creator
+==================
+
+The only thing we need higher rights than standard user is binding sockets to
+ports lower than 1024. So we will have a separate process that keeps the
+rights, while the rests drop them for security reasons.
+
+This process is the socket creator. Its goal is to be as simple as possible
+and to contain as little code as possible to minimise the amount of code
+running with higher privileges (to minimize the number of bugs and make
+checking/auditing it easier). It uses low-level OS API instead of some
+fancy library for that reason. It has only fixed-length reads so there's no
+place for buffer overruns.
+
+Protocol
+--------
+
+It talks with whoever started it by its stdin/stdout. It reads simple
+binary protocol from stdin and does what the commands ask. Command is a single
+byte (usually from the printable range, so it is easier to debug and guess
+what it does), followed by parameters.
+
+Note that as send_fd and recv_fd works only with unix domain socket, it's stdio
+must be a socket, not pipe.
+
+* 'T': It has no parameters. It asks the socket creator to terminate.
+
+* 'S' 'U|T' '4|6' port address: Asks it to create a port. First parameter
+ tels the socket type (either UDP or TCP). The second one is address family
+ (either IPv4 or IPv6). Then there's 2 bytes of the port number, in the
+ network byte order. The last one is either 4 or 16 bytes of address, as
+ they would be passed to bind (note that both parameters are already prepared,
+ like hton called on them).
+
+ The answer to this is either 'S' directly followed by the socket (using
+ sendmsg) if it is successful. If it fails, 'E' is returned instead, followed
+ by either 'S' or 'B' (either socket() or bind() call failed). Then there is
+ one int (architecture-dependent length and endianess), which is the errno
+ value after the failure.
+
+The creator may also send these messages at any time (but not in the middle
+of another message):
+
+* 'F': A fatal error has been detected. It is followed by one byte of error
+ condition code and then the creator terminates with non-zero status.
+
+ The conditions are:
+ * 'I': Invalid input (eg. someone sent a wrong letter and it does not
+ understand it).
diff --git a/src/bin/sockcreator/main.cc b/src/bin/sockcreator/main.cc
new file mode 100644
index 0000000..37da303
--- /dev/null
+++ b/src/bin/sockcreator/main.cc
@@ -0,0 +1,26 @@
+// Copyright (C) 2011 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 "sockcreator.h"
+
+using namespace isc::socket_creator;
+
+int
+main() {
+ /*
+ * TODO Maybe use some OS-specific caps interface and drop everything
+ * but ability to bind ports? It would be nice.
+ */
+ return run(0, 1); // Read commands from stdin, output to stdout
+}
diff --git a/src/bin/sockcreator/sockcreator.cc b/src/bin/sockcreator/sockcreator.cc
new file mode 100644
index 0000000..6b50813
--- /dev/null
+++ b/src/bin/sockcreator/sockcreator.cc
@@ -0,0 +1,151 @@
+// Copyright (C) 2011 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 "sockcreator.h"
+
+#include <util/io/fd.h>
+
+#include <unistd.h>
+#include <cerrno>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+using namespace isc::util::io;
+
+namespace isc {
+namespace socket_creator {
+
+int
+get_sock(const int type, struct sockaddr *bind_addr, const socklen_t addr_len)
+{
+ int sock(socket(bind_addr->sa_family, type, 0));
+ if (sock == -1) {
+ return -1;
+ }
+ if (bind(sock, bind_addr, addr_len) == -1) {
+ return -2;
+ }
+ return sock;
+}
+
+// These are macros so they can exit the function
+#define READ(WHERE, HOW_MANY) do { \
+ size_t how_many = (HOW_MANY); \
+ if (read_data(input_fd, (WHERE), how_many) < how_many) { \
+ return 1; \
+ } \
+ } while (0)
+
+#define WRITE(WHAT, HOW_MANY) do { \
+ if (!write_data(output_fd, (WHAT), (HOW_MANY))) { \
+ return 2; \
+ } \
+ } while (0)
+
+#define DEFAULT \
+ default: /* Unrecognized part of protocol */ \
+ WRITE("FI", 2); \
+ return 3;
+
+int
+run(const int input_fd, const int output_fd, const get_sock_t get_sock,
+ const send_fd_t send_fd)
+{
+ for (;;) {
+ // Read the command
+ char command;
+ READ(&command, 1);
+ switch (command) {
+ case 'T': // The "terminate" command
+ return 0;
+ case 'S': { // Create a socket
+ // Read what type of socket they want
+ char type[2];
+ READ(type, 2);
+ // Read the address they ask for
+ struct sockaddr *addr(NULL);
+ size_t addr_len(0);
+ struct sockaddr_in addr_in;
+ struct sockaddr_in6 addr_in6;
+ switch (type[1]) { // The address family
+ /*
+ * Here are some casts. They are required by C++ and
+ * the low-level interface (they are implicit in C).
+ */
+ case '4':
+ addr = static_cast<struct sockaddr *>(
+ static_cast<void *>(&addr_in));
+ addr_len = sizeof addr_in;
+ memset(&addr_in, 0, sizeof addr_in);
+ addr_in.sin_family = AF_INET;
+ READ(static_cast<char *>(static_cast<void *>(
+ &addr_in.sin_port)), 2);
+ READ(static_cast<char *>(static_cast<void *>(
+ &addr_in.sin_addr.s_addr)), 4);
+ break;
+ case '6':
+ addr = static_cast<struct sockaddr *>(
+ static_cast<void *>(&addr_in6));
+ addr_len = sizeof addr_in6;
+ memset(&addr_in6, 0, sizeof addr_in6);
+ addr_in6.sin6_family = AF_INET6;
+ READ(static_cast<char *>(static_cast<void *>(
+ &addr_in6.sin6_port)), 2);
+ READ(static_cast<char *>(static_cast<void *>(
+ &addr_in6.sin6_addr.s6_addr)), 16);
+ break;
+ DEFAULT
+ }
+ int sock_type;
+ switch (type[0]) { // Translate the type
+ case 'T':
+ sock_type = SOCK_STREAM;
+ break;
+ case 'U':
+ sock_type = SOCK_DGRAM;
+ break;
+ DEFAULT
+ }
+ int result(get_sock(sock_type, addr, addr_len));
+ if (result >= 0) { // We got the socket
+ WRITE("S", 1);
+ // FIXME: Check the output and write a test for it
+ send_fd(output_fd, result);
+ } else {
+ WRITE("E", 1);
+ switch (result) {
+ case -1:
+ WRITE("S", 1);
+ break;
+ case -2:
+ WRITE("B", 1);
+ break;
+ default:
+ return 4;
+ }
+ int error(errno);
+ WRITE(static_cast<char *>(static_cast<void *>(&error)),
+ sizeof error);
+ }
+ break;
+ }
+ DEFAULT
+ }
+ }
+}
+
+} // End of the namespaces
+}
diff --git a/src/bin/sockcreator/sockcreator.h b/src/bin/sockcreator/sockcreator.h
new file mode 100644
index 0000000..ddf9a09
--- /dev/null
+++ b/src/bin/sockcreator/sockcreator.h
@@ -0,0 +1,100 @@
+// Copyright (C) 2011 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.
+
+/**
+ * \file sockcreator.h
+ * \short Socket creator functionality.
+ *
+ * This module holds the functionality of the socket creator. It is
+ * a separate module from main to ease up the tests.
+ */
+
+#ifndef __SOCKCREATOR_H
+#define __SOCKCREATOR_H 1
+
+#include <util/io/fd_share.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+namespace isc {
+namespace socket_creator {
+
+/**
+ * \short Create a socket and bind it.
+ *
+ * This is just a bundle of socket() and bind() calls. The sa_family of
+ * bind_addr is used to determine the domain of the socket.
+ *
+ * \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 better, left intact from socket() or bind()).
+ * \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.
+ */
+int
+get_sock(const int type, struct sockaddr *bind_addr, const socklen_t addr_len);
+
+/**
+ * Type of the get_sock function, to pass it as parameter.
+ */
+typedef
+int
+(*get_sock_t)(const int, struct sockaddr *, const socklen_t);
+
+/**
+ * Type of the send_fd() function, so it can be passed as a parameter.
+ */
+typedef
+int
+(*send_fd_t)(const int, const int);
+
+/**
+ * \short Infinite loop parsing commands and returning the sockets.
+ *
+ * This reads commands and socket descriptions from the input_fd
+ * file descriptor, creates sockets and writes the results (socket or
+ * error) to output_fd.
+ *
+ * Current errors are:
+ * - 1: Read error
+ * - 2: Write error
+ * - 3: Protocol error (unknown command, etc)
+ * - 4: Some internal inconsistency detected
+ *
+ * It terminates either if a command asks it to or when unrecoverable
+ * error happens.
+ *
+ * \return Like a return value of a main - 0 means everything OK, anything
+ * else is error.
+ * \param input_fd Here is where it reads the commads.
+ * \param output_fd Here is where it writes the results.
+ * \param get_sock_fun The function that is used to create the sockets.
+ * This should be left on the default value, the parameter is here
+ * for testing purposes.
+ * \param send_fd_fun The function that is used to send the socket over
+ * a file descriptor. This should be left on the default value, it is
+ * here for testing purposes.
+ */
+int
+run(const int input_fd, const int output_fd,
+ const get_sock_t get_sock_fun = get_sock,
+ const send_fd_t send_fd_fun = isc::util::io::send_fd);
+
+} // End of the namespaces
+}
+
+#endif // __SOCKCREATOR_H
diff --git a/src/bin/sockcreator/tests/Makefile.am b/src/bin/sockcreator/tests/Makefile.am
new file mode 100644
index 0000000..2e1307a
--- /dev/null
+++ b/src/bin/sockcreator/tests/Makefile.am
@@ -0,0 +1,25 @@
+CLEANFILES = *.gcno *.gcda
+
+AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CXXFLAGS = $(B10_CXXFLAGS)
+
+if USE_STATIC_LINK
+AM_LDFLAGS = -static
+endif
+
+TESTS =
+if HAVE_GTEST
+TESTS += run_unittests
+run_unittests_SOURCES = ../sockcreator.cc ../sockcreator.h
+run_unittests_SOURCES += sockcreator_tests.cc
+run_unittests_SOURCES += run_unittests.cc
+
+run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
+run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
+run_unittests_LDADD = $(GTEST_LDADD)
+run_unittests_LDADD += $(top_builddir)/src/lib/util/io/libutil_io.la
+run_unittests_LDADD += \
+ $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
+endif
+
+noinst_PROGRAMS = $(TESTS)
diff --git a/src/bin/sockcreator/tests/run_unittests.cc b/src/bin/sockcreator/tests/run_unittests.cc
new file mode 100644
index 0000000..e787ab1
--- /dev/null
+++ b/src/bin/sockcreator/tests/run_unittests.cc
@@ -0,0 +1,22 @@
+// Copyright (C) 2011 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 <gtest/gtest.h>
+
+int
+main(int argc, char *argv[]) {
+ ::testing::InitGoogleTest(&argc, argv);
+
+ return RUN_ALL_TESTS();
+}
diff --git a/src/bin/sockcreator/tests/sockcreator_tests.cc b/src/bin/sockcreator/tests/sockcreator_tests.cc
new file mode 100644
index 0000000..73cbf48
--- /dev/null
+++ b/src/bin/sockcreator/tests/sockcreator_tests.cc
@@ -0,0 +1,273 @@
+// Copyright (C) 2011 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 "../sockcreator.h"
+
+#include <util/unittests/fork.h>
+#include <util/io/fd.h>
+
+#include <gtest/gtest.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <cstring>
+#include <cerrno>
+
+using namespace isc::socket_creator;
+using namespace isc::util::unittests;
+using namespace isc::util::io;
+
+namespace {
+
+/*
+ * Generic version of the creation of socket test. It just tries to
+ * create the socket and checks the result is not negative (eg.
+ * it is valid descriptor) and that it can listen.
+ *
+ * This is a macro so ASSERT_* does abort the TEST, not just the
+ * function inside.
+ */
+#define TEST_ANY_CREATE(SOCK_TYPE, ADDR_TYPE, ADDR_FAMILY, FAMILY_FIELD, \
+ ADDR_SET, CHECK_SOCK) \
+ do { \
+ /*
+ * This should create an address that binds on all interfaces
+ * and lets the OS choose a free port.
+ */ \
+ struct ADDR_TYPE addr; \
+ memset(&addr, 0, sizeof addr); \
+ ADDR_SET(addr); \
+ addr.FAMILY_FIELD = ADDR_FAMILY; \
+ struct sockaddr *addr_ptr = static_cast<struct sockaddr *>( \
+ static_cast<void *>(&addr)); \
+ \
+ int socket = get_sock(SOCK_TYPE, addr_ptr, sizeof addr); \
+ /* Provide even nice error message. */ \
+ ASSERT_GE(socket, 0) << "Couldn't create a socket of type " \
+ #SOCK_TYPE " and family " #ADDR_FAMILY ", failed with " \
+ << socket << " and error " << strerror(errno); \
+ CHECK_SOCK(ADDR_TYPE, socket); \
+ EXPECT_EQ(0, close(socket)); \
+ } while (0)
+
+// Just helper macros
+#define INADDR_SET(WHAT) do { WHAT.sin_addr.s_addr = INADDR_ANY; } while (0)
+#define IN6ADDR_SET(WHAT) do { WHAT.sin6_addr = in6addr_loopback; } while (0)
+// If the get_sock returned something useful, listen must work
+#define TCP_CHECK(UNUSED, SOCKET) do { \
+ EXPECT_EQ(0, listen(SOCKET, 1)); \
+ } while (0)
+// More complicated with UDP, so we send a packet to ourselfs and se if it
+// arrives
+#define UDP_CHECK(ADDR_TYPE, SOCKET) do { \
+ struct ADDR_TYPE addr; \
+ memset(&addr, 0, sizeof addr); \
+ struct sockaddr *addr_ptr = static_cast<struct sockaddr *>( \
+ static_cast<void *>(&addr)); \
+ \
+ socklen_t len = sizeof addr; \
+ ASSERT_EQ(0, getsockname(SOCKET, addr_ptr, &len)); \
+ ASSERT_EQ(5, sendto(SOCKET, "test", 5, 0, addr_ptr, sizeof addr)) << \
+ "Send failed with error " << strerror(errno) << " on socket " << \
+ SOCKET; \
+ char buffer[5]; \
+ ASSERT_EQ(5, recv(SOCKET, buffer, 5, 0)) << \
+ "Recv failed with error " << strerror(errno) << " on socket " << \
+ SOCKET; \
+ EXPECT_STREQ("test", buffer); \
+ } while (0)
+
+/*
+ * Several tests to ensure we can create the sockets.
+ */
+TEST(get_sock, udp4_create) {
+ TEST_ANY_CREATE(SOCK_DGRAM, sockaddr_in, AF_INET, sin_family, INADDR_SET,
+ UDP_CHECK);
+}
+
+TEST(get_sock, tcp4_create) {
+ TEST_ANY_CREATE(SOCK_STREAM, sockaddr_in, AF_INET, sin_family, INADDR_SET,
+ TCP_CHECK);
+}
+
+TEST(get_sock, udp6_create) {
+ TEST_ANY_CREATE(SOCK_DGRAM, sockaddr_in6, AF_INET6, sin6_family,
+ IN6ADDR_SET, UDP_CHECK);
+}
+
+TEST(get_sock, tcp6_create) {
+ TEST_ANY_CREATE(SOCK_STREAM, sockaddr_in6, AF_INET6, sin6_family,
+ IN6ADDR_SET, TCP_CHECK);
+}
+
+/*
+ * Try to ask the get_sock function some nonsense and test if it
+ * is able to report error.
+ */
+TEST(get_sock, fail_with_nonsense) {
+ struct sockaddr addr;
+ memset(&addr, 0, sizeof addr);
+ ASSERT_LT(get_sock(0, &addr, sizeof addr), 0);
+}
+
+/*
+ * Helper functions to pass to run during testing.
+ */
+int
+get_sock_dummy(const int type, struct sockaddr *addr, const socklen_t)
+{
+ int result(0);
+ int port(0);
+ /*
+ * We encode the type and address family into the int and return it.
+ * Lets ignore the port and address for now
+ * First bit is 1 if it is known type. Second tells if TCP or UDP.
+ * The familly is similar - third bit is known address family,
+ * the fourth is the family.
+ */
+ switch (type) {
+ case SOCK_STREAM:
+ result += 1;
+ break;
+ case SOCK_DGRAM:
+ result += 3;
+ break;
+ }
+ switch (addr->sa_family) {
+ case AF_INET:
+ result += 4;
+ port = static_cast<struct sockaddr_in *>(
+ static_cast<void *>(addr))->sin_port;
+ break;
+ case AF_INET6:
+ result += 12;
+ port = static_cast<struct sockaddr_in6 *>(
+ static_cast<void *>(addr))->sin6_port;
+ break;
+ }
+ /*
+ * The port should be 0xffff. If it's not, we change the result.
+ * The port of 0xbbbb means bind should fail and 0xcccc means
+ * socket should fail.
+ */
+ if (port != 0xffff) {
+ errno = 0;
+ if (port == 0xbbbb) {
+ return -2;
+ } else if (port == 0xcccc) {
+ return -1;
+ } else {
+ result += 16;
+ }
+ }
+ return result;
+}
+
+int
+send_fd_dummy(const int destination, const int what)
+{
+ /*
+ * Make sure it is 1 byte so we know the length. We do not use more during
+ * the test anyway.
+ */
+ char fd_data(what);
+ if (!write_data(destination, &fd_data, 1)) {
+ return -1;
+ } else {
+ 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()
+ * parses the commands correctly.
+ */
+void run_test(const char *input_data, const size_t input_size,
+ const char *output_data, const size_t output_size,
+ bool should_succeed = true)
+{
+ // Prepare the input feeder and output checker processes
+ int input_fd(0), output_fd(0);
+ pid_t input(provide_input(&input_fd, input_data, input_size)),
+ output(check_output(&output_fd, output_data, output_size));
+ ASSERT_NE(-1, input) << "Couldn't start input feeder";
+ ASSERT_NE(-1, output) << "Couldn't start output checker";
+ // Run the body
+ int result(run(input_fd, output_fd, get_sock_dummy, send_fd_dummy));
+ // Close the pipes
+ close(input_fd);
+ close(output_fd);
+ // Did it run well?
+ if (should_succeed) {
+ EXPECT_EQ(0, result);
+ } else {
+ EXPECT_NE(0, result);
+ }
+ // Check the subprocesses say everything is OK too
+ EXPECT_TRUE(process_ok(input));
+ EXPECT_TRUE(process_ok(output));
+}
+
+/*
+ * Check it terminates successfully when asked to.
+ */
+TEST(run, terminate) {
+ run_test("T", 1, NULL, 0);
+}
+
+/*
+ * Check it rejects incorrect input.
+ */
+TEST(run, bad_input) {
+ run_test("XXX", 3, "FI", 2, false);
+}
+
+/*
+ * Check it correctly parses queries to create sockets.
+ */
+TEST(run, sockets) {
+ run_test(
+ "SU4\xff\xff\0\0\0\0" // This has 9 bytes
+ "ST4\xff\xff\0\0\0\0" // This has 9 bytes
+ "ST6\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" // This has 21 bytes
+ "SU6\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" // This has 21 bytes
+ "T", 61,
+ "S\x07S\x05S\x0dS\x0f", 8);
+}
+
+/*
+ * Check if failures of get_socket are handled correctly.
+ */
+TEST(run, bad_sockets) {
+ // We need to construct the answer, but it depends on int length.
+ size_t int_len(sizeof(int));
+ size_t result_len(4 + 2 * int_len);
+ char result[4 + sizeof(int) * 2];
+ // Both errno parts should be 0
+ memset(result, 0, result_len);
+ // Fill the 2 control parts
+ strcpy(result, "EB");
+ strcpy(result + 2 + int_len, "ES");
+ // Run the test
+ run_test(
+ "SU4\xbb\xbb\0\0\0\0"
+ "SU4\xcc\xcc\0\0\0\0"
+ "T", 19,
+ result, result_len);
+}
+
+}
diff --git a/src/bin/stats/b10-stats.8 b/src/bin/stats/b10-stats.8
index 062ff35..5714234 100644
--- a/src/bin/stats/b10-stats.8
+++ b/src/bin/stats/b10-stats.8
@@ -1,7 +1,7 @@
'\" t
.\" Title: b10-stats
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
.\" Date: Oct 15, 2010
.\" Manual: BIND10
.\" Source: BIND10
@@ -9,6 +9,15 @@
.\"
.TH "B10\-STATS" "8" "Oct 15, 2010" "BIND10" "BIND10"
.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
@@ -35,6 +44,11 @@ with other modules like
\fBbind10\fR,
\fBb10\-auth\fR
and so on\&. It waits for coming data from other modules, then other modules send data to stats module periodically\&. Other modules send stats data to stats module independently from implementation of stats module, so the frequency of sending data may not be constant\&. Stats module collects data and aggregates it\&.
+\fBb10\-stats\fR
+invokes "sendstats" command for
+\fBbind10\fR
+after its initial starting because it\*(Aqs sure to collect statistics data from
+\fBbind10\fR\&.
.SH "OPTIONS"
.PP
The arguments are as follows:
@@ -49,7 +63,8 @@ switches to verbose mode\&. It sends verbose messages to STDOUT\&.
.PP
/usr/local/share/bind10\-devel/stats\&.spec
\(em This is a spec file for
-\fBb10\-stats\fR\&. It contains definitions of statistics items of BIND 10 and commands received vi bindctl\&.
+\fBb10\-stats\fR\&. It contains definitions of statistics items of BIND 10 and commands received via
+bindctl(1)\&.
.SH "SEE ALSO"
.PP
diff --git a/src/bin/stats/b10-stats.xml b/src/bin/stats/b10-stats.xml
index f622439..7ec58dd 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 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2010,2011 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
@@ -64,7 +64,9 @@
send stats data to stats module independently from
implementation of stats module, so the frequency of sending data
may not be constant. Stats module collects data and aggregates
- it.
+ it. <command>b10-stats</command> invokes "sendstats" command
+ for <command>bind10</command> after its initial starting because it's
+ sure to collect statistics data from <command>bind10</command>.
</para>
</refsect1>
diff --git a/src/bin/stats/stats.py.in b/src/bin/stats/stats.py.in
index 15e2980..eeddd92 100755
--- a/src/bin/stats/stats.py.in
+++ b/src/bin/stats/stats.py.in
@@ -1,6 +1,6 @@
#!@PYTHON@
-# Copyright (C) 2010 Internet Systems Consortium.
+# Copyright (C) 2010, 2011 Internet Systems Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -15,8 +15,6 @@
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-__version__ = "$Revision$"
-
import sys; sys.path.append ('@@PYTHONPATH@@')
import os
import signal
@@ -220,7 +218,13 @@ class CCSessionListener(Listener):
self.stats_data['stats.start_time'] = get_datetime()
self.stats_data['stats.last_update_time'] = get_datetime()
self.stats_data['stats.lname'] = self.session.lname
- return self.cc_session.start()
+ self.cc_session.start()
+ # request Bob to send statistics data
+ if self.verbose:
+ sys.stdout.write("[b10-stats] request Bob to send statistics data\n")
+ cmd = isc.config.ccsession.create_command("sendstats", None)
+ seq = self.session.group_sendmsg(cmd, 'Boss')
+ self.session.group_recvmsg(True, seq)
def stop(self):
"""
diff --git a/src/bin/stats/tests/b10-stats_test.py b/src/bin/stats/tests/b10-stats_test.py
index e4e1a1e..3566bc4 100644
--- a/src/bin/stats/tests/b10-stats_test.py
+++ b/src/bin/stats/tests/b10-stats_test.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2010 Internet Systems Consortium.
+# Copyright (C) 2010,2011 Internet Systems Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -13,8 +13,6 @@
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-__version__ = "$Revision$"
-
#
# Tests for the stats module
#
@@ -504,6 +502,13 @@ class TestStats(unittest.TestCase):
self.assertEqual(result_ok(),
self.session.get_message("Stats", None))
+ def test_for_boss(self):
+ last_queue = self.session.old_message_queue.pop()
+ self.assertEqual(
+ last_queue.msg, {'command': ['sendstats']})
+ self.assertEqual(
+ last_queue.env['group'], 'Boss')
+
class TestStats2(unittest.TestCase):
def setUp(self):
diff --git a/src/bin/xfrout/tests/Makefile.am b/src/bin/xfrout/tests/Makefile.am
index 01f2e40..76c5977 100644
--- a/src/bin/xfrout/tests/Makefile.am
+++ b/src/bin/xfrout/tests/Makefile.am
@@ -6,7 +6,7 @@ EXTRA_DIST = $(PYTESTS)
# required by loadable python modules.
LIBRARY_PATH_PLACEHOLDER =
if SET_ENV_LIBRARY_PATH
-LIBRARY_PATH_PLACEHOLDER += $(ENV_LIBRARY_PATH)=$(abs_top_builddir)/src/lib/dns/.libs:$(abs_top_builddir)/src/lib/exceptions/.libs:$(abs_top_builddir)/src/lib/xfr/.libs:$$$(ENV_LIBRARY_PATH)
+LIBRARY_PATH_PLACEHOLDER += $(ENV_LIBRARY_PATH)=$(abs_top_builddir)/src/lib/dns/.libs:$(abs_top_builddir)/src/lib/exceptions/.libs:$(abs_top_builddir)/src/lib/util/io/.libs:$$$(ENV_LIBRARY_PATH)
endif
# test using command-line arguments, so use check-local target instead of TESTS
@@ -18,7 +18,7 @@ if ENABLE_PYTHON_COVERAGE
endif
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
- env PYTHONPATH=$(abs_top_builddir)/src/bin/xfrout:$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/lib/dns/python/.libs:$(abs_top_builddir)/src/lib/xfr/.libs \
+ env PYTHONPATH=$(abs_top_builddir)/src/bin/xfrout:$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/lib/dns/python/.libs:$(abs_top_builddir)/src/lib/util/io/.libs \
$(LIBRARY_PATH_PLACEHOLDER) \
$(PYCOVERAGE_RUN) $(abs_srcdir)/$$pytest || exit ; \
done
diff --git a/src/bin/xfrout/tests/xfrout_test.py b/src/bin/xfrout/tests/xfrout_test.py
deleted file mode 100644
index 5aec072..0000000
--- a/src/bin/xfrout/tests/xfrout_test.py
+++ /dev/null
@@ -1,437 +0,0 @@
-# Copyright (C) 2010 Internet Systems Consortium.
-#
-# 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 the XfroutSession and UnixSockServer classes '''
-
-
-import unittest
-import os
-from isc.cc.session import *
-from pydnspp import *
-from xfrout import *
-
-# our fake socket, where we can read and insert messages
-class MySocket():
- def __init__(self, family, type):
- self.family = family
- self.type = type
- self.sendqueue = bytearray()
-
- def connect(self, to):
- pass
-
- def close(self):
- pass
-
- def send(self, data):
- self.sendqueue.extend(data);
- return len(data)
-
- def readsent(self):
- if len(self.sendqueue) >= 2:
- size = 2 + struct.unpack("!H", self.sendqueue[:2])[0]
- else:
- size = 0
- result = self.sendqueue[:size]
- self.sendqueue = self.sendqueue[size:]
- return result
-
- def read_msg(self):
- sent_data = self.readsent()
- get_msg = Message(Message.PARSE)
- get_msg.from_wire(bytes(sent_data[2:]))
- return get_msg
-
- def clear_send(self):
- del self.sendqueue[:]
-
-# We subclass the Session class we're testing here, only
-# to override the handle() and _send_data() method
-class MyXfroutSession(XfroutSession):
- def handle(self):
- pass
-
- def _send_data(self, sock, data):
- size = len(data)
- total_count = 0
- while total_count < size:
- count = sock.send(data[total_count:])
- total_count += count
-
-class Dbserver:
- def __init__(self):
- self._shutdown_event = threading.Event()
- def get_db_file(self):
- return None
- def decrease_transfers_counter(self):
- pass
-
-class TestXfroutSession(unittest.TestCase):
- def getmsg(self):
- msg = Message(Message.PARSE)
- msg.from_wire(self.mdata)
- return msg
-
- def setUp(self):
- self.sock = MySocket(socket.AF_INET,socket.SOCK_STREAM)
- self.log = isc.log.NSLogger('xfrout', '', severity = 'critical', log_to_console = False )
- self.xfrsess = MyXfroutSession(self.sock, None, Dbserver(), self.log)
- self.mdata = bytes(b'\xd6=\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x07example\x03com\x00\x00\xfc\x00\x01')
- self.soa_record = (4, 3, 'example.com.', 'com.example.', 3600, 'SOA', None, 'master.example.com. admin.example.com. 1234 3600 1800 2419200 7200')
-
- def test_parse_query_message(self):
- [get_rcode, get_msg] = self.xfrsess._parse_query_message(self.mdata)
- self.assertEqual(get_rcode.to_text(), "NOERROR")
-
- def test_get_query_zone_name(self):
- msg = self.getmsg()
- self.assertEqual(self.xfrsess._get_query_zone_name(msg), "example.com.")
-
- def test_send_data(self):
- self.xfrsess._send_data(self.sock, self.mdata)
- senddata = self.sock.readsent()
- self.assertEqual(senddata, self.mdata)
-
- def test_reply_xfrout_query_with_error_rcode(self):
- msg = self.getmsg()
- self.xfrsess._reply_query_with_error_rcode(msg, self.sock, Rcode(3))
- get_msg = self.sock.read_msg()
- self.assertEqual(get_msg.get_rcode().to_text(), "NXDOMAIN")
-
- def test_send_message(self):
- msg = self.getmsg()
- msg.make_response()
- # soa record data with different cases
- soa_record = (4, 3, 'Example.com.', 'com.Example.', 3600, 'SOA', None, 'master.Example.com. admin.exAmple.com. 1234 3600 1800 2419200 7200')
- rrset_soa = self.xfrsess._create_rrset_from_db_record(soa_record)
- msg.add_rrset(Message.SECTION_ANSWER, rrset_soa)
- self.xfrsess._send_message(self.sock, msg)
- send_out_data = self.sock.readsent()[2:]
-
- # CASE_INSENSITIVE compression mode
- render = MessageRenderer();
- render.set_length_limit(XFROUT_MAX_MESSAGE_SIZE)
- msg.to_wire(render)
- self.assertNotEqual(render.get_data(), send_out_data)
-
- # CASE_SENSITIVE compression mode
- render.clear()
- render.set_compress_mode(MessageRenderer.CASE_SENSITIVE)
- render.set_length_limit(XFROUT_MAX_MESSAGE_SIZE)
- msg.to_wire(render)
- self.assertEqual(render.get_data(), send_out_data)
-
- def test_clear_message(self):
- msg = self.getmsg()
- qid = msg.get_qid()
- opcode = msg.get_opcode()
- rcode = msg.get_rcode()
-
- self.xfrsess._clear_message(msg)
- self.assertEqual(msg.get_qid(), qid)
- self.assertEqual(msg.get_opcode(), opcode)
- self.assertEqual(msg.get_rcode(), rcode)
- self.assertTrue(msg.get_header_flag(Message.HEADERFLAG_AA))
-
- def test_reply_query_with_format_error(self):
- msg = self.getmsg()
- self.xfrsess._reply_query_with_format_error(msg, self.sock)
- get_msg = self.sock.read_msg()
- self.assertEqual(get_msg.get_rcode().to_text(), "FORMERR")
-
- def test_create_rrset_from_db_record(self):
- rrset = self.xfrsess._create_rrset_from_db_record(self.soa_record)
- self.assertEqual(rrset.get_name().to_text(), "example.com.")
- self.assertEqual(rrset.get_class(), RRClass("IN"))
- self.assertEqual(rrset.get_type().to_text(), "SOA")
- rdata = rrset.get_rdata()
- self.assertEqual(rdata[0].to_text(), self.soa_record[7])
-
- def test_send_message_with_last_soa(self):
- rrset_soa = self.xfrsess._create_rrset_from_db_record(self.soa_record)
-
- msg = self.getmsg()
- msg.make_response()
- self.xfrsess._send_message_with_last_soa(msg, self.sock, rrset_soa, 0)
- get_msg = self.sock.read_msg()
-
- self.assertEqual(get_msg.get_rr_count(Message.SECTION_QUESTION), 1)
- self.assertEqual(get_msg.get_rr_count(Message.SECTION_ANSWER), 1)
- self.assertEqual(get_msg.get_rr_count(Message.SECTION_AUTHORITY), 0)
-
- #answer_rrset_iter = section_iter(get_msg, section.ANSWER())
- answer = get_msg.get_section(Message.SECTION_ANSWER)[0]#answer_rrset_iter.get_rrset()
- self.assertEqual(answer.get_name().to_text(), "example.com.")
- self.assertEqual(answer.get_class(), RRClass("IN"))
- self.assertEqual(answer.get_type().to_text(), "SOA")
- rdata = answer.get_rdata()
- self.assertEqual(rdata[0].to_text(), self.soa_record[7])
-
- def test_trigger_send_message_with_last_soa(self):
- rrset_a = RRset(Name("example.com"), RRClass.IN(), RRType.A(), RRTTL(3600))
- rrset_a.add_rdata(Rdata(RRType.A(), RRClass.IN(), "192.0.2.1"))
- rrset_soa = self.xfrsess._create_rrset_from_db_record(self.soa_record)
-
- msg = self.getmsg()
- msg.make_response()
-
- msg.add_rrset(Message.SECTION_ANSWER, rrset_a)
- # give the function a value that is larger than MAX-len(rrset)
- self.xfrsess._send_message_with_last_soa(msg, self.sock, rrset_soa, 65520)
-
- # this should have triggered the sending of two messages
- # (1 with the rrset we added manually, and 1 that triggered
- # the sending in _with_last_soa)
- get_msg = self.sock.read_msg()
- self.assertEqual(get_msg.get_rr_count(Message.SECTION_QUESTION), 1)
- self.assertEqual(get_msg.get_rr_count(Message.SECTION_ANSWER), 1)
- self.assertEqual(get_msg.get_rr_count(Message.SECTION_AUTHORITY), 0)
-
- answer = get_msg.get_section(Message.SECTION_ANSWER)[0]
- self.assertEqual(answer.get_name().to_text(), "example.com.")
- self.assertEqual(answer.get_class(), RRClass("IN"))
- self.assertEqual(answer.get_type().to_text(), "A")
- rdata = answer.get_rdata()
- self.assertEqual(rdata[0].to_text(), "192.0.2.1")
-
- get_msg = self.sock.read_msg()
- self.assertEqual(get_msg.get_rr_count(Message.SECTION_QUESTION), 0)
- self.assertEqual(get_msg.get_rr_count(Message.SECTION_ANSWER), 1)
- self.assertEqual(get_msg.get_rr_count(Message.SECTION_AUTHORITY), 0)
-
- #answer_rrset_iter = section_iter(get_msg, Message.SECTION_ANSWER)
- answer = get_msg.get_section(Message.SECTION_ANSWER)[0]
- self.assertEqual(answer.get_name().to_text(), "example.com.")
- self.assertEqual(answer.get_class(), RRClass("IN"))
- self.assertEqual(answer.get_type().to_text(), "SOA")
- rdata = answer.get_rdata()
- self.assertEqual(rdata[0].to_text(), self.soa_record[7])
-
- # and it should not have sent anything else
- self.assertEqual(0, len(self.sock.sendqueue))
-
- def test_get_rrset_len(self):
- rrset_soa = self.xfrsess._create_rrset_from_db_record(self.soa_record)
- self.assertEqual(82, get_rrset_len(rrset_soa))
-
- def test_zone_has_soa(self):
- global sqlite3_ds
- def mydb1(zone, file):
- return True
- sqlite3_ds.get_zone_soa = mydb1
- self.assertTrue(self.xfrsess._zone_has_soa(""))
- def mydb2(zone, file):
- return False
- sqlite3_ds.get_zone_soa = mydb2
- self.assertFalse(self.xfrsess._zone_has_soa(""))
-
- def test_zone_exist(self):
- global sqlite3_ds
- def zone_exist(zone, file):
- return zone
- sqlite3_ds.zone_exist = zone_exist
- self.assertTrue(self.xfrsess._zone_exist(True))
- self.assertFalse(self.xfrsess._zone_exist(False))
-
- def test_check_xfrout_available(self):
- def zone_exist(zone):
- return zone
- def zone_has_soa(zone):
- return (not zone)
- self.xfrsess._zone_exist = zone_exist
- self.xfrsess._zone_has_soa = zone_has_soa
- self.assertEqual(self.xfrsess._check_xfrout_available(False).to_text(), "NOTAUTH")
- self.assertEqual(self.xfrsess._check_xfrout_available(True).to_text(), "SERVFAIL")
-
- def zone_empty(zone):
- return zone
- self.xfrsess._zone_has_soa = zone_empty
- def false_func():
- return False
- self.xfrsess._server.increase_transfers_counter = false_func
- self.assertEqual(self.xfrsess._check_xfrout_available(True).to_text(), "REFUSED")
- def true_func():
- return True
- self.xfrsess._server.increase_transfers_counter = true_func
- self.assertEqual(self.xfrsess._check_xfrout_available(True).to_text(), "NOERROR")
-
- def test_dns_xfrout_start_formerror(self):
- # formerror
- self.xfrsess.dns_xfrout_start(self.sock, b"\xd6=\x00\x00\x00\x01\x00")
- sent_data = self.sock.readsent()
- self.assertEqual(len(sent_data), 0)
-
- def default(self, param):
- return "example.com"
-
- def test_dns_xfrout_start_notauth(self):
- self.xfrsess._get_query_zone_name = self.default
- def notauth(formpara):
- return Rcode.NOTAUTH()
- self.xfrsess._check_xfrout_available = notauth
- self.xfrsess.dns_xfrout_start(self.sock, self.mdata)
- get_msg = self.sock.read_msg()
- self.assertEqual(get_msg.get_rcode().to_text(), "NOTAUTH")
-
- def test_dns_xfrout_start_noerror(self):
- self.xfrsess._get_query_zone_name = self.default
- def noerror(form):
- return Rcode.NOERROR()
- self.xfrsess._check_xfrout_available = noerror
-
- def myreply(msg, sock, zonename):
- self.sock.send(b"success")
-
- self.xfrsess._reply_xfrout_query = myreply
- self.xfrsess.dns_xfrout_start(self.sock, self.mdata)
- self.assertEqual(self.sock.readsent(), b"success")
-
- def test_reply_xfrout_query_noerror(self):
- global sqlite3_ds
- def get_zone_soa(zonename, file):
- return self.soa_record
-
- def get_zone_datas(zone, file):
- return [self.soa_record]
-
- sqlite3_ds.get_zone_soa = get_zone_soa
- sqlite3_ds.get_zone_datas = get_zone_datas
- self.xfrsess._reply_xfrout_query(self.getmsg(), self.sock, "example.com.")
- reply_msg = self.sock.read_msg()
- self.assertEqual(reply_msg.get_rr_count(Message.SECTION_ANSWER), 2)
-
-class MyCCSession():
- def __init__(self):
- pass
-
- def get_remote_config_value(self, module_name, identifier):
- if module_name == "Auth" and identifier == "database_file":
- return "initdb.file", False
- else:
- return "unknown", False
-
-
-class MyUnixSockServer(UnixSockServer):
- def __init__(self):
- self._lock = threading.Lock()
- self._transfers_counter = 0
- self._shutdown_event = threading.Event()
- self._max_transfers_out = 10
- self._cc = MyCCSession()
- self._log = isc.log.NSLogger('xfrout', '', severity = 'critical', log_to_console = False )
-
-class TestUnixSockServer(unittest.TestCase):
- def setUp(self):
- self.write_sock, self.read_sock = socket.socketpair()
- self.unix = MyUnixSockServer()
-
- def test_receive_query_message(self):
- send_msg = b"\xd6=\x00\x00\x00\x01\x00"
- msg_len = struct.pack('H', socket.htons(len(send_msg)))
- self.write_sock.send(msg_len)
- self.write_sock.send(send_msg)
- recv_msg = self.unix._receive_query_message(self.read_sock)
- self.assertEqual(recv_msg, send_msg)
-
- def test_updata_config_data(self):
- self.unix.update_config_data({'transfers_out':10 })
- self.assertEqual(self.unix._max_transfers_out, 10)
-
- def test_get_db_file(self):
- self.assertEqual(self.unix.get_db_file(), "initdb.file")
-
- def test_increase_transfers_counter(self):
- self.unix._max_transfers_out = 10
- count = self.unix._transfers_counter
- self.assertEqual(self.unix.increase_transfers_counter(), True)
- self.assertEqual(count + 1, self.unix._transfers_counter)
-
- self.unix._max_transfers_out = 0
- count = self.unix._transfers_counter
- self.assertEqual(self.unix.increase_transfers_counter(), False)
- self.assertEqual(count, self.unix._transfers_counter)
-
- def test_decrease_transfers_counter(self):
- count = self.unix._transfers_counter
- self.unix.decrease_transfers_counter()
- self.assertEqual(count - 1, self.unix._transfers_counter)
-
- def _remove_file(self, sock_file):
- try:
- os.remove(sock_file)
- except OSError:
- pass
-
- def test_sock_file_in_use_file_exist(self):
- sock_file = 'temp.sock.file'
- self._remove_file(sock_file)
- self.assertFalse(self.unix._sock_file_in_use(sock_file))
- self.assertFalse(os.path.exists(sock_file))
-
- def test_sock_file_in_use_file_not_exist(self):
- self.assertFalse(self.unix._sock_file_in_use('temp.sock.file'))
-
- def _start_unix_sock_server(self, sock_file):
- serv = ThreadingUnixStreamServer(sock_file, BaseRequestHandler)
- serv_thread = threading.Thread(target=serv.serve_forever)
- serv_thread.setDaemon(True)
- serv_thread.start()
-
- def test_sock_file_in_use(self):
- sock_file = 'temp.sock.file'
- self._remove_file(sock_file)
- self.assertFalse(self.unix._sock_file_in_use(sock_file))
- self._start_unix_sock_server(sock_file)
-
- old_stdout = sys.stdout
- sys.stdout = open(os.devnull, 'w')
- self.assertTrue(self.unix._sock_file_in_use(sock_file))
- sys.stdout = old_stdout
-
- def test_remove_unused_sock_file_in_use(self):
- sock_file = 'temp.sock.file'
- self._remove_file(sock_file)
- self.assertFalse(self.unix._sock_file_in_use(sock_file))
- self._start_unix_sock_server(sock_file)
- old_stdout = sys.stdout
- sys.stdout = open(os.devnull, 'w')
- try:
- self.unix._remove_unused_sock_file(sock_file)
- except SystemExit:
- pass
- else:
- # This should never happen
- self.assertTrue(False)
-
- sys.stdout = old_stdout
-
- def test_remove_unused_sock_file_dir(self):
- import tempfile
- dir_name = tempfile.mkdtemp()
- old_stdout = sys.stdout
- sys.stdout = open(os.devnull, 'w')
- try:
- self.unix._remove_unused_sock_file(dir_name)
- except SystemExit:
- pass
- else:
- # This should never happen
- self.assertTrue(False)
-
- sys.stdout = old_stdout
- os.rmdir(dir_name)
-
-if __name__== "__main__":
- unittest.main()
diff --git a/src/bin/xfrout/tests/xfrout_test.py.in b/src/bin/xfrout/tests/xfrout_test.py.in
new file mode 100644
index 0000000..472ef3c
--- /dev/null
+++ b/src/bin/xfrout/tests/xfrout_test.py.in
@@ -0,0 +1,469 @@
+# Copyright (C) 2010 Internet Systems Consortium.
+#
+# 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 the XfroutSession and UnixSockServer classes '''
+
+
+import unittest
+import os
+from isc.cc.session import *
+from pydnspp import *
+from xfrout import *
+import xfrout
+
+# our fake socket, where we can read and insert messages
+class MySocket():
+ def __init__(self, family, type):
+ self.family = family
+ self.type = type
+ self.sendqueue = bytearray()
+
+ def connect(self, to):
+ pass
+
+ def close(self):
+ pass
+
+ def send(self, data):
+ self.sendqueue.extend(data);
+ return len(data)
+
+ def readsent(self):
+ if len(self.sendqueue) >= 2:
+ size = 2 + struct.unpack("!H", self.sendqueue[:2])[0]
+ else:
+ size = 0
+ result = self.sendqueue[:size]
+ self.sendqueue = self.sendqueue[size:]
+ return result
+
+ def read_msg(self):
+ sent_data = self.readsent()
+ get_msg = Message(Message.PARSE)
+ get_msg.from_wire(bytes(sent_data[2:]))
+ return get_msg
+
+ def clear_send(self):
+ del self.sendqueue[:]
+
+# We subclass the Session class we're testing here, only
+# to override the handle() and _send_data() method
+class MyXfroutSession(XfroutSession):
+ def handle(self):
+ pass
+
+ def _send_data(self, sock, data):
+ size = len(data)
+ total_count = 0
+ while total_count < size:
+ count = sock.send(data[total_count:])
+ total_count += count
+
+class Dbserver:
+ def __init__(self):
+ self._shutdown_event = threading.Event()
+ def get_db_file(self):
+ return None
+ def decrease_transfers_counter(self):
+ pass
+
+class TestXfroutSession(unittest.TestCase):
+ def getmsg(self):
+ msg = Message(Message.PARSE)
+ msg.from_wire(self.mdata)
+ return msg
+
+ def setUp(self):
+ self.sock = MySocket(socket.AF_INET,socket.SOCK_STREAM)
+ self.log = isc.log.NSLogger('xfrout', '', severity = 'critical', log_to_console = False )
+ self.xfrsess = MyXfroutSession(self.sock, None, Dbserver(), self.log)
+ self.mdata = bytes(b'\xd6=\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x07example\x03com\x00\x00\xfc\x00\x01')
+ self.soa_record = (4, 3, 'example.com.', 'com.example.', 3600, 'SOA', None, 'master.example.com. admin.example.com. 1234 3600 1800 2419200 7200')
+
+ def test_parse_query_message(self):
+ [get_rcode, get_msg] = self.xfrsess._parse_query_message(self.mdata)
+ self.assertEqual(get_rcode.to_text(), "NOERROR")
+
+ def test_get_query_zone_name(self):
+ msg = self.getmsg()
+ self.assertEqual(self.xfrsess._get_query_zone_name(msg), "example.com.")
+
+ def test_send_data(self):
+ self.xfrsess._send_data(self.sock, self.mdata)
+ senddata = self.sock.readsent()
+ self.assertEqual(senddata, self.mdata)
+
+ def test_reply_xfrout_query_with_error_rcode(self):
+ msg = self.getmsg()
+ self.xfrsess._reply_query_with_error_rcode(msg, self.sock, Rcode(3))
+ get_msg = self.sock.read_msg()
+ self.assertEqual(get_msg.get_rcode().to_text(), "NXDOMAIN")
+
+ def test_send_message(self):
+ msg = self.getmsg()
+ msg.make_response()
+ # soa record data with different cases
+ soa_record = (4, 3, 'Example.com.', 'com.Example.', 3600, 'SOA', None, 'master.Example.com. admin.exAmple.com. 1234 3600 1800 2419200 7200')
+ rrset_soa = self.xfrsess._create_rrset_from_db_record(soa_record)
+ msg.add_rrset(Message.SECTION_ANSWER, rrset_soa)
+ self.xfrsess._send_message(self.sock, msg)
+ send_out_data = self.sock.readsent()[2:]
+
+ # CASE_INSENSITIVE compression mode
+ render = MessageRenderer();
+ render.set_length_limit(XFROUT_MAX_MESSAGE_SIZE)
+ msg.to_wire(render)
+ self.assertNotEqual(render.get_data(), send_out_data)
+
+ # CASE_SENSITIVE compression mode
+ render.clear()
+ render.set_compress_mode(MessageRenderer.CASE_SENSITIVE)
+ render.set_length_limit(XFROUT_MAX_MESSAGE_SIZE)
+ msg.to_wire(render)
+ self.assertEqual(render.get_data(), send_out_data)
+
+ def test_clear_message(self):
+ msg = self.getmsg()
+ qid = msg.get_qid()
+ opcode = msg.get_opcode()
+ rcode = msg.get_rcode()
+
+ self.xfrsess._clear_message(msg)
+ self.assertEqual(msg.get_qid(), qid)
+ self.assertEqual(msg.get_opcode(), opcode)
+ self.assertEqual(msg.get_rcode(), rcode)
+ self.assertTrue(msg.get_header_flag(Message.HEADERFLAG_AA))
+
+ def test_reply_query_with_format_error(self):
+ msg = self.getmsg()
+ self.xfrsess._reply_query_with_format_error(msg, self.sock)
+ get_msg = self.sock.read_msg()
+ self.assertEqual(get_msg.get_rcode().to_text(), "FORMERR")
+
+ def test_create_rrset_from_db_record(self):
+ rrset = self.xfrsess._create_rrset_from_db_record(self.soa_record)
+ self.assertEqual(rrset.get_name().to_text(), "example.com.")
+ self.assertEqual(rrset.get_class(), RRClass("IN"))
+ self.assertEqual(rrset.get_type().to_text(), "SOA")
+ rdata = rrset.get_rdata()
+ self.assertEqual(rdata[0].to_text(), self.soa_record[7])
+
+ def test_send_message_with_last_soa(self):
+ rrset_soa = self.xfrsess._create_rrset_from_db_record(self.soa_record)
+
+ msg = self.getmsg()
+ msg.make_response()
+ self.xfrsess._send_message_with_last_soa(msg, self.sock, rrset_soa, 0)
+ get_msg = self.sock.read_msg()
+
+ self.assertEqual(get_msg.get_rr_count(Message.SECTION_QUESTION), 1)
+ self.assertEqual(get_msg.get_rr_count(Message.SECTION_ANSWER), 1)
+ self.assertEqual(get_msg.get_rr_count(Message.SECTION_AUTHORITY), 0)
+
+ #answer_rrset_iter = section_iter(get_msg, section.ANSWER())
+ answer = get_msg.get_section(Message.SECTION_ANSWER)[0]#answer_rrset_iter.get_rrset()
+ self.assertEqual(answer.get_name().to_text(), "example.com.")
+ self.assertEqual(answer.get_class(), RRClass("IN"))
+ self.assertEqual(answer.get_type().to_text(), "SOA")
+ rdata = answer.get_rdata()
+ self.assertEqual(rdata[0].to_text(), self.soa_record[7])
+
+ def test_trigger_send_message_with_last_soa(self):
+ rrset_a = RRset(Name("example.com"), RRClass.IN(), RRType.A(), RRTTL(3600))
+ rrset_a.add_rdata(Rdata(RRType.A(), RRClass.IN(), "192.0.2.1"))
+ rrset_soa = self.xfrsess._create_rrset_from_db_record(self.soa_record)
+
+ msg = self.getmsg()
+ msg.make_response()
+
+ msg.add_rrset(Message.SECTION_ANSWER, rrset_a)
+ # give the function a value that is larger than MAX-len(rrset)
+ self.xfrsess._send_message_with_last_soa(msg, self.sock, rrset_soa, 65520)
+
+ # this should have triggered the sending of two messages
+ # (1 with the rrset we added manually, and 1 that triggered
+ # the sending in _with_last_soa)
+ get_msg = self.sock.read_msg()
+ self.assertEqual(get_msg.get_rr_count(Message.SECTION_QUESTION), 1)
+ self.assertEqual(get_msg.get_rr_count(Message.SECTION_ANSWER), 1)
+ self.assertEqual(get_msg.get_rr_count(Message.SECTION_AUTHORITY), 0)
+
+ answer = get_msg.get_section(Message.SECTION_ANSWER)[0]
+ self.assertEqual(answer.get_name().to_text(), "example.com.")
+ self.assertEqual(answer.get_class(), RRClass("IN"))
+ self.assertEqual(answer.get_type().to_text(), "A")
+ rdata = answer.get_rdata()
+ self.assertEqual(rdata[0].to_text(), "192.0.2.1")
+
+ get_msg = self.sock.read_msg()
+ self.assertEqual(get_msg.get_rr_count(Message.SECTION_QUESTION), 0)
+ self.assertEqual(get_msg.get_rr_count(Message.SECTION_ANSWER), 1)
+ self.assertEqual(get_msg.get_rr_count(Message.SECTION_AUTHORITY), 0)
+
+ #answer_rrset_iter = section_iter(get_msg, Message.SECTION_ANSWER)
+ answer = get_msg.get_section(Message.SECTION_ANSWER)[0]
+ self.assertEqual(answer.get_name().to_text(), "example.com.")
+ self.assertEqual(answer.get_class(), RRClass("IN"))
+ self.assertEqual(answer.get_type().to_text(), "SOA")
+ rdata = answer.get_rdata()
+ self.assertEqual(rdata[0].to_text(), self.soa_record[7])
+
+ # and it should not have sent anything else
+ self.assertEqual(0, len(self.sock.sendqueue))
+
+ def test_get_rrset_len(self):
+ rrset_soa = self.xfrsess._create_rrset_from_db_record(self.soa_record)
+ self.assertEqual(82, get_rrset_len(rrset_soa))
+
+ def test_zone_has_soa(self):
+ global sqlite3_ds
+ def mydb1(zone, file):
+ return True
+ sqlite3_ds.get_zone_soa = mydb1
+ self.assertTrue(self.xfrsess._zone_has_soa(""))
+ def mydb2(zone, file):
+ return False
+ sqlite3_ds.get_zone_soa = mydb2
+ self.assertFalse(self.xfrsess._zone_has_soa(""))
+
+ def test_zone_exist(self):
+ global sqlite3_ds
+ def zone_exist(zone, file):
+ return zone
+ sqlite3_ds.zone_exist = zone_exist
+ self.assertTrue(self.xfrsess._zone_exist(True))
+ self.assertFalse(self.xfrsess._zone_exist(False))
+
+ def test_check_xfrout_available(self):
+ def zone_exist(zone):
+ return zone
+ def zone_has_soa(zone):
+ return (not zone)
+ self.xfrsess._zone_exist = zone_exist
+ self.xfrsess._zone_has_soa = zone_has_soa
+ self.assertEqual(self.xfrsess._check_xfrout_available(False).to_text(), "NOTAUTH")
+ self.assertEqual(self.xfrsess._check_xfrout_available(True).to_text(), "SERVFAIL")
+
+ def zone_empty(zone):
+ return zone
+ self.xfrsess._zone_has_soa = zone_empty
+ def false_func():
+ return False
+ self.xfrsess._server.increase_transfers_counter = false_func
+ self.assertEqual(self.xfrsess._check_xfrout_available(True).to_text(), "REFUSED")
+ def true_func():
+ return True
+ self.xfrsess._server.increase_transfers_counter = true_func
+ self.assertEqual(self.xfrsess._check_xfrout_available(True).to_text(), "NOERROR")
+
+ def test_dns_xfrout_start_formerror(self):
+ # formerror
+ self.xfrsess.dns_xfrout_start(self.sock, b"\xd6=\x00\x00\x00\x01\x00")
+ sent_data = self.sock.readsent()
+ self.assertEqual(len(sent_data), 0)
+
+ def default(self, param):
+ return "example.com"
+
+ def test_dns_xfrout_start_notauth(self):
+ self.xfrsess._get_query_zone_name = self.default
+ def notauth(formpara):
+ return Rcode.NOTAUTH()
+ self.xfrsess._check_xfrout_available = notauth
+ self.xfrsess.dns_xfrout_start(self.sock, self.mdata)
+ get_msg = self.sock.read_msg()
+ self.assertEqual(get_msg.get_rcode().to_text(), "NOTAUTH")
+
+ def test_dns_xfrout_start_noerror(self):
+ self.xfrsess._get_query_zone_name = self.default
+ def noerror(form):
+ return Rcode.NOERROR()
+ self.xfrsess._check_xfrout_available = noerror
+
+ def myreply(msg, sock, zonename):
+ self.sock.send(b"success")
+
+ self.xfrsess._reply_xfrout_query = myreply
+ self.xfrsess.dns_xfrout_start(self.sock, self.mdata)
+ self.assertEqual(self.sock.readsent(), b"success")
+
+ def test_reply_xfrout_query_noerror(self):
+ global sqlite3_ds
+ def get_zone_soa(zonename, file):
+ return self.soa_record
+
+ def get_zone_datas(zone, file):
+ return [self.soa_record]
+
+ sqlite3_ds.get_zone_soa = get_zone_soa
+ sqlite3_ds.get_zone_datas = get_zone_datas
+ self.xfrsess._reply_xfrout_query(self.getmsg(), self.sock, "example.com.")
+ reply_msg = self.sock.read_msg()
+ self.assertEqual(reply_msg.get_rr_count(Message.SECTION_ANSWER), 2)
+
+class MyCCSession():
+ def __init__(self):
+ pass
+
+ def get_remote_config_value(self, module_name, identifier):
+ if module_name == "Auth" and identifier == "database_file":
+ return "initdb.file", False
+ else:
+ return "unknown", False
+
+
+class MyUnixSockServer(UnixSockServer):
+ def __init__(self):
+ self._lock = threading.Lock()
+ self._transfers_counter = 0
+ self._shutdown_event = threading.Event()
+ self._max_transfers_out = 10
+ self._cc = MyCCSession()
+ self._log = isc.log.NSLogger('xfrout', '', severity = 'critical', log_to_console = False )
+
+class TestUnixSockServer(unittest.TestCase):
+ def setUp(self):
+ self.write_sock, self.read_sock = socket.socketpair()
+ self.unix = MyUnixSockServer()
+
+ def test_receive_query_message(self):
+ send_msg = b"\xd6=\x00\x00\x00\x01\x00"
+ msg_len = struct.pack('H', socket.htons(len(send_msg)))
+ self.write_sock.send(msg_len)
+ self.write_sock.send(send_msg)
+ recv_msg = self.unix._receive_query_message(self.read_sock)
+ self.assertEqual(recv_msg, send_msg)
+
+ def test_updata_config_data(self):
+ self.unix.update_config_data({'transfers_out':10 })
+ self.assertEqual(self.unix._max_transfers_out, 10)
+
+ def test_get_db_file(self):
+ self.assertEqual(self.unix.get_db_file(), "initdb.file")
+
+ def test_increase_transfers_counter(self):
+ self.unix._max_transfers_out = 10
+ count = self.unix._transfers_counter
+ self.assertEqual(self.unix.increase_transfers_counter(), True)
+ self.assertEqual(count + 1, self.unix._transfers_counter)
+
+ self.unix._max_transfers_out = 0
+ count = self.unix._transfers_counter
+ self.assertEqual(self.unix.increase_transfers_counter(), False)
+ self.assertEqual(count, self.unix._transfers_counter)
+
+ def test_decrease_transfers_counter(self):
+ count = self.unix._transfers_counter
+ self.unix.decrease_transfers_counter()
+ self.assertEqual(count - 1, self.unix._transfers_counter)
+
+ def _remove_file(self, sock_file):
+ try:
+ os.remove(sock_file)
+ except OSError:
+ pass
+
+ def test_sock_file_in_use_file_exist(self):
+ sock_file = 'temp.sock.file'
+ self._remove_file(sock_file)
+ self.assertFalse(self.unix._sock_file_in_use(sock_file))
+ self.assertFalse(os.path.exists(sock_file))
+
+ def test_sock_file_in_use_file_not_exist(self):
+ self.assertFalse(self.unix._sock_file_in_use('temp.sock.file'))
+
+ def _start_unix_sock_server(self, sock_file):
+ serv = ThreadingUnixStreamServer(sock_file, BaseRequestHandler)
+ serv_thread = threading.Thread(target=serv.serve_forever)
+ serv_thread.setDaemon(True)
+ serv_thread.start()
+
+ def test_sock_file_in_use(self):
+ sock_file = 'temp.sock.file'
+ self._remove_file(sock_file)
+ self.assertFalse(self.unix._sock_file_in_use(sock_file))
+ self._start_unix_sock_server(sock_file)
+
+ old_stdout = sys.stdout
+ sys.stdout = open(os.devnull, 'w')
+ self.assertTrue(self.unix._sock_file_in_use(sock_file))
+ sys.stdout = old_stdout
+
+ def test_remove_unused_sock_file_in_use(self):
+ sock_file = 'temp.sock.file'
+ self._remove_file(sock_file)
+ self.assertFalse(self.unix._sock_file_in_use(sock_file))
+ self._start_unix_sock_server(sock_file)
+ old_stdout = sys.stdout
+ sys.stdout = open(os.devnull, 'w')
+ try:
+ self.unix._remove_unused_sock_file(sock_file)
+ except SystemExit:
+ pass
+ else:
+ # This should never happen
+ self.assertTrue(False)
+
+ sys.stdout = old_stdout
+
+ def test_remove_unused_sock_file_dir(self):
+ import tempfile
+ dir_name = tempfile.mkdtemp()
+ old_stdout = sys.stdout
+ sys.stdout = open(os.devnull, 'w')
+ try:
+ self.unix._remove_unused_sock_file(dir_name)
+ except SystemExit:
+ pass
+ else:
+ # This should never happen
+ self.assertTrue(False)
+
+ sys.stdout = old_stdout
+ os.rmdir(dir_name)
+
+class TestInitialization(unittest.TestCase):
+ def setEnv(self, name, value):
+ if value is None:
+ if name in os.environ:
+ del os.environ[name]
+ else:
+ os.environ[name] = value
+
+ def setUp(self):
+ self._oldSocket = os.getenv("BIND10_XFROUT_SOCKET_FILE")
+ self._oldFromBuild = os.getenv("B10_FROM_BUILD")
+
+ def tearDown(self):
+ self.setEnv("B10_FROM_BUILD", self._oldFromBuild)
+ self.setEnv("BIND10_XFROUT_SOCKET_FILE", self._oldSocket)
+ # Make sure even the computed values are back
+ xfrout.init_paths()
+
+ def testNoEnv(self):
+ self.setEnv("B10_FROM_BUILD", None)
+ self.setEnv("BIND10_XFROUT_SOCKET_FILE", None)
+ xfrout.init_paths()
+ self.assertEqual(xfrout.UNIX_SOCKET_FILE,
+ "@@LOCALSTATEDIR@@/auth_xfrout_conn")
+
+ def testProvidedSocket(self):
+ self.setEnv("B10_FROM_BUILD", None)
+ self.setEnv("BIND10_XFROUT_SOCKET_FILE", "The/Socket/File")
+ xfrout.init_paths()
+ self.assertEqual(xfrout.UNIX_SOCKET_FILE, "The/Socket/File")
+
+if __name__== "__main__":
+ unittest.main()
diff --git a/src/bin/xfrout/xfrout.py.in b/src/bin/xfrout/xfrout.py.in
index b3f9e95..17ca3eb 100755
--- a/src/bin/xfrout/xfrout.py.in
+++ b/src/bin/xfrout/xfrout.py.in
@@ -37,29 +37,38 @@ from optparse import OptionParser, OptionValueError
from isc.util import socketserver_mixin
try:
- from libxfr_python import *
+ from libutil_io_python import *
from pydnspp import *
except ImportError as e:
# C++ loadable module may not be installed; even so the xfrout process
# must keep running, so we warn about it and move forward.
- sys.stderr.write('[b10-xfrout] failed to import DNS or XFR module: %s\n' % str(e))
+ sys.stderr.write('[b10-xfrout] failed to import DNS or isc.util.io module: %s\n' % str(e))
isc.util.process.rename()
-if "B10_FROM_BUILD" in os.environ:
- SPECFILE_PATH = os.environ["B10_FROM_BUILD"] + "/src/bin/xfrout"
- AUTH_SPECFILE_PATH = os.environ["B10_FROM_BUILD"] + "/src/bin/auth"
- if "B10_FROM_SOURCE_LOCALSTATEDIR" in os.environ:
- UNIX_SOCKET_FILE = os.environ["B10_FROM_SOURCE_LOCALSTATEDIR"] + \
- "/auth_xfrout_conn"
+def init_paths():
+ global SPECFILE_PATH
+ global AUTH_SPECFILE_PATH
+ global UNIX_SOCKET_FILE
+ if "B10_FROM_BUILD" in os.environ:
+ SPECFILE_PATH = os.environ["B10_FROM_BUILD"] + "/src/bin/xfrout"
+ AUTH_SPECFILE_PATH = os.environ["B10_FROM_BUILD"] + "/src/bin/auth"
+ if "B10_FROM_SOURCE_LOCALSTATEDIR" in os.environ:
+ UNIX_SOCKET_FILE = os.environ["B10_FROM_SOURCE_LOCALSTATEDIR"] + \
+ "/auth_xfrout_conn"
+ else:
+ UNIX_SOCKET_FILE = os.environ["B10_FROM_BUILD"] + "/auth_xfrout_conn"
else:
- UNIX_SOCKET_FILE = os.environ["B10_FROM_BUILD"] + "/auth_xfrout_conn"
-else:
- PREFIX = "@prefix@"
- DATAROOTDIR = "@datarootdir@"
- SPECFILE_PATH = "@datadir@/@PACKAGE@".replace("${datarootdir}", DATAROOTDIR).replace("${prefix}", PREFIX)
- AUTH_SPECFILE_PATH = SPECFILE_PATH
- UNIX_SOCKET_FILE = "@@LOCALSTATEDIR@@/auth_xfrout_conn"
+ PREFIX = "@prefix@"
+ DATAROOTDIR = "@datarootdir@"
+ SPECFILE_PATH = "@datadir@/@PACKAGE@".replace("${datarootdir}", DATAROOTDIR).replace("${prefix}", PREFIX)
+ AUTH_SPECFILE_PATH = SPECFILE_PATH
+ if "BIND10_XFROUT_SOCKET_FILE" in os.environ:
+ UNIX_SOCKET_FILE = os.environ["BIND10_XFROUT_SOCKET_FILE"]
+ else:
+ UNIX_SOCKET_FILE = "@@LOCALSTATEDIR@@/auth_xfrout_conn"
+
+init_paths()
SPECFILE_LOCATION = SPECFILE_PATH + "/xfrout.spec"
AUTH_SPECFILE_LOCATION = AUTH_SPECFILE_PATH + os.sep + "auth.spec"
@@ -376,7 +385,7 @@ class UnixSockServer(socketserver_mixin.NoPollMixIn, ThreadingUnixStreamServer):
# This may happen when one xfrout process try to connect to
# xfrout unix socket server, to check whether there is another
# xfrout running.
- if sock_fd == XFR_FD_RECEIVE_FAIL:
+ if sock_fd == FD_COMM_ERROR:
self._log.log_message("error", "Failed to receive the file descriptor for XFR connection")
return
diff --git a/src/bin/zonemgr/tests/zonemgr_test.py b/src/bin/zonemgr/tests/zonemgr_test.py
index 70dc1b0..2e9f685 100644
--- a/src/bin/zonemgr/tests/zonemgr_test.py
+++ b/src/bin/zonemgr/tests/zonemgr_test.py
@@ -22,10 +22,10 @@ import tempfile
from zonemgr import *
ZONE_NAME_CLASS1_IN = ("sd.cn.", "IN")
-ZONE_NAME_CLASS2_CH = ("tw.cn", "CH")
+ZONE_NAME_CLASS2_CH = ("tw.cn.", "CH")
ZONE_NAME_CLASS3_IN = ("example.com", "IN")
ZONE_NAME_CLASS1_CH = ("sd.cn.", "CH")
-ZONE_NAME_CLASS2_IN = ("tw.cn", "IN")
+ZONE_NAME_CLASS2_IN = ("tw.cn.", "IN")
MAX_TRANSFER_TIMEOUT = 14400
LOWERBOUND_REFRESH = 10
@@ -46,21 +46,43 @@ class MySession():
def group_recvmsg(self, nonblock, seq):
return None, None
+class FakeConfig:
+ def __init__(self):
+ self.zone_list = []
+ self.set_zone_list_from_name_classes([ZONE_NAME_CLASS1_IN,
+ ZONE_NAME_CLASS2_CH])
+ def set_zone_list_from_name_classes(self, zones):
+ self.zone_list = map(lambda nc: {"name": nc[0], "class": nc[1]}, zones)
+ def get(self, name):
+ if name == 'lowerbound_refresh':
+ return LOWERBOUND_REFRESH
+ elif name == 'lowerbound_retry':
+ return LOWERBOUND_RETRY
+ elif name == 'max_transfer_timeout':
+ return MAX_TRANSFER_TIMEOUT
+ elif name == 'jitter_scope':
+ return JITTER_SCOPE
+ elif name == 'secondary_zones':
+ return self.zone_list
+ else:
+ raise ValueError('Uknown config option')
+
class MyZonemgrRefresh(ZonemgrRefresh):
def __init__(self):
- class FakeConfig:
- def get(self, name):
- if name == 'lowerbound_refresh':
- return LOWERBOUND_REFRESH
- elif name == 'lowerbound_retry':
- return LOWERBOUND_RETRY
- elif name == 'max_transfer_timeout':
- return MAX_TRANSFER_TIMEOUT
- elif name == 'jitter_scope':
- return JITTER_SCOPE
- else:
- raise ValueError('Uknown config option')
self._master_socket, self._slave_socket = socket.socketpair()
+ self._zonemgr_refresh_info = {}
+
+ def get_zone_soa(zone_name, db_file):
+ if zone_name == 'sd.cn.':
+ return (1, 2, 'sd.cn.', 'cn.sd.', 21600, 'SOA', None,
+ 'a.dns.cn. root.cnnic.cn. 2009073106 7200 3600 2419200 21600')
+ elif zone_name == 'tw.cn.':
+ return (1, 2, 'tw.cn.', 'cn.sd.', 21600, 'SOA', None,
+ 'a.dns.cn. root.cnnic.cn. 2009073112 7200 3600 2419200 21600')
+ else:
+ return None
+ sqlite3_ds.get_zone_soa = get_zone_soa
+
ZonemgrRefresh.__init__(self, MySession(), "initdb.file",
self._slave_socket, FakeConfig())
current_time = time.time()
@@ -70,7 +92,7 @@ class MyZonemgrRefresh(ZonemgrRefresh):
'next_refresh_time': current_time + 6500,
'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600',
'zone_state': 0},
- ('tw.cn', 'CH'): {
+ ('tw.cn.', 'CH'): {
'last_refresh_time': current_time,
'next_refresh_time': current_time + 6900,
'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073112 7200 3600 2419200 21600',
@@ -272,28 +294,6 @@ class TestZonemgrRefresh(unittest.TestCase):
ZONE_NAME_CLASS1_IN)
sqlite3_ds.get_zone_soa = old_get_zone_soa
- def test_build_zonemgr_refresh_info(self):
- soa_rdata = 'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600'
-
- def get_zones_info(db_file):
- return [("sd.cn.", "IN")]
-
- def get_zone_soa(zone_name, db_file):
- return (1, 2, 'sd.cn.', 'cn.sd.', 21600, 'SOA', None,
- 'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600')
-
- sqlite3_ds.get_zones_info = get_zones_info
- sqlite3_ds.get_zone_soa = get_zone_soa
-
- self.zone_refresh._zonemgr_refresh_info = {}
- self.zone_refresh._build_zonemgr_refresh_info()
- self.assertEqual(1, len(self.zone_refresh._zonemgr_refresh_info))
- zone_soa_rdata = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_soa_rdata"]
- self.assertEqual(soa_rdata, zone_soa_rdata)
- self.assertEqual(ZONE_OK, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"])
- self.assertTrue("last_refresh_time" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
- self.assertTrue("next_refresh_time" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
-
def test_zone_handle_notify(self):
self.zone_refresh.zone_handle_notify(ZONE_NAME_CLASS1_IN,"127.0.0.1")
notify_master = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["notify_master"]
@@ -356,7 +356,7 @@ class TestZonemgrRefresh(unittest.TestCase):
'next_refresh_time': time1 + 7200,
'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600',
'zone_state': ZONE_OK},
- ("tw.cn","CH"):{
+ ("tw.cn.","CH"):{
'last_refresh_time': time1 - 7200,
'next_refresh_time': time1,
'refresh_timeout': time1 + MAX_TRANSFER_TIMEOUT,
@@ -424,7 +424,8 @@ class TestZonemgrRefresh(unittest.TestCase):
"lowerbound_refresh" : 60,
"lowerbound_retry" : 30,
"max_transfer_timeout" : 19800,
- "jitter_scope" : 0.25
+ "jitter_scope" : 0.25,
+ "secondary_zones": []
}
self.zone_refresh.update_config_data(config_data)
self.assertEqual(60, self.zone_refresh._lowerbound_refresh)
@@ -440,6 +441,31 @@ class TestZonemgrRefresh(unittest.TestCase):
self.zone_refresh.shutdown()
self.assertFalse(listener.is_alive())
+ def test_secondary_zones(self):
+ """Test that we can modify the list of secondary zones"""
+ config = FakeConfig()
+ config.zone_list = []
+ # First, remove everything
+ self.zone_refresh.update_config_data(config)
+ self.assertEqual(self.zone_refresh._zonemgr_refresh_info, {})
+ # Put something in
+ config.set_zone_list_from_name_classes([ZONE_NAME_CLASS1_IN])
+ self.zone_refresh.update_config_data(config)
+ self.assertTrue(("sd.cn.", "IN") in
+ self.zone_refresh._zonemgr_refresh_info)
+ # This one does not exist
+ config.set_zone_list_from_name_classes(["example.net", "CH"])
+ self.assertRaises(ZonemgrException,
+ self.zone_refresh.update_config_data, config)
+ # So it should not affect the old ones
+ self.assertTrue(("sd.cn.", "IN") in
+ self.zone_refresh._zonemgr_refresh_info)
+ # Make sure it works even when we "accidentally" forget the final dot
+ config.set_zone_list_from_name_classes([("sd.cn", "IN")])
+ self.zone_refresh.update_config_data(config)
+ self.assertTrue(("sd.cn.", "IN") in
+ self.zone_refresh._zonemgr_refresh_info)
+
def tearDown(self):
sys.stderr= self.stderr_backup
@@ -464,10 +490,11 @@ class MyZonemgr(Zonemgr):
self._cc = MySession()
self._module_cc = MyCCSession()
self._config_data = {
- "lowerbound_refresh" : 10,
- "lowerbound_retry" : 5,
+ "lowerbound_refresh" : 10,
+ "lowerbound_retry" : 5,
"max_transfer_timeout" : 14400,
- "jitter_scope" : 0.1
+ "jitter_scope" : 0.1,
+ "secondary_zones": []
}
def _start_zone_refresh_timer(self):
@@ -480,12 +507,14 @@ class TestZonemgr(unittest.TestCase):
def test_config_handler(self):
config_data1 = {
- "lowerbound_refresh" : 60,
- "lowerbound_retry" : 30,
+ "lowerbound_refresh" : 60,
+ "lowerbound_retry" : 30,
"max_transfer_timeout" : 14400,
- "jitter_scope" : 0.1
+ "jitter_scope" : 0.1,
+ "secondary_zones": []
}
- self.zonemgr.config_handler(config_data1)
+ self.assertEqual(self.zonemgr.config_handler(config_data1),
+ {"result": [0]})
self.assertEqual(config_data1, self.zonemgr._config_data)
config_data2 = {"zone_name" : "sd.cn.", "port" : "53", "master" : "192.168.1.1"}
self.zonemgr.config_handler(config_data2)
@@ -494,10 +523,19 @@ class TestZonemgr(unittest.TestCase):
config_data3 = {"jitter_scope" : 0.7}
self.zonemgr.config_handler(config_data3)
self.assertEqual(0.5, self.zonemgr._config_data.get("jitter_scope"))
+ # The zone doesn't exist in database, it should be rejected
+ self.zonemgr._zone_refresh = ZonemgrRefresh(None, "initdb.file", None,
+ config_data1)
+ config_data1["secondary_zones"] = [{"name": "nonexistent.example",
+ "class": "IN"}]
+ self.assertNotEqual(self.zonemgr.config_handler(config_data1),
+ {"result": [0]})
+ # As it is rejected, the old value should be kept
+ self.assertEqual(0.5, self.zonemgr._config_data.get("jitter_scope"))
def test_get_db_file(self):
self.assertEqual("initdb.file", self.zonemgr.get_db_file())
-
+
def test_parse_cmd_params(self):
params1 = {"zone_name" : "org.cn", "zone_class" : "CH", "master" : "127.0.0.1"}
answer1 = (("org.cn", "CH"), "127.0.0.1")
diff --git a/src/bin/zonemgr/zonemgr.py.in b/src/bin/zonemgr/zonemgr.py.in
index 2cededf..129c673 100755
--- a/src/bin/zonemgr/zonemgr.py.in
+++ b/src/bin/zonemgr/zonemgr.py.in
@@ -100,9 +100,8 @@ class ZonemgrRefresh:
self._cc = cc
self._check_sock = slave_socket
self._db_file = db_file
- self.update_config_data(config_data)
self._zonemgr_refresh_info = {}
- self._build_zonemgr_refresh_info()
+ self.update_config_data(config_data)
self._running = False
def _random_jitter(self, max, jitter):
@@ -148,16 +147,13 @@ class ZonemgrRefresh:
def _zone_not_exist(self, zone_name_class):
""" Zone doesn't belong to zonemgr"""
- if zone_name_class in self._zonemgr_refresh_info.keys():
- return False
- return True
+ return not zone_name_class in self._zonemgr_refresh_info
def zone_refresh_success(self, zone_name_class):
"""Update zone info after zone refresh success"""
if (self._zone_not_exist(zone_name_class)):
raise ZonemgrException("[b10-zonemgr] Zone (%s, %s) doesn't "
"belong to zonemgr" % zone_name_class)
- return
self.zonemgr_reload_zone(zone_name_class)
self._set_zone_refresh_timer(zone_name_class)
self._set_zone_state(zone_name_class, ZONE_OK)
@@ -168,7 +164,6 @@ class ZonemgrRefresh:
if (self._zone_not_exist(zone_name_class)):
raise ZonemgrException("[b10-zonemgr] Zone (%s, %s) doesn't "
"belong to zonemgr" % zone_name_class)
- return
# Is zone expired?
if (self._zone_is_expired(zone_name_class)):
self._set_zone_state(zone_name_class, ZONE_EXPIRED)
@@ -181,7 +176,6 @@ class ZonemgrRefresh:
if (self._zone_not_exist(zone_name_class)):
raise ZonemgrException("[b10-zonemgr] Notified zone (%s, %s) "
"doesn't belong to zonemgr" % zone_name_class)
- return
self._set_zone_notifier_master(zone_name_class, master)
self._set_zone_notify_timer(zone_name_class)
@@ -192,6 +186,7 @@ class ZonemgrRefresh:
def zonemgr_add_zone(self, zone_name_class):
""" Add a zone into zone manager."""
+ log_msg("Loading zone (%s, %s)" % zone_name_class)
zone_info = {}
zone_soa = sqlite3_ds.get_zone_soa(str(zone_name_class[0]), self._db_file)
if not zone_soa:
@@ -203,14 +198,6 @@ class ZonemgrRefresh:
float(zone_soa[7].split(" ")[REFRESH_OFFSET])
self._zonemgr_refresh_info[zone_name_class] = zone_info
- def _build_zonemgr_refresh_info(self):
- """ Build zonemgr refresh info map."""
- log_msg("Start loading zone into zonemgr.")
- for zone_name, zone_class in sqlite3_ds.get_zones_info(self._db_file):
- zone_name_class = (zone_name, zone_class)
- self.zonemgr_add_zone(zone_name_class)
- log_msg("Finish loading zone into zonemgr.")
-
def _zone_is_expired(self, zone_name_class):
"""Judge whether a zone is expired or not."""
zone_expired_time = float(self._get_zone_soa_rdata(zone_name_class).split(" ")[EXPIRED_OFFSET])
@@ -415,6 +402,32 @@ class ZonemgrRefresh:
def update_config_data(self, new_config):
""" update ZonemgrRefresh config """
+ backup = self._zonemgr_refresh_info.copy()
+ try:
+ required = {}
+ # Add new zones
+ for secondary_zone in new_config.get('secondary_zones'):
+ name = secondary_zone['name']
+ # Be tolerant to sclerotic users who forget the final dot
+ if name[-1] != '.':
+ name = name + '.'
+ name_class = (name, secondary_zone['class'])
+ required[name_class] = True
+ # Add it only if it isn't there already
+ if not name_class in self._zonemgr_refresh_info:
+ self.zonemgr_add_zone(name_class)
+ # Drop the zones that are no longer there
+ # Do it in two phases, python doesn't like deleting while iterating
+ to_drop = []
+ for old_zone in self._zonemgr_refresh_info:
+ if not old_zone in required:
+ to_drop.append(old_zone)
+ for drop in to_drop:
+ del self._zonemgr_refresh_info[drop]
+ # If we are not able to find it in database, restore the original
+ except:
+ self._zonemgr_refresh_info = backup
+ raise
self._lowerbound_refresh = new_config.get('lowerbound_refresh')
self._lowerbound_retry = new_config.get('lowerbound_retry')
self._max_transfer_timeout = new_config.get('max_transfer_timeout')
@@ -471,26 +484,37 @@ class Zonemgr:
def config_handler(self, new_config):
""" Update config data. """
answer = create_answer(0)
+ ok = True
+ complete = self._config_data.copy()
for key in new_config:
- if key not in self._config_data:
+ if key not in complete:
answer = create_answer(1, "Unknown config data: " + str(key))
+ ok = False
continue
- self._config_data[key] = new_config[key]
+ complete[key] = new_config[key]
- self._config_data_check(self._config_data)
- if (self._zone_refresh):
- self._zone_refresh.update_config_data(self._config_data)
+ self._config_data_check(complete)
+ if self._zone_refresh is not None:
+ try:
+ self._zone_refresh.update_config_data(complete)
+ except Exception as e:
+ answer = create_answer(1, str(e))
+ ok = False
+ if ok:
+ self._config_data = complete
return answer
def _config_data_check(self, config_data):
- """Check whether the new config data is valid or
- not. """
+ """Check whether the new config data is valid or
+ not. It contains only basic logic, not full check against
+ database."""
# jitter should not be bigger than half of the original value
if config_data.get('jitter_scope') > 0.5:
config_data['jitter_scope'] = 0.5
log_msg("[b10-zonemgr] jitter_scope is too big, its value will "
- "be set to 0.5")
+ "be set to 0.5")
+
def _parse_cmd_params(self, args, command):
zone_name = args.get("zone_name")
diff --git a/src/bin/zonemgr/zonemgr.spec.pre.in b/src/bin/zonemgr/zonemgr.spec.pre.in
index 0539ef3..9df01f2 100644
--- a/src/bin/zonemgr/zonemgr.spec.pre.in
+++ b/src/bin/zonemgr/zonemgr.spec.pre.in
@@ -25,6 +25,32 @@
"item_type": "real",
"item_optional": false,
"item_default": 0.25
+ },
+ {
+ "item_name": "secondary_zones",
+ "item_type": "list",
+ "item_optional": false,
+ "item_default": [],
+ "list_item_spec": {
+ "item_name": "secondary_zone",
+ "item_type": "map",
+ "item_optional": false,
+ "item_default": {},
+ "map_item_spec": [
+ {
+ "item_name": "class",
+ "item_type": "string",
+ "item_optional": false,
+ "item_default": "IN"
+ },
+ {
+ "item_name": "name",
+ "item_type": "string",
+ "item_optional": false,
+ "item_default": ""
+ }
+ ]
+ }
}
],
"commands": [
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index d620c6c..81455c4 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -1,2 +1,2 @@
-SUBDIRS = exceptions util dns cc config python xfr bench log \
- asiolink nsas cache resolve testutils datasrc server_common
+SUBDIRS = exceptions util dns cc config python xfr bench log asiolink \
+ asiodns nsas cache resolve testutils datasrc server_common
diff --git a/src/lib/asiodns/Makefile.am b/src/lib/asiodns/Makefile.am
new file mode 100644
index 0000000..4bcdde6
--- /dev/null
+++ b/src/lib/asiodns/Makefile.am
@@ -0,0 +1,34 @@
+SUBDIRS = . tests
+
+AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
+AM_CPPFLAGS += -I$(top_srcdir)/src/lib/asiolink -I$(top_builddir)/src/lib/asiolink
+AM_CPPFLAGS += -I$(top_srcdir)/src/lib/util -I$(top_builddir)/src/lib/util
+
+AM_CXXFLAGS = $(B10_CXXFLAGS)
+
+CLEANFILES = *.gcno *.gcda
+
+lib_LTLIBRARIES = libasiodns.la
+libasiodns_la_SOURCES = dns_answer.h
+libasiodns_la_SOURCES += asiodns.h
+libasiodns_la_SOURCES += asiodef.cc asiodef.h
+libasiodns_la_SOURCES += dns_lookup.h
+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 += io_fetch.cc io_fetch.h
+
+EXTRA_DIST = asiodef.msg
+
+# Note: the ordering matters: -Wno-... must follow -Wextra (defined in
+# B10_CXXFLAGS)
+libasiodns_la_CXXFLAGS = $(AM_CXXFLAGS)
+if USE_CLANGPP
+# Same for clang++, but we need to turn off -Werror completely.
+libasiodns_la_CXXFLAGS += -Wno-error
+endif
+libasiodns_la_CPPFLAGS = $(AM_CPPFLAGS)
+libasiodns_la_LIBADD = $(top_builddir)/src/lib/log/liblog.la
diff --git a/src/lib/asiodns/README b/src/lib/asiodns/README
new file mode 100644
index 0000000..596d1df
--- /dev/null
+++ b/src/lib/asiodns/README
@@ -0,0 +1,157 @@
+The asiodns library is intended to provide an abstraction layer between
+BIND10 modules and asiolink library.
+
+These DNS server and client routines are written using the "stackless
+coroutine" pattern invented by Chris Kohlhoff and described at
+http://blog.think-async.com/2010/03/potted-guide-to-stackless-coroutines.html.
+This is intended to simplify development a bit, since it allows the
+routines to be written in a straightfowrard step-step-step fashion rather
+than as a complex chain of separate handler functions.
+
+Coroutine objects (i.e., UDPServer, TCPServer and IOFetch) are objects
+with reenterable operator() members. When an instance of one of these
+classes is called as a function, it resumes at the position where it left
+off. Thus, a UDPServer can issue an asynchronous I/O call and specify
+itself as the handler object; when the call completes, the UDPServer
+carries on at the same position. As a result, the code can look as
+if it were using synchronous, not asynchronous, I/O, providing some of
+the benefit of threading but with minimal switching overhead.
+
+So, in simplified form, the behavior of a DNS Server is:
+
+ REENTER:
+ while true:
+ YIELD packet = read_packet
+ FORK
+ if not parent:
+ break
+
+ # This callback informs the caller that a packet has arrived, and
+ # gives it a chance to update configuration, etc
+ SimpleCallback(packet)
+ YIELD answer = DNSLookup(packet, this)
+ response = DNSAnswer(answer)
+ YIELD send(response)
+
+At each "YIELD" point, the coroutine initiates an asynchronous operation,
+then pauses and turns over control to some other task on the ASIO service
+queue. When the operation completes, the coroutine resumes.
+
+DNSLookup, DNSAnswer and SimpleCallback define callback methods
+used by a DNS Server to communicate with the module that called it.
+They are abstract-only classes whose concrete implementations
+are supplied by the calling module.
+
+The DNSLookup callback always runs asynchronously. Concrete
+implementations must be sure to call the server's "resume" method when
+it is finished.
+
+In an authoritative server, the DNSLookup implementation would examine
+the query, look up the answer, then call "resume". (See the diagram
+in doc/auth_process.jpg.)
+
+In a recursive server, the DNSLookup impelemtation would initiate a
+DNSQuery, which in turn would be responsible for calling the server's
+"resume" method. (See the diagram in doc/recursive_process.jpg.)
+
+A DNSQuery object is intended to handle resolution of a query over
+the network when the local authoritative data sources or cache are not
+sufficient. The plan is that it will make use of subsidiary DNSFetch
+calls to get data from particular authoritative servers, and when it has
+gotten a complete answer, it calls "resume".
+
+In current form, however, DNSQuery is much simpler; it forwards queries
+to a single upstream resolver and passes the answers back to the client.
+It is constructed with the address of the forward server. Queries are
+initiated with the question to ask the forward server, a buffer into
+which to write the answer, and a pointer to the coroutine to be resumed
+when the answer has arrived. In simplified form, the DNSQuery routine is:
+
+ REENTER:
+ render the question into a wire-format query packet
+ YIELD send(query)
+ YIELD response = read_packet
+ server->resume
+
+Currently, DNSQuery is only implemented for UDP queries. In future work
+it will be necessary to write code to fall back to TCP when circumstances
+require it.
+
+
+Upstream Fetches
+================
+Upstream fetches (queries by the resolver on behalf of a client) are made
+using a slightly-modified version of the pattern described above.
+
+Sockets
+-------
+First, it will be useful to understand the class hierarchy used in the
+fetch logic:
+
+ IOSocket
+ |
+ IOAsioSocket
+ |
+ +-----+-----+
+ | |
+UDPSocket TCPSocket
+
+IOSocket is a wrapper class for a socket and is used by the authoritative
+server code. It is an abstract base class, providing little more that the ability to hold the socket and to return the protocol in use.
+
+Built on this is IOAsioSocket, which adds the open, close, asyncSend and
+asyncReceive methods. This is a template class, which takes as template
+argument the class of the object that will be used as the callback when the
+asynchronous operation completes. This object can be of any type, but must
+include an operator() method with the signature:
+
+ operator()(asio::error_code ec, size_t length)
+
+... the two arguments being the status of the completed I/O operation and
+the number of bytes transferred. (In the case of the open method, the second
+argument will be zero.)
+
+Finally, the TCPSocket and UDPSocket classes provide the body of the
+asynchronous operations.
+
+Fetch Sequence
+--------------
+The fetch is implemented by the IOFetch class, which takes as argument the
+protocol to use. The sequence is:
+
+ REENTER:
+ render the question into a wire-format query packet
+ open() // Open socket and optionally connect
+ if (! synchronous) {
+ YIELD;
+ }
+ YIELD asyncSend(query) // Send query
+ do {
+ YIELD asyncReceive(response) // Read response
+ } while (! complete(response))
+ close() // Drop connection and close socket
+ server->resume
+
+The open() method opens a socket for use. On TCP, it also makes a
+connection to the remote end. So under UDP the operation will complete
+immediately, but under TCP it could take a long time. One solution would be
+for the open operation to post an event to the I/O queue; then both cases
+could be regarded as being equivalent, with the completion being signalled
+by the posting of the completion event. However UDP is the most common case
+and that would involve extra overhead. So the open() returns a status
+indicating whether the operation completed asynchronously. If it did, the
+code yields back to the coroutine; if not the yield is bypassed.
+
+The asynchronous send is straightforward, invoking the underlying ASIO
+function. (Note that the address/port is supplied to both the open() and
+asyncSend() methods - it is used by the TCPSocket in open() and by the
+UDPSocket in asyncSend().)
+
+The asyncReceive() method issues an asynchronous read and waits for completion.
+The fetch object keeps track of the amount of data received so far and when
+the receive completes it calls a method on the socket to determine if the
+entire message has been received. (This will always be the case for UDP. On
+TCP though, the message is preceded by a count field as several reads may be
+required to read all the data.) The fetch loops until all the data is read.
+
+Finally, the socket is closed and the server called to resume operation.
diff --git a/src/lib/asiodns/asiodef.cc b/src/lib/asiodns/asiodef.cc
new file mode 100644
index 0000000..127e848
--- /dev/null
+++ b/src/lib/asiodns/asiodef.cc
@@ -0,0 +1,39 @@
+// File created from asiodef.msg on Mon Feb 28 17:15:30 2011
+
+#include <cstddef>
+#include <log/message_types.h>
+#include <log/message_initializer.h>
+
+namespace isc {
+namespace asiodns {
+
+extern const isc::log::MessageID ASIODNS_FETCHCOMP = "FETCHCOMP";
+extern const isc::log::MessageID ASIODNS_FETCHSTOP = "FETCHSTOP";
+extern const isc::log::MessageID ASIODNS_OPENSOCK = "OPENSOCK";
+extern const isc::log::MessageID ASIODNS_RECVSOCK = "RECVSOCK";
+extern const isc::log::MessageID ASIODNS_RECVTMO = "RECVTMO";
+extern const isc::log::MessageID ASIODNS_SENDSOCK = "SENDSOCK";
+extern const isc::log::MessageID ASIODNS_UNKORIGIN = "UNKORIGIN";
+extern const isc::log::MessageID ASIODNS_UNKRESULT = "UNKRESULT";
+
+} // namespace asiodns
+} // namespace isc
+
+namespace {
+
+const char* values[] = {
+ "FETCHCOMP", "upstream fetch to %s(%d) has now completed",
+ "FETCHSTOP", "upstream fetch to %s(%d) has been stopped",
+ "OPENSOCK", "error %d opening %s socket to %s(%d)",
+ "RECVSOCK", "error %d reading %s data from %s(%d)",
+ "RECVTMO", "receive timeout while waiting for data from %s(%d)",
+ "SENDSOCK", "error %d sending data using %s to %s(%d)",
+ "UNKORIGIN", "unknown origin for ASIO error code %d (protocol: %s, address %s)",
+ "UNKRESULT", "unknown result (%d) when IOFetch::stop() was executed for I/O to %s(%d)",
+ NULL
+};
+
+const isc::log::MessageInitializer initializer(values);
+
+} // Anonymous namespace
+
diff --git a/src/lib/asiodns/asiodef.h b/src/lib/asiodns/asiodef.h
new file mode 100644
index 0000000..50aa8a9
--- /dev/null
+++ b/src/lib/asiodns/asiodef.h
@@ -0,0 +1,23 @@
+// File created from asiodef.msg on Mon Feb 28 17:15:30 2011
+
+#ifndef __ASIODEF_H
+#define __ASIODEF_H
+
+#include <log/message_types.h>
+
+namespace isc {
+namespace asiodns {
+
+extern const isc::log::MessageID ASIODNS_FETCHCOMP;
+extern const isc::log::MessageID ASIODNS_FETCHSTOP;
+extern const isc::log::MessageID ASIODNS_OPENSOCK;
+extern const isc::log::MessageID ASIODNS_RECVSOCK;
+extern const isc::log::MessageID ASIODNS_RECVTMO;
+extern const isc::log::MessageID ASIODNS_SENDSOCK;
+extern const isc::log::MessageID ASIODNS_UNKORIGIN;
+extern const isc::log::MessageID ASIODNS_UNKRESULT;
+
+} // namespace asiodns
+} // namespace isc
+
+#endif // __ASIODEF_H
diff --git a/src/lib/asiodns/asiodef.msg b/src/lib/asiodns/asiodef.msg
new file mode 100644
index 0000000..7f86acb
--- /dev/null
+++ b/src/lib/asiodns/asiodef.msg
@@ -0,0 +1,56 @@
+# Copyright (C) 2011 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.
+
+$PREFIX ASIODNS_
+$NAMESPACE isc::asiodns
+
+FETCHCOMP upstream fetch to %s(%d) has now completed
++ A debug message, this records the the upstream fetch (a query made by the
++ resolver on behalf of its client) to the specified address has completed.
+
+FETCHSTOP upstream fetch to %s(%d) has been stopped
++ An external component has requested the halting of an upstream fetch. This
++ is an allowed operation, and the message should only appear if debug is
++ enabled.
+
+OPENSOCK error %d opening %s socket to %s(%d)
++ The asynchronous I/O code encountered an error when trying to open a socket
++ of the specified protocol in order to send a message to the target address.
++ The the number of the system error that cause the problem is given in the
++ message.
+
+RECVSOCK error %d reading %s data from %s(%d)
++ The asynchronous I/O code encountered an error when trying read data from
++ the specified address on the given protocol. The the number of the system
++ error that cause the problem is given in the message.
+
+SENDSOCK error %d sending data using %s to %s(%d)
++ The asynchronous I/O code encountered an error when trying send data to
++ the specified address on the given protocol. The the number of the system
++ error that cause the problem is given in the message.
+
+RECVTMO receive timeout while waiting for data from %s(%d)
++ An upstream fetch from the specified address timed out. This may happen for
++ any number of reasons and is most probably a problem at the remote server
++ or a problem on the network. The message will only appear if debug is
++ enabled.
+
+UNKORIGIN unknown origin for ASIO error code %d (protocol: %s, address %s)
++ This message should not appear and indicates an internal error if it does.
++ Please enter a bug report.
+
+UNKRESULT unknown result (%d) when IOFetch::stop() was executed for I/O to %s(%d)
++ The termination method of the resolver's upstream fetch class was called with
++ an unknown result code (which is given in the message). This message should
++ not appear and may indicate an internal error. Please enter a bug report.
diff --git a/src/lib/asiodns/asiodns.h b/src/lib/asiodns/asiodns.h
new file mode 100644
index 0000000..8791a72
--- /dev/null
+++ b/src/lib/asiodns/asiodns.h
@@ -0,0 +1,23 @@
+// Copyright (C) 2011 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 __ASIODNS_H
+#define __ASIODNS_H 1
+
+#include <asiodns/dns_service.h>
+#include <asiodns/dns_server.h>
+#include <asiodns/dns_lookup.h>
+#include <asiodns/dns_answer.h>
+
+#endif // __ASIODNS_H
diff --git a/src/lib/asiodns/dns_answer.h b/src/lib/asiodns/dns_answer.h
new file mode 100644
index 0000000..3654369
--- /dev/null
+++ b/src/lib/asiodns/dns_answer.h
@@ -0,0 +1,77 @@
+// Copyright (C) 2011 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 __ASIOLINK_DNS_ANSWER_H
+#define __ASIOLINK_DNS_ANSWER_H 1
+
+#include <asiolink/io_message.h>
+#include <util/buffer.h>
+#include <dns/message.h>
+
+namespace isc {
+namespace asiodns {
+
+/// \brief The \c DNSAnswer class is an abstract base class for a DNS
+/// Answer provider function.
+///
+/// Specific derived class implementations are hidden within the
+/// implementation. Instances of the derived classes can be called
+/// as functions via the operator() interface. Pointers to these
+/// instances can then be provided to the \c IOService class
+/// via its constructor.
+///
+/// A DNS Answer provider function takes answer data that has been obtained
+/// from a DNS Lookup provider functon and readies it to be sent to the
+/// client. After it has run, the OutputBuffer object passed to it should
+/// contain the answer to the query rendered into wire format.
+class DNSAnswer {
+ ///
+ /// \name Constructors and Destructor
+ ///
+ /// Note: The copy constructor and the assignment operator are
+ /// intentionally defined as private, making this class non-copyable.
+ //@{
+private:
+ DNSAnswer(const DNSAnswer& source);
+ DNSAnswer& operator=(const DNSAnswer& source);
+protected:
+ /// \brief The default constructor.
+ ///
+ /// This is intentionally defined as \c protected as this base class
+ /// should never be instantiated (except as part of a derived class).
+ DNSAnswer() {}
+public:
+ /// \brief The destructor
+ virtual ~DNSAnswer() {}
+ //@}
+ /// \brief The function operator
+ ///
+ /// This makes its call indirectly via the "self" pointer, ensuring
+ /// that the function ultimately invoked will be the one in the derived
+ /// class.
+ ///
+ /// \param io_message The event message to handle
+ /// \param query_message The DNS MessagePtr of the original query
+ /// \param answer_message The DNS MessagePtr of the answer we are
+ /// building
+ /// \param buffer Intermediate data results are put here
+ virtual void operator()(const asiolink::IOMessage& io_message,
+ isc::dns::MessagePtr query_message,
+ isc::dns::MessagePtr answer_message,
+ isc::util::OutputBufferPtr buffer) const = 0;
+};
+
+} // namespace asiodns
+} // namespace isc
+#endif // __ASIOLINK_DNS_ANSWER_H
diff --git a/src/lib/asiodns/dns_lookup.h b/src/lib/asiodns/dns_lookup.h
new file mode 100644
index 0000000..40290e4
--- /dev/null
+++ b/src/lib/asiodns/dns_lookup.h
@@ -0,0 +1,85 @@
+// Copyright (C) 2011 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 __ASIOLINK_DNS_LOOKUP_H
+#define __ASIOLINK_DNS_LOOKUP_H 1
+
+#include <asiolink/io_message.h>
+#include <asiodns/dns_server.h>
+#include <dns/message.h>
+#include <util/buffer.h>
+
+namespace isc {
+namespace asiodns {
+
+/// \brief The \c DNSLookup class is an abstract base class for a DNS
+/// Lookup provider function.
+///
+/// Specific derived class implementations are hidden within the
+/// implementation. Instances of the derived classes can be called
+/// as functions via the operator() interface. Pointers to these
+/// instances can then be provided to the \c IOService class
+/// via its constructor.
+///
+/// A DNS Lookup provider function obtains the data needed to answer
+/// a DNS query (e.g., from authoritative data source, cache, or upstream
+/// query). After it has run, the OutputBuffer object passed to it
+/// should contain the answer to the query, in an internal representation.
+class DNSLookup {
+ ///
+ /// \name Constructors and Destructor
+ ///
+ /// Note: The copy constructor and the assignment operator are
+ /// intentionally defined as private, making this class non-copyable.
+ //@{
+private:
+ DNSLookup(const DNSLookup& source);
+ DNSLookup& operator=(const DNSLookup& source);
+protected:
+ /// \brief The default constructor.
+ ///
+ /// This is intentionally defined as \c protected as this base class
+ /// should never be instantiated (except as part of a derived class).
+ DNSLookup() : self_(this) {}
+public:
+ /// \brief The destructor
+ virtual ~DNSLookup() {}
+ //@}
+ /// \brief The function operator
+ ///
+ /// This makes its call indirectly via the "self" pointer, ensuring
+ /// that the function ultimately invoked will be the one in the derived
+ /// class.
+ ///
+ /// \param io_message The event message to handle
+ /// \param message The DNS MessagePtr that needs handling
+ /// \param answer_message The final answer will be constructed in
+ /// this MessagePtr
+ /// \param buffer The final answer is put here
+ /// \param server DNSServer object to use
+ virtual void operator()(const asiolink::IOMessage& io_message,
+ isc::dns::MessagePtr message,
+ isc::dns::MessagePtr answer_message,
+ isc::util::OutputBufferPtr buffer,
+ DNSServer* server) const
+ {
+ (*self_)(io_message, message, answer_message, buffer, server);
+ }
+private:
+ DNSLookup* self_;
+};
+
+} // namespace asiodns
+} // namespace isc
+#endif // __ASIOLINK_DNS_LOOKUP_H
diff --git a/src/lib/asiodns/dns_server.h b/src/lib/asiodns/dns_server.h
new file mode 100644
index 0000000..f235860
--- /dev/null
+++ b/src/lib/asiodns/dns_server.h
@@ -0,0 +1,157 @@
+// Copyright (C) 2011 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 __ASIOLINK_DNS_SERVER_H
+#define __ASIOLINK_DNS_SERVER_H 1
+
+#include <asiolink/io_message.h>
+
+namespace isc {
+namespace asiodns {
+
+/// \brief The \c DNSServer class is a wrapper (and base class) for
+/// classes which provide DNS server functionality.
+///
+/// The classes derived from this one, \c TCPServer and \c UDPServer,
+/// act as the interface layer between clients sending queries, and
+/// functions defined elsewhere that provide answers to those queries.
+/// Those functions are described in more detail below under
+/// \c SimpleCallback, \c DNSLookup, and \c DNSAnswer.
+///
+/// Notes to developers:
+/// When constructed, this class (and its derived classes) will have its
+/// "self_" member set to point to "this". Objects of this class (as
+/// instantiated through a base class) are sometimes passed by
+/// reference (as this superclass); calls to methods in the base
+/// class are then rerouted via this pointer to methods in the derived
+/// class. This allows code from outside asiodns, with no specific
+/// knowledge of \c TCPServer or \c UDPServer, to access their methods.
+///
+/// This class is both assignable and copy-constructable. Its subclasses
+/// use the "stackless coroutine" pattern, meaning that it will copy itself
+/// when "forking", and that instances will be posted as ASIO handler
+/// objects, which are always copied.
+///
+/// Because these objects are frequently copied, it is recommended
+/// that derived classes be kept small to reduce copy overhead.
+class DNSServer {
+protected:
+ ///
+ /// \name Constructors and destructors
+ ///
+ /// This is intentionally defined as \c protected, as this base class
+ /// should never be instantiated except as part of a derived class.
+ //@{
+ DNSServer() : self_(this) {}
+public:
+ /// \brief The destructor
+ virtual ~DNSServer() {}
+ //@}
+
+ ///
+ /// \name Class methods
+ ///
+ /// These methods all make their calls indirectly via the "self_"
+ /// pointer, ensuring that the functions ultimately invoked will be
+ /// the ones in the derived class. This makes it possible to pass
+ /// instances of derived classes as references to this base class
+ /// without losing access to derived class data.
+ ///
+ //@{
+ /// \brief The funtion operator
+ virtual void operator()(asio::error_code ec = asio::error_code(),
+ size_t length = 0)
+ {
+ (*self_)(ec, length);
+ }
+
+ /// \brief Stop current running server
+ virtual void stop() { self_->stop();}
+
+ /// \brief Resume processing of the server coroutine after an
+ /// asynchronous call (e.g., to the DNS Lookup provider) has completed.
+ ///
+ /// \param done If true, this signals the system there is an answer
+ /// 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
+ /// normally be another \c DNSServer object containing a copy
+ /// of the original "self_" pointer. Calling clone() guarantees
+ /// that the underlying object is also correctly copied.
+ ///
+ /// \return A deep copy of this DNSServer object
+ virtual DNSServer* clone() { return (self_->clone()); }
+ //@}
+
+protected:
+ /// \brief Lookup handler object.
+ ///
+ /// This is a protected class; it can only be instantiated
+ /// from within a derived class of \c DNSServer.
+ ///
+ /// A server object that has received a query creates an instance
+ /// of this class and scheudles it on the ASIO service queue
+ /// using asio::io_service::post(). When the handler executes, it
+ /// calls the asyncLookup() method in the server object to start a
+ /// DNS lookup. When the lookup is complete, the server object is
+ /// scheduled to resume, again using io_service::post().
+ ///
+ /// Note that the calling object is copied into the handler object,
+ /// not referenced. This is because, once the calling object yields
+ /// control to the handler, it falls out of scope and may disappear
+ template <typename T>
+ class AsyncLookup {
+ public:
+ AsyncLookup(T& caller) : caller_(caller) {}
+ void operator()() { caller_.asyncLookup(); }
+ private:
+ T caller_;
+ };
+
+ /// \brief Carries out a DNS lookup.
+ ///
+ /// This function calls the \c DNSLookup object specified by the
+ /// DNS server when the \c IOService was created, passing along
+ /// the details of the query and a pointer back to the current
+ /// server object. It is called asynchronously via the AsyncLookup
+ /// handler class.
+ virtual void asyncLookup() { self_->asyncLookup(); }
+
+private:
+ DNSServer* self_;
+};
+
+
+} // namespace asiodns
+} // namespace isc
+#endif // __ASIOLINK_DNS_SERVER_H
diff --git a/src/lib/asiodns/dns_service.cc b/src/lib/asiodns/dns_service.cc
new file mode 100644
index 0000000..94510fe
--- /dev/null
+++ b/src/lib/asiodns/dns_service.cc
@@ -0,0 +1,201 @@
+// Copyright (C) 2011 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 <netinet/in.h>
+#include <sys/socket.h>
+#include <unistd.h> // for some IPC/network system calls
+
+#include <boost/lexical_cast.hpp>
+
+#include <config.h>
+
+#include <log/dummylog.h>
+
+#include <asio.hpp>
+#include <dns_service.h>
+#include <asiolink/io_service.h>
+#include <asiolink/io_service.h>
+#include <tcp_server.h>
+#include <udp_server.h>
+
+#include <log/dummylog.h>
+
+#include <boost/lexical_cast.hpp>
+#include <boost/foreach.hpp>
+
+using isc::log::dlog;
+
+using namespace isc::asiolink;
+
+namespace isc {
+namespace asiodns {
+
+class DNSLookup;
+class DNSAnswer;
+
+namespace {
+
+asio::ip::address
+convertAddr(const std::string& address) {
+ asio::error_code err;
+ asio::ip::address addr = asio::ip::address::from_string(address, err);
+ if (err) {
+ isc_throw(IOError, "Invalid IP address '" << &address << "': "
+ << err.message());
+ }
+ return (addr);
+}
+
+}
+
+
+class DNSServiceImpl {
+public:
+ DNSServiceImpl(IOService& io_service, const char& port,
+ const asio::ip::address* v4addr,
+ const asio::ip::address* v6addr,
+ SimpleCallback* checkin, DNSLookup* lookup,
+ DNSAnswer* answer);
+
+ IOService& io_service_;
+
+ typedef boost::shared_ptr<UDPServer> UDPServerPtr;
+ typedef boost::shared_ptr<TCPServer> TCPServerPtr;
+ typedef boost::shared_ptr<DNSServer> DNSServerPtr;
+ std::vector<DNSServerPtr> servers_;
+ SimpleCallback *checkin_;
+ DNSLookup *lookup_;
+ DNSAnswer *answer_;
+
+ void addServer(uint16_t port, const asio::ip::address& address) {
+ try {
+ dlog(std::string("Initialize TCP server at ") + address.to_string() + ":" + boost::lexical_cast<std::string>(port));
+ TCPServerPtr tcpServer(new TCPServer(io_service_.get_io_service(),
+ address, port, checkin_, lookup_, answer_));
+ (*tcpServer)();
+ servers_.push_back(tcpServer);
+ dlog(std::string("Initialize UDP server at ") + address.to_string() + ":" + boost::lexical_cast<std::string>(port));
+ UDPServerPtr udpServer(new UDPServer(io_service_.get_io_service(),
+ address, port, checkin_, lookup_, answer_));
+ (*udpServer)();
+ servers_.push_back(udpServer);
+ }
+ catch (const asio::system_error& err) {
+ // We need to catch and convert any ASIO level exceptions.
+ // This can happen for unavailable address, binding a privilege port
+ // without the privilege, etc.
+ isc_throw(IOError, "Failed to initialize network servers: " <<
+ err.what());
+ }
+ }
+ void addServer(const char& port, const asio::ip::address& address) {
+ uint16_t portnum;
+ try {
+ // XXX: SunStudio with stlport4 doesn't reject some invalid
+ // representation such as "-1" by lexical_cast<uint16_t>, so
+ // we convert it into a signed integer of a larger size and perform
+ // range check ourselves.
+ const int32_t portnum32 = boost::lexical_cast<int32_t>(&port);
+ if (portnum32 < 0 || portnum32 > 65535) {
+ isc_throw(IOError, "Invalid port number '" << &port);
+ }
+ portnum = portnum32;
+ } catch (const boost::bad_lexical_cast& ex) {
+ isc_throw(IOError, "Invalid port number '" << &port << "': " <<
+ ex.what());
+ }
+ addServer(portnum, address);
+ }
+};
+
+DNSServiceImpl::DNSServiceImpl(IOService& io_service,
+ const char& port,
+ const asio::ip::address* const v4addr,
+ const asio::ip::address* const v6addr,
+ SimpleCallback* checkin,
+ DNSLookup* lookup,
+ DNSAnswer* answer) :
+ io_service_(io_service),
+ checkin_(checkin),
+ lookup_(lookup),
+ answer_(answer)
+{
+
+ if (v4addr) {
+ addServer(port, *v4addr);
+ }
+ if (v6addr) {
+ addServer(port, *v6addr);
+ }
+}
+
+DNSService::DNSService(IOService& io_service,
+ const char& port, const char& address,
+ SimpleCallback* checkin,
+ DNSLookup* lookup,
+ DNSAnswer* answer) :
+ impl_(new DNSServiceImpl(io_service, port, NULL, NULL, checkin, lookup,
+ answer)), io_service_(io_service)
+{
+ addServer(port, &address);
+}
+
+DNSService::DNSService(IOService& io_service,
+ const char& port,
+ const bool use_ipv4, const bool use_ipv6,
+ SimpleCallback* checkin,
+ DNSLookup* lookup,
+ DNSAnswer* answer) :
+ impl_(NULL), io_service_(io_service)
+{
+ const asio::ip::address v4addr_any =
+ asio::ip::address(asio::ip::address_v4::any());
+ const asio::ip::address* const v4addrp = use_ipv4 ? &v4addr_any : NULL;
+ const asio::ip::address v6addr_any =
+ asio::ip::address(asio::ip::address_v6::any());
+ const asio::ip::address* const v6addrp = use_ipv6 ? &v6addr_any : NULL;
+ impl_ = new DNSServiceImpl(io_service, port, v4addrp, v6addrp, checkin, lookup, answer);
+}
+
+DNSService::DNSService(IOService& io_service, SimpleCallback* checkin,
+ DNSLookup* lookup, DNSAnswer *answer) :
+ impl_(new DNSServiceImpl(io_service, *"0", NULL, NULL, checkin, lookup,
+ answer)), io_service_(io_service)
+{
+}
+
+DNSService::~DNSService() {
+ delete impl_;
+}
+
+void
+DNSService::addServer(const char& port, const std::string& address) {
+ impl_->addServer(port, convertAddr(address));
+}
+
+void
+DNSService::addServer(uint16_t port, const std::string& address) {
+ impl_->addServer(port, convertAddr(address));
+}
+
+void
+DNSService::clearServers() {
+ BOOST_FOREACH(const DNSServiceImpl::DNSServerPtr& s, impl_->servers_) {
+ s->stop();
+ }
+ impl_->servers_.clear();
+}
+
+} // namespace asiodns
+} // namespace isc
diff --git a/src/lib/asiodns/dns_service.h b/src/lib/asiodns/dns_service.h
new file mode 100644
index 0000000..6b6a6c0
--- /dev/null
+++ b/src/lib/asiodns/dns_service.h
@@ -0,0 +1,114 @@
+// Copyright (C) 2011 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 __ASIOLINK_DNS_SERVICE_H
+#define __ASIOLINK_DNS_SERVICE_H 1
+
+#include <resolve/resolver_interface.h>
+
+#include <asiolink/io_service.h>
+#include <asiolink/simple_callback.h>
+
+namespace isc {
+namespace asiodns {
+
+class DNSLookup;
+class DNSAnswer;
+class DNSServiceImpl;
+
+/// \brief Handle DNS Queries
+///
+/// DNSService is the service that handles DNS queries and answers with
+/// a given IOService. This class is mainly intended to hold all the
+/// logic that is shared between the authoritative and the recursive
+/// server implementations. As such, it handles asio, including config
+/// updates (through the 'Checkinprovider'), and listening sockets.
+class DNSService {
+ ///
+ /// \name Constructors and Destructor
+ ///
+ /// Note: The copy constructor and the assignment operator are
+ /// intentionally defined as private, making this class non-copyable.
+ //@{
+private:
+ DNSService(const DNSService& source);
+ DNSService& operator=(const DNSService& source);
+
+public:
+ /// \brief The constructor with a specific IP address and port on which
+ /// the services listen on.
+ ///
+ /// \param io_service The IOService to work with
+ /// \param port the port to listen on
+ /// \param address the IP address to listen on
+ /// \param checkin Provider for cc-channel events (see \c SimpleCallback)
+ /// \param lookup The lookup provider (see \c DNSLookup)
+ /// \param answer The answer provider (see \c DNSAnswer)
+ DNSService(asiolink::IOService& io_service, const char& port,
+ const char& address, isc::asiolink::SimpleCallback* checkin,
+ DNSLookup* lookup, DNSAnswer* answer);
+ /// \brief The constructor with a specific port on which the services
+ /// listen on.
+ ///
+ /// It effectively listens on "any" IPv4 and/or IPv6 addresses.
+ /// IPv4/IPv6 services will be available if and only if \c use_ipv4
+ /// or \c use_ipv6 is \c true, respectively.
+ ///
+ /// \param io_service The IOService to work with
+ /// \param port the port to listen on
+ /// \param use_ipv4 If true, listen on ipv4 'any'
+ /// \param use_ipv6 If true, listen on ipv6 'any'
+ /// \param checkin Provider for cc-channel events (see \c SimpleCallback)
+ /// \param lookup The lookup provider (see \c DNSLookup)
+ /// \param answer The answer provider (see \c DNSAnswer)
+ DNSService(asiolink::IOService& io_service, const char& port,
+ const bool use_ipv4, const bool use_ipv6,
+ isc::asiolink::SimpleCallback* checkin, DNSLookup* lookup,
+ DNSAnswer* answer);
+ /// \brief The constructor without any servers.
+ ///
+ /// Use addServer() to add some servers.
+ DNSService(asiolink::IOService& io_service, isc::asiolink::SimpleCallback* checkin,
+ DNSLookup* lookup, DNSAnswer* answer);
+ /// \brief The destructor.
+ ~DNSService();
+ //@}
+
+ /// \brief Add another server to the service
+ void addServer(uint16_t port, const std::string &address);
+ void addServer(const char &port, const std::string &address);
+ /// \brief Remove all servers from the service
+ void clearServers();
+
+ /// \brief Return the native \c io_service object used in this wrapper.
+ ///
+ /// This is a short term work around to support other BIND 10 modules
+ /// that share the same \c io_service with the authoritative server.
+ /// It will eventually be removed once the wrapper interface is
+ /// generalized.
+ asio::io_service& get_io_service() { return io_service_.get_io_service(); }
+
+ /// \brief Return the IO Service Object
+ ///
+ /// \return IOService object for this DNS service.
+ asiolink::IOService& getIOService() { return (io_service_);}
+
+private:
+ DNSServiceImpl* impl_;
+ asiolink::IOService& io_service_;
+};
+
+} // namespace asiodns
+} // namespace isc
+#endif // __ASIOLINK_DNS_SERVICE_H
diff --git a/src/lib/asiodns/io_fetch.cc b/src/lib/asiodns/io_fetch.cc
new file mode 100644
index 0000000..8f57d8e
--- /dev/null
+++ b/src/lib/asiodns/io_fetch.cc
@@ -0,0 +1,407 @@
+// Copyright (C) 2011 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 <netinet/in.h>
+#include <stdint.h>
+#include <sys/socket.h>
+#include <unistd.h> // for some IPC/network system calls
+
+#include <boost/bind.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+
+#include <asio.hpp>
+#include <asio/deadline_timer.hpp>
+
+#include <asiolink/io_address.h>
+#include <asiolink/io_asio_socket.h>
+#include <asiolink/io_endpoint.h>
+#include <asiolink/io_service.h>
+#include <asiolink/tcp_endpoint.h>
+#include <asiolink/tcp_socket.h>
+#include <asiolink/udp_endpoint.h>
+#include <asiolink/udp_socket.h>
+
+#include <dns/message.h>
+#include <dns/messagerenderer.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
+#include <log/logger.h>
+
+#include <asiodns/asiodef.h>
+#include <asiodns/io_fetch.h>
+
+#include <util/buffer.h>
+#include <util/random/qid_gen.h>
+
+
+using namespace asio;
+using namespace isc::asiolink;
+using namespace isc::dns;
+using namespace isc::util;
+using namespace isc::util::random;
+using namespace isc::log;
+using namespace std;
+
+namespace isc {
+namespace asiodns {
+
+/// Use the ASIO logger
+
+isc::log::Logger logger("asiolink");
+
+/// \brief IOFetch Data
+///
+/// The data for IOFetch is held in a separate struct pointed to by a shared_ptr
+/// object. This is because the IOFetch object will be copied often (it is used
+/// as a coroutine and passed as callback to many async_*() functions) and we
+/// want keep the same data). Organising the data in this way keeps copying to
+/// a minimum.
+struct IOFetchData {
+
+ // The first two members are shared pointers to a base class because what is
+ // actually instantiated depends on whether the fetch is over UDP or TCP,
+ // which is not known until construction of the IOFetch. Use of a shared
+ // pointer here is merely to ensure deletion when the data object is deleted.
+ boost::scoped_ptr<IOAsioSocket<IOFetch> > socket;
+ ///< Socket to use for I/O
+ boost::scoped_ptr<IOEndpoint> remote_snd;///< Where the fetch is sent
+ boost::scoped_ptr<IOEndpoint> remote_rcv;///< Where the response came from
+ isc::dns::Question question; ///< Question to be asked
+ OutputBufferPtr msgbuf; ///< Wire buffer for question
+ OutputBufferPtr received; ///< Received data put here
+ IOFetch::Callback* callback; ///< Called on I/O Completion
+ asio::deadline_timer timer; ///< Timer to measure timeouts
+ IOFetch::Protocol protocol; ///< Protocol being used
+ size_t cumulative; ///< Cumulative received amount
+ size_t expected; ///< Expected amount of data
+ size_t offset; ///< Offset to receive data
+ bool stopped; ///< Have we stopped running?
+ int timeout; ///< Timeout in ms
+ bool packet; ///< true if packet was supplied
+
+ // In case we need to log an error, the origin of the last asynchronous
+ // I/O is recorded. To save time and simplify the code, this is recorded
+ // as the ID of the error message that would be generated if the I/O failed.
+ // This means that we must make sure that all possible "origins" take the
+ // same arguments in their message in the same order.
+ isc::log::MessageID origin; ///< Origin of last asynchronous I/O
+ uint8_t staging[IOFetch::STAGING_LENGTH];
+ ///< Temporary array for received data
+ isc::dns::qid_t qid; ///< The QID set in the query
+
+ /// \brief Constructor
+ ///
+ /// Just fills in the data members of the IOFetchData structure
+ ///
+ /// \param proto Either IOFetch::TCP or IOFetch::UDP.
+ /// \param service I/O Service object to handle the asynchronous
+ /// operations.
+ /// \param query DNS question to send to the upstream server.
+ /// \param address IP address of upstream server
+ /// \param port Port to use for the query
+ /// \param buff Output buffer into which the response (in wire format)
+ /// is written (if a response is received).
+ /// \param cb Callback object containing the callback to be called
+ /// when we terminate. The caller is responsible for managing this
+ /// object and deleting it if necessary.
+ /// \param wait Timeout for the fetch (in ms).
+ ///
+ /// TODO: May need to alter constructor (see comment 4 in Trac ticket #554)
+ IOFetchData(IOFetch::Protocol proto, IOService& service,
+ const isc::dns::Question& query, const IOAddress& address,
+ uint16_t port, OutputBufferPtr& buff, IOFetch::Callback* cb, int wait)
+ :
+ socket((proto == IOFetch::UDP) ?
+ static_cast<IOAsioSocket<IOFetch>*>(
+ new UDPSocket<IOFetch>(service)) :
+ static_cast<IOAsioSocket<IOFetch>*>(
+ new TCPSocket<IOFetch>(service))
+ ),
+ remote_snd((proto == IOFetch::UDP) ?
+ static_cast<IOEndpoint*>(new UDPEndpoint(address, port)) :
+ static_cast<IOEndpoint*>(new TCPEndpoint(address, port))
+ ),
+ remote_rcv((proto == IOFetch::UDP) ?
+ static_cast<IOEndpoint*>(new UDPEndpoint(address, port)) :
+ static_cast<IOEndpoint*>(new TCPEndpoint(address, port))
+ ),
+ question(query),
+ msgbuf(new OutputBuffer(512)),
+ received(buff),
+ callback(cb),
+ timer(service.get_io_service()),
+ protocol(proto),
+ cumulative(0),
+ expected(0),
+ offset(0),
+ stopped(false),
+ timeout(wait),
+ packet(false),
+ origin(ASIODNS_UNKORIGIN),
+ staging(),
+ qid(QidGenerator::getInstance().generateQid())
+ {}
+
+ // Checks if the response we received was ok;
+ // - data contains the buffer we read, as well as the address
+ // we sent to and the address we received from.
+ // length is provided by the operator() in IOFetch.
+ // Addresses must match, number of octets read must be at least
+ // 2, and the first two octets must match the qid of the message
+ // we sent.
+ bool responseOK() {
+ return (*remote_snd == *remote_rcv && cumulative >= 2 &&
+ readUint16(received->getData()) == qid);
+ }
+};
+
+/// IOFetch Constructor - just initialize the private data
+
+IOFetch::IOFetch(Protocol protocol, IOService& service,
+ const isc::dns::Question& question, const IOAddress& address, uint16_t port,
+ OutputBufferPtr& buff, Callback* cb, int wait)
+ :
+ data_(new IOFetchData(protocol, service, question, address,
+ port, buff, cb, wait))
+{
+}
+
+IOFetch::IOFetch(Protocol protocol, IOService& service,
+ OutputBufferPtr& outpkt, const IOAddress& address, uint16_t port,
+ OutputBufferPtr& buff, Callback* cb, int wait)
+ :
+ data_(new IOFetchData(protocol, service,
+ isc::dns::Question(isc::dns::Name("dummy.example.org"),
+ isc::dns::RRClass::IN(), isc::dns::RRType::A()),
+ address, port, buff, cb, wait))
+{
+ data_->msgbuf = outpkt;
+ data_->packet = true;
+}
+
+// Return protocol in use.
+
+IOFetch::Protocol
+IOFetch::getProtocol() const {
+ return (data_->protocol);
+}
+
+/// The function operator is implemented with the "stackless coroutine"
+/// pattern; see internal/coroutine.h for details.
+
+void
+IOFetch::operator()(asio::error_code ec, size_t length) {
+
+ if (data_->stopped) {
+ return;
+ } else if (ec) {
+ logIOFailure(ec);
+ return;
+ }
+
+ CORO_REENTER (this) {
+
+ /// Generate the upstream query and render it to wire format
+ /// This is done in a different scope to allow inline variable
+ /// declarations.
+ {
+ if (data_->packet) {
+ // A packet was given, overwrite the QID (which is in the
+ // first two bytes of the packet).
+ data_->msgbuf->writeUint16At(data_->qid, 0);
+
+ } else {
+ // A question was given, construct the packet
+ Message msg(Message::RENDER);
+ msg.setQid(data_->qid);
+ msg.setOpcode(Opcode::QUERY());
+ msg.setRcode(Rcode::NOERROR());
+ msg.setHeaderFlag(Message::HEADERFLAG_RD);
+ msg.addQuestion(data_->question);
+ MessageRenderer renderer(*data_->msgbuf);
+ msg.toWire(renderer);
+ }
+ }
+
+ // If we timeout, we stop, which will can cancel outstanding I/Os and
+ // shutdown everything.
+ if (data_->timeout != -1) {
+ data_->timer.expires_from_now(boost::posix_time::milliseconds(
+ data_->timeout));
+ data_->timer.async_wait(boost::bind(&IOFetch::stop, *this,
+ TIME_OUT));
+ }
+
+ // Open a connection to the target system. For speed, if the operation
+ // is synchronous (i.e. UDP operation) we bypass the yield.
+ data_->origin = ASIODNS_OPENSOCK;
+ if (data_->socket->isOpenSynchronous()) {
+ data_->socket->open(data_->remote_snd.get(), *this);
+ } else {
+ CORO_YIELD data_->socket->open(data_->remote_snd.get(), *this);
+ }
+
+ do {
+ // Begin an asynchronous send, and then yield. When the send completes,
+ // we will resume immediately after this point.
+ data_->origin = ASIODNS_SENDSOCK;
+ CORO_YIELD data_->socket->asyncSend(data_->msgbuf->getData(),
+ data_->msgbuf->getLength(), data_->remote_snd.get(), *this);
+
+ // Now receive the response. Since TCP may not receive the entire
+ // message in one operation, we need to loop until we have received
+ // it. (This can't be done within the asyncReceive() method because
+ // each I/O operation will be done asynchronously and between each one
+ // we need to yield ... and we *really* don't want to set up another
+ // coroutine within that method.) So after each receive (and yield),
+ // we check if the operation is complete and if not, loop to read again.
+ //
+ // Another concession to TCP is that the amount of is contained in the
+ // first two bytes. This leads to two problems:
+ //
+ // a) We don't want those bytes in the return buffer.
+ // b) They may not both arrive in the first I/O.
+ //
+ // So... we need to loop until we have at least two bytes, then store
+ // the expected amount of data. Then we need to loop until we have
+ // received all the data before copying it back to the user's buffer.
+ // And we want to minimise the amount of copying...
+
+ data_->origin = ASIODNS_RECVSOCK;
+ data_->cumulative = 0; // No data yet received
+ data_->offset = 0; // First data into start of buffer
+ data_->received->clear(); // Clear the receive buffer
+ do {
+ CORO_YIELD data_->socket->asyncReceive(data_->staging,
+ static_cast<size_t>(STAGING_LENGTH),
+ data_->offset,
+ data_->remote_rcv.get(), *this);
+ } while (!data_->socket->processReceivedData(data_->staging, length,
+ data_->cumulative, data_->offset,
+ data_->expected, data_->received));
+ } while (!data_->responseOK());
+
+ // Finished with this socket, so close it. This will not generate an
+ // I/O error, but reset the origin to unknown in case we change this.
+ data_->origin = ASIODNS_UNKORIGIN;
+ data_->socket->close();
+
+ /// We are done
+ stop(SUCCESS);
+ }
+}
+
+// Function that stops the coroutine sequence. It is called either when the
+// query finishes or when the timer times out. Either way, it sets the
+// "stopped_" flag and cancels anything that is in progress.
+//
+// As the function may be entered multiple times as things wind down, it checks
+// if the stopped_ flag is already set. If it is, the call is a no-op.
+
+void
+IOFetch::stop(Result result) {
+
+ if (!data_->stopped) {
+
+ // Mark the fetch as stopped to prevent other completion callbacks
+ // (invoked because of the calls to cancel()) from executing the
+ // cancel calls again.
+ //
+ // In a single threaded environment, the callbacks won't be invoked
+ // until this one completes. In a multi-threaded environment, they may
+ // well be, in which case the testing (and setting) of the stopped_
+ // variable should be done inside a mutex (and the stopped_ variable
+ // declared as "volatile").
+ //
+ // The numeric arguments indicate the debug level, with the lower
+ // numbers indicating the most important information. The relative
+ // values are somewhat arbitrary.
+ //
+ // Although Logger::debug checks the debug flag internally, doing it
+ // below before calling Logger::debug avoids the overhead of a string
+ // conversion in the common case when debug is not enabled.
+ //
+ // TODO: Update testing of stopped_ if threads are used.
+ data_->stopped = true;
+ switch (result) {
+ case TIME_OUT:
+ if (logger.isDebugEnabled(1)) {
+ logger.debug(20, ASIODNS_RECVTMO,
+ data_->remote_snd->getAddress().toText().c_str(),
+ static_cast<int>(data_->remote_snd->getPort()));
+ }
+ break;
+
+ case SUCCESS:
+ if (logger.isDebugEnabled(50)) {
+ logger.debug(30, ASIODNS_FETCHCOMP,
+ data_->remote_rcv->getAddress().toText().c_str(),
+ static_cast<int>(data_->remote_rcv->getPort()));
+ }
+ break;
+
+ case STOPPED:
+ // Fetch has been stopped for some other reason. This is
+ // allowed but as it is unusual it is logged, but with a lower
+ // debug level than a timeout (which is totally normal).
+ logger.debug(1, ASIODNS_FETCHSTOP,
+ data_->remote_snd->getAddress().toText().c_str(),
+ static_cast<int>(data_->remote_snd->getPort()));
+ break;
+
+ default:
+ logger.error(ASIODNS_UNKRESULT, static_cast<int>(result),
+ data_->remote_snd->getAddress().toText().c_str(),
+ static_cast<int>(data_->remote_snd->getPort()));
+ }
+
+ // Stop requested, cancel and I/O's on the socket and shut it down,
+ // and cancel the timer.
+ data_->socket->cancel();
+ data_->socket->close();
+
+ data_->timer.cancel();
+
+ // Execute the I/O completion callback (if present).
+ if (data_->callback) {
+ (*(data_->callback))(result);
+ }
+ }
+}
+
+// Log an error - called on I/O failure
+
+void IOFetch::logIOFailure(asio::error_code ec) {
+
+ // Should only get here with a known error code.
+ assert((data_->origin == ASIODNS_OPENSOCK) ||
+ (data_->origin == ASIODNS_SENDSOCK) ||
+ (data_->origin == ASIODNS_RECVSOCK) ||
+ (data_->origin == ASIODNS_UNKORIGIN));
+
+ static const char* PROTOCOL[2] = {"TCP", "UDP"};
+ logger.error(data_->origin,
+ ec.value(),
+ ((data_->remote_snd->getProtocol() == IPPROTO_TCP) ?
+ PROTOCOL[0] : PROTOCOL[1]),
+ data_->remote_snd->getAddress().toText().c_str(),
+ static_cast<int>(data_->remote_snd->getPort()));
+}
+
+} // namespace asiodns
+} // namespace isc {
+
diff --git a/src/lib/asiodns/io_fetch.h b/src/lib/asiodns/io_fetch.h
new file mode 100644
index 0000000..98c917d
--- /dev/null
+++ b/src/lib/asiodns/io_fetch.h
@@ -0,0 +1,204 @@
+// Copyright (C) 2010 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 __IO_FETCH_H
+#define __IO_FETCH_H 1
+
+#include <config.h>
+
+#include <boost/shared_array.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+
+#include <coroutine.h>
+
+#include <asio/error_code.hpp>
+#include <asiolink/io_address.h>
+#include <asiolink/io_service.h>
+
+#include <util/buffer.h>
+#include <dns/question.h>
+
+namespace isc {
+namespace asiodns {
+
+// Forward declarations
+class IOFetchData;
+
+/// \brief Upstream Fetch Processing
+///
+/// IOFetch is the class used to send upstream fetches and to handle responses.
+///
+/// \param E Endpoint type to use.
+
+class IOFetch : public coroutine {
+public:
+ /// \brief Protocol to use on the fetch
+ enum Protocol {
+ UDP = 0,
+ TCP = 1
+ };
+
+ /// \brief Origin of Asynchronous I/O Call
+ ///
+ /// Indicates what initiated an asynchronous I/O call and used in deciding
+ /// what error message to output if the I/O fails.
+ enum Origin {
+ NONE = 0, ///< No asynchronous call outstanding
+ OPEN = 1,
+ SEND = 2,
+ RECEIVE = 3,
+ CLOSE = 4
+ };
+
+ /// \brief Result of Upstream Fetch
+ ///
+ /// Note that this applies to the status of I/Os in the fetch - a fetch
+ /// that resulted in a packet being received from the server is a SUCCESS,
+ /// even if the contents of the packet indicate that some error occurred.
+ enum Result {
+ SUCCESS = 0, ///< Success, fetch completed
+ TIME_OUT = 1, ///< Failure, fetch timed out
+ STOPPED = 2, ///< Control code, fetch has been stopped
+ NOTSET = 3 ///< For testing, indicates value not set
+ };
+
+ // The next enum is a "trick" to allow constants to be defined in a class
+ // declaration.
+
+ /// \brief Integer Constants
+ enum {
+ STAGING_LENGTH = 8192 ///< Size of staging buffer
+ };
+
+ /// \brief I/O Fetch Callback
+ ///
+ /// Class of callback object for when the fetch itself has completed - an
+ /// object of this class is passed to the IOFetch constructor and its
+ /// operator() method called when the fetch completes.
+ ///
+ /// Note the difference between the two operator() methods:
+ /// - IOFetch::operator() callback is called when an asynchronous I/O has
+ /// completed.
+ /// - IOFetch::Callback::operator() is called when an upstream fetch - which
+ /// may have involved several asynchronous I/O operations - has completed.
+ ///
+ /// This is an abstract class.
+ class Callback {
+ public:
+ /// \brief Default Constructor
+ Callback()
+ {}
+
+ /// \brief Virtual Destructor
+ virtual ~Callback()
+ {}
+
+ /// \brief Callback method
+ ///
+ /// This is the method called when the fetch completes.
+ ///
+ /// \param result Result of the fetch
+ virtual void operator()(Result result) = 0;
+ };
+
+ /// \brief Constructor.
+ ///
+ /// Creates the object that will handle the upstream fetch.
+ ///
+ /// \param protocol Fetch protocol, either IOFetch::TCP or IOFetch::UDP
+ /// \param service I/O Service object to handle the asynchronous
+ /// operations.
+ /// \param question DNS question to send to the upstream server.
+ /// \param address IP address of upstream server
+ /// \param port Port to which to connect on the upstream server
+ /// \param buff Output buffer into which the response (in wire format)
+ /// is written (if a response is received).
+ /// \param cb Callback object containing the callback to be called when we
+ /// terminate. The caller is responsible for managing this object
+ /// and deleting it if necessary.
+ /// \param wait Timeout for the fetch (in ms). The default value of
+ /// -1 indicates no timeout.
+ IOFetch(Protocol protocol, isc::asiolink::IOService& service,
+ const isc::dns::Question& question,
+ const isc::asiolink::IOAddress& address,
+ uint16_t port, isc::util::OutputBufferPtr& buff, Callback* cb,
+ int wait = -1);
+
+ /// \brief Constructor.
+ ///
+ /// Creates the object that will handle the upstream fetch.
+ ///
+ /// \param protocol Fetch protocol, either IOFetch::TCP or IOFetch::UDP
+ /// \param service I/O Service object to handle the asynchronous
+ /// operations.
+ /// \param outpkt Packet to send to upstream server. Note that the
+ /// QID (first two bytes of the packet) may be altered in the sending.
+ /// \param buff Output buffer into which the response (in wire format)
+ /// is written (if a response is received).
+ /// \param cb Callback object containing the callback to be called
+ /// when we terminate. The caller is responsible for managing this
+ /// object and deleting it if necessary.
+ /// \param address IP address of upstream server
+ /// \param port Port to which to connect on the upstream server
+ /// (default = 53)
+ /// \param wait Timeout for the fetch (in ms). The default value of
+ /// -1 indicates no timeout.
+ IOFetch(Protocol protocol, isc::asiolink::IOService& service,
+ isc::util::OutputBufferPtr& outpkt,
+ const isc::asiolink::IOAddress& address,
+ uint16_t port, isc::util::OutputBufferPtr& buff, Callback* cb,
+ int wait = -1);
+
+ /// \brief Return Current Protocol
+ ///
+ /// \return Protocol associated with this IOFetch object.
+ Protocol getProtocol() const;
+
+ /// \brief Coroutine entry point
+ ///
+ /// The operator() method is the method in which the coroutine code enters
+ /// this object when an operation has been completed.
+ ///
+ /// \param ec Error code, the result of the last asynchronous I/O operation.
+ /// \param length Amount of data received on the last asynchronous read
+ void operator()(asio::error_code ec = asio::error_code(), size_t length = 0);
+
+ /// \brief Terminate query
+ ///
+ /// This method can be called at any point. It terminates the current
+ /// query with the specified reason.
+ ///
+ /// \param reason Reason for terminating the query
+ void stop(Result reason = STOPPED);
+
+private:
+ /// \brief Log I/O Failure
+ ///
+ /// Records an I/O failure to the log file
+ ///
+ /// \param ec ASIO error code
+ void logIOFailure(asio::error_code ec);
+
+ // Member variables. All data is in a structure pointed to by a shared
+ // pointer. The IOFetch object is copied a number of times during its
+ // life, and only requiring a pointer to be copied reduces overhead.
+ boost::shared_ptr<IOFetchData> data_; ///< Private data
+
+};
+
+} // namespace asiodns
+} // namespace isc
+
+#endif // __IO_FETCH_H
diff --git a/src/lib/asiodns/tcp_server.cc b/src/lib/asiodns/tcp_server.cc
new file mode 100644
index 0000000..f91eb32
--- /dev/null
+++ b/src/lib/asiodns/tcp_server.cc
@@ -0,0 +1,244 @@
+// Copyright (C) 2011 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 <netinet/in.h>
+#include <sys/socket.h>
+#include <unistd.h> // for some IPC/network system calls
+#include <errno.h>
+
+#include <boost/shared_array.hpp>
+
+#include <log/dummylog.h>
+
+#include <util/buffer.h>
+
+#include <asio.hpp>
+#include <asiolink/dummy_io_cb.h>
+#include <asiolink/tcp_endpoint.h>
+#include <asiolink/tcp_socket.h>
+#include <tcp_server.h>
+
+
+using namespace asio;
+using asio::ip::udp;
+using asio::ip::tcp;
+
+using namespace std;
+using namespace isc::dns;
+using namespace isc::util;
+using namespace isc::asiolink;
+
+namespace isc {
+namespace asiodns {
+
+/// The following functions implement the \c TCPServer class.
+///
+/// The constructor
+TCPServer::TCPServer(io_service& io_service,
+ const ip::address& addr, const uint16_t port,
+ const SimpleCallback* checkin,
+ const DNSLookup* lookup,
+ const DNSAnswer* answer) :
+ io_(io_service), done_(false),
+ checkin_callback_(checkin), lookup_callback_(lookup),
+ answer_callback_(answer)
+{
+ tcp::endpoint endpoint(addr, port);
+ acceptor_.reset(new tcp::acceptor(io_service));
+ acceptor_->open(endpoint.protocol());
+ // Set v6-only (we use a separate instantiation for v4,
+ // otherwise asio will bind to both v4 and v6
+ if (addr.is_v6()) {
+ acceptor_->set_option(ip::v6_only(true));
+ }
+ acceptor_->set_option(tcp::acceptor::reuse_address(true));
+ acceptor_->bind(endpoint);
+ acceptor_->listen();
+}
+
+void
+TCPServer::operator()(error_code ec, size_t length) {
+ /// Because the coroutine reentry block is implemented as
+ /// a switch statement, inline variable declarations are not
+ /// permitted. Certain variables used below can be declared here.
+
+ boost::array<const_buffer,2> bufs;
+ OutputBuffer lenbuf(TCP_MESSAGE_LENGTHSIZE);
+
+ CORO_REENTER (this) {
+ do {
+ /// Create a socket to listen for connections
+ socket_.reset(new tcp::socket(acceptor_->get_io_service()));
+
+ /// Wait for new connections. In the event of non-fatal error,
+ /// try again
+ do {
+ CORO_YIELD acceptor_->async_accept(*socket_, *this);
+
+ // Abort on fatal errors
+ // TODO: Log error?
+ if (ec) {
+ using namespace asio::error;
+ if (ec.value() != would_block && ec.value() != try_again &&
+ ec.value() != connection_aborted &&
+ ec.value() != interrupted) {
+ return;
+ }
+ }
+ } while (ec);
+
+ /// Fork the coroutine by creating a copy of this one and
+ /// scheduling it on the ASIO service queue. The parent
+ /// will continue listening for DNS connections while the
+ /// handles the one that has just arrived.
+ CORO_FORK io_.post(TCPServer(*this));
+ } while (is_parent());
+
+ /// Instantiate the data buffer that will be used by the
+ /// asynchronous read call.
+ data_.reset(new char[MAX_LENGTH]);
+
+ /// Read the message, in two parts. First, the message length:
+ CORO_YIELD async_read(*socket_, asio::buffer(data_.get(),
+ TCP_MESSAGE_LENGTHSIZE), *this);
+ if (ec) {
+ socket_->close();
+ CORO_YIELD return;
+ }
+
+ /// Now read the message itself. (This is done in a different scope
+ /// to allow inline variable declarations.)
+ CORO_YIELD {
+ InputBuffer dnsbuffer(data_.get(), length);
+ uint16_t msglen = dnsbuffer.readUint16();
+ async_read(*socket_, asio::buffer(data_.get(), msglen), *this);
+ }
+
+ if (ec) {
+ socket_->close();
+ CORO_YIELD return;
+ }
+
+
+ // Create an \c IOMessage object to store the query.
+ //
+ // (XXX: It would be good to write a factory function
+ // that would quickly generate an IOMessage object without
+ // all these calls to "new".)
+ peer_.reset(new TCPEndpoint(socket_->remote_endpoint()));
+
+ // The TCP socket class has been extended with asynchronous functions
+ // and takes as a template parameter a completion callback class. As
+ // TCPServer does not use these extended functions (only those defined
+ // in the IOSocket base class) - but needs a TCPSocket to get hold of
+ // the underlying Boost TCP socket - DummyIOCallback is used. This
+ // provides the appropriate operator() but is otherwise functionless.
+ iosock_.reset(new TCPSocket<DummyIOCallback>(*socket_));
+ io_message_.reset(new IOMessage(data_.get(), length, *iosock_, *peer_));
+ bytes_ = length;
+
+ // Perform any necessary operations prior to processing the incoming
+ // packet (e.g., checking for queued configuration messages).
+ //
+ // (XXX: it may be a performance issue to have this called for
+ // every single incoming packet; we may wish to throttle it somehow
+ // in the future.)
+ if (checkin_callback_ != NULL) {
+ (*checkin_callback_)(*io_message_);
+ }
+
+ // If we don't have a DNS Lookup provider, there's no point in
+ // continuing; we exit the coroutine permanently.
+ if (lookup_callback_ == NULL) {
+ socket_->close();
+ CORO_YIELD return;
+ }
+
+ // Reset or instantiate objects that will be needed by the
+ // DNS lookup and the write call.
+ respbuf_.reset(new OutputBuffer(0));
+ query_message_.reset(new Message(Message::PARSE));
+ answer_message_.reset(new Message(Message::RENDER));
+
+ // Schedule a DNS lookup, and yield. When the lookup is
+ // finished, the coroutine will resume immediately after
+ // this point.
+ CORO_YIELD io_.post(AsyncLookup<TCPServer>(*this));
+
+ // The 'done_' flag indicates whether we have an answer
+ // to send back. If not, exit the coroutine permanently.
+ if (!done_) {
+ // TODO: should we keep the connection open for a short time
+ // to see if new requests come in?
+ socket_->close();
+ CORO_YIELD return;
+ }
+
+ if (ec) {
+ CORO_YIELD return;
+ }
+ // Call the DNS answer provider to render the answer into
+ // wire format
+ (*answer_callback_)(*io_message_, query_message_,
+ answer_message_, respbuf_);
+
+ // Set up the response, beginning with two length bytes.
+ lenbuf.writeUint16(respbuf_->getLength());
+ bufs[0] = buffer(lenbuf.getData(), lenbuf.getLength());
+ bufs[1] = buffer(respbuf_->getData(), respbuf_->getLength());
+
+ // Begin an asynchronous send, and then yield. When the
+ // send completes, we will resume immediately after this point
+ // (though we have nothing further to do, so the coroutine
+ // will simply exit at that time).
+ CORO_YIELD async_write(*socket_, bufs, *this);
+
+ // TODO: should we keep the connection open for a short time
+ // to see if new requests come in?
+ socket_->close();
+ }
+}
+
+/// Call the DNS lookup provider. (Expected to be called by the
+/// AsyncLookup<TCPServer> handler.)
+void
+TCPServer::asyncLookup() {
+ (*lookup_callback_)(*io_message_, query_message_,
+ answer_message_, respbuf_, this);
+}
+
+void TCPServer::stop() {
+ /// we use close instead of cancel, with the same reason
+ /// with udp server stop, refer to the udp server code
+
+ acceptor_->close();
+ // User may stop the server even when it hasn't started to
+ // run, in that that socket_ is empty
+ if (socket_) {
+ socket_->close();
+ }
+}
+/// 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
+TCPServer::resume(const bool done) {
+ done_ = done;
+ io_.post(*this);
+}
+
+} // namespace asiodns
+} // namespace isc
diff --git a/src/lib/asiodns/tcp_server.h b/src/lib/asiodns/tcp_server.h
new file mode 100644
index 0000000..22a2f69
--- /dev/null
+++ b/src/lib/asiodns/tcp_server.h
@@ -0,0 +1,124 @@
+// Copyright (C) 2011 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 __TCP_SERVER_H
+#define __TCP_SERVER_H 1
+
+#ifndef ASIO_HPP
+#error "asio.hpp must be included before including this, see asiolink.h as to why"
+#endif
+
+#include <boost/shared_array.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <asiolink/asiolink.h>
+#include <coroutine.h>
+#include "dns_server.h"
+#include "dns_lookup.h"
+#include "dns_answer.h"
+
+namespace isc {
+namespace asiodns {
+
+/// \brief A TCP-specific \c DNSServer object.
+///
+/// This class inherits from both \c DNSServer and from \c coroutine,
+/// defined in coroutine.h.
+class TCPServer : public virtual DNSServer, public virtual coroutine {
+public:
+ explicit TCPServer(asio::io_service& io_service,
+ const asio::ip::address& addr, const uint16_t port,
+ const isc::asiolink::SimpleCallback* checkin = NULL,
+ const DNSLookup* lookup = NULL,
+ const DNSAnswer* answer = NULL);
+
+ void operator()(asio::error_code ec = asio::error_code(),
+ size_t length = 0);
+ 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);
+ }
+
+private:
+ enum { MAX_LENGTH = 65535 };
+ static const size_t TCP_MESSAGE_LENGTHSIZE = 2;
+
+ // The ASIO service object
+ asio::io_service& io_;
+
+ // Class member variables which are dynamic, and changes to which
+ // need to accessible from both sides of a coroutine fork or from
+ // outside of the coroutine (i.e., from an asynchronous I/O call),
+ // should be declared here as pointers and allocated in the
+ // constructor or in the coroutine. This allows state information
+ // to persist when an individual copy of the coroutine falls out
+ // scope while waiting for an event, *so long as* there is another
+ // object that is referencing the same data. As a side-benefit, using
+ // pointers also reduces copy overhead for coroutine objects.
+ //
+ // Note: Currently these objects are allocated by "new" in the
+ // constructor, or in the function operator while processing a query.
+ // Repeated allocations from the heap for every incoming query is
+ // clearly a performance issue; this must be optimized in the future.
+ // The plan is to have a structure pre-allocate several "server state"
+ // objects which can be pulled off a free list and placed on an in-use
+ // list whenever a query comes in. This will serve the dual purpose
+ // of improving performance and guaranteeing that state information
+ // will *not* be destroyed when any one instance of the coroutine
+ // falls out of scope while waiting for an event.
+ //
+ // An ASIO acceptor object to handle new connections. Created in
+ // the constructor.
+ boost::shared_ptr<asio::ip::tcp::acceptor> acceptor_;
+
+ // Socket used to for listen for queries. Created in the
+ // constructor and stored in a shared_ptr because socket objects
+ // are not copyable.
+ boost::shared_ptr<asio::ip::tcp::socket> socket_;
+
+ // The buffer into which the response is written
+ boost::shared_ptr<isc::util::OutputBuffer> respbuf_;
+
+ // \c IOMessage and \c Message objects to be passed to the
+ // DNS lookup and answer providers
+ boost::shared_ptr<isc::asiolink::IOMessage> io_message_;
+ isc::dns::MessagePtr query_message_;
+ isc::dns::MessagePtr answer_message_;
+
+ // The buffer into which the query packet is written
+ boost::shared_array<char>data_;
+
+ // State information that is entirely internal to a given instance
+ // of the coroutine can be declared here.
+ size_t bytes_;
+ bool done_;
+
+ // Callback functions provided by the caller
+ const isc::asiolink::SimpleCallback* checkin_callback_;
+ const DNSLookup* lookup_callback_;
+ const DNSAnswer* answer_callback_;
+
+ boost::shared_ptr<isc::asiolink::IOEndpoint> peer_;
+ boost::shared_ptr<isc::asiolink::IOSocket> iosock_;
+};
+
+} // namespace asiodns
+} // namespace isc
+#endif // __TCP_SERVER_H
diff --git a/src/lib/asiodns/tests/Makefile.am b/src/lib/asiodns/tests/Makefile.am
new file mode 100644
index 0000000..fd65d0b
--- /dev/null
+++ b/src/lib/asiodns/tests/Makefile.am
@@ -0,0 +1,50 @@
+AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CPPFLAGS += -I$(top_builddir)/src/lib/dns -I$(top_srcdir)/src/bin
+AM_CPPFLAGS += -I$(top_builddir)/src/lib/cc -I$(top_builddir)/src/lib/util
+AM_CPPFLAGS += -DTEST_DATA_DIR=\"$(srcdir)/testdata\"
+
+AM_CXXFLAGS = $(B10_CXXFLAGS)
+
+if USE_STATIC_LINK
+AM_LDFLAGS = -static
+endif
+
+CLEANFILES = *.gcno *.gcda
+
+TESTS =
+if HAVE_GTEST
+TESTS += run_unittests
+run_unittests_SOURCES = run_unittests.cc
+run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.h
+run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.cc
+run_unittests_SOURCES += io_service_unittest.cc
+run_unittests_SOURCES += dns_server_unittest.cc
+run_unittests_SOURCES += io_fetch_unittest.cc
+
+run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
+
+run_unittests_LDADD = $(GTEST_LDADD)
+run_unittests_LDADD += $(SQLITE_LIBS)
+run_unittests_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
+run_unittests_LDADD += $(top_builddir)/src/lib/util/libutil.la
+run_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
+run_unittests_LDADD += $(top_builddir)/src/lib/log/liblog.la
+run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
+run_unittests_LDADD += $(top_builddir)/src/lib/asiodns/libasiodns.la
+
+run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
+
+# Note: the ordering matters: -Wno-... must follow -Wextra (defined in
+# B10_CXXFLAGS)
+run_unittests_CXXFLAGS = $(AM_CXXFLAGS)
+if USE_GXX
+run_unittests_CXXFLAGS += -Wno-unused-parameter
+endif
+if USE_CLANGPP
+# Same for clang++, but we need to turn off -Werror completely.
+run_unittests_CXXFLAGS += -Wno-error
+endif
+endif
+
+noinst_PROGRAMS = $(TESTS)
diff --git a/src/lib/asiodns/tests/dns_server_unittest.cc b/src/lib/asiodns/tests/dns_server_unittest.cc
new file mode 100644
index 0000000..1ef3192
--- /dev/null
+++ b/src/lib/asiodns/tests/dns_server_unittest.cc
@@ -0,0 +1,503 @@
+// Copyright (C) 2011 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 <gtest/gtest.h>
+
+#include <asio.hpp>
+#include <asiolink/io_endpoint.h>
+#include <asiolink/io_error.h>
+#include <asiodns/udp_server.h>
+#include <asiodns/tcp_server.h>
+#include <asiodns/dns_answer.h>
+#include <asiodns/dns_lookup.h>
+#include <string>
+#include <csignal>
+#include <unistd.h> //for alarm
+
+#include <boost/shared_ptr.hpp>
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+
+
+/// The following tests focus on stop interface for udp and
+/// tcp server, there are lots of things can be shared to test
+/// both tcp and udp server, so they are in the same unittest
+
+/// The general work flow for dns server, is that wait for user
+/// query, once get one query, we will check the data is valid or
+/// not, if it passed, we will try to loop up the question, then
+/// compose the answer and finally send it back to user. The server
+/// may be stopped at any point during this porcess, so the test strategy
+/// is that we define 5 stop point and stop the server at these
+/// 5 points, to check whether stop is successful
+/// The 5 test points are :
+/// Before the server start to run
+/// After we get the query and check whether it's valid
+/// After we lookup the query
+/// After we compoisite the answer
+/// After user get the final result.
+
+/// The standard about whether we stop the server successfully or not
+/// is based on the fact that if the server is still running, the io
+/// service won't quit since it will wait for some asynchronized event for
+/// server. So if the io service block function run returns we assume
+/// that the server is stopped. To avoid stop interface failure which
+/// will block followed tests, using alarm signal to stop the blocking
+/// io service
+///
+/// The whole test context including one server and one client, and
+/// five stop checkpoints, we call them ServerStopper exclude the first
+/// stop point. Once the unittest fired, the client will send message
+/// to server, and the stopper may stop the server at the checkpoint, then
+/// we check the client get feedback or not. Since there is no DNS logic
+/// involved so the message sending between client and server is plain text
+/// And the valid checker, question lookup and answer composition are dummy.
+
+using namespace isc::asiolink;
+using namespace isc::asiodns;
+using namespace asio;
+
+namespace {
+static const std::string server_ip = "127.0.0.1";
+const int server_port = 5553;
+//message client send to udp server, which isn't dns package
+//just for simple testing
+static const std::string query_message("BIND10 is awesome");
+
+// \brief provide capacity to derived class the ability
+// to stop DNSServer at certern point
+class ServerStopper {
+ public:
+ ServerStopper() : server_to_stop_(NULL) {}
+ virtual ~ServerStopper(){}
+
+ void setServerToStop(DNSServer* server) {
+ server_to_stop_ = server;
+ }
+
+ void stopServer() const {
+ if (server_to_stop_) {
+ server_to_stop_->stop();
+ }
+ }
+
+ private:
+ DNSServer* server_to_stop_;
+};
+
+// \brief no check logic at all,just provide a checkpoint to stop the server
+class DummyChecker : public SimpleCallback, public ServerStopper {
+ public:
+ virtual void operator()(const IOMessage&) const {
+ stopServer();
+ }
+};
+
+// \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();
+ server->resume(true);
+ }
+};
+
+// \brief copy the data received from user to the answer part
+// provide checkpoint to stop server
+class SimpleAnswer : public DNSAnswer, public ServerStopper {
+ public:
+ void operator()(const IOMessage& message,
+ isc::dns::MessagePtr query_message,
+ isc::dns::MessagePtr answer_message,
+ isc::util::OutputBufferPtr buffer) const
+ {
+ //copy what we get from user
+ buffer->writeData(message.getData(), message.getDataSize());
+ stopServer();
+ }
+
+};
+
+// \brief simple client, send one string to server and wait for response
+// in case, server stopped and client cann't get response, there is a timer wait
+// for specified seconds (the value is just a estimate since server process logic is quite
+// simple, and all the intercommunication is local) then cancel the waiting.
+class SimpleClient : public ServerStopper {
+ public:
+ static const size_t MAX_DATA_LEN = 256;
+ SimpleClient(asio::io_service& service,
+ unsigned int wait_server_time_out)
+ {
+ wait_for_response_timer_.reset(new deadline_timer(service));
+ received_data_ = new char[MAX_DATA_LEN];
+ received_data_len_ = 0;
+ wait_server_time_out_ = wait_server_time_out;
+ }
+
+ virtual ~SimpleClient() {
+ delete [] received_data_;
+ }
+
+ void setGetFeedbackCallback(boost::function<void()>& func) {
+ get_response_call_back_ = func;
+ }
+
+ virtual void sendDataThenWaitForFeedback(const std::string& data) = 0;
+ virtual std::string getReceivedData() const = 0;
+
+ void startTimer() {
+ wait_for_response_timer_->cancel();
+ wait_for_response_timer_->
+ expires_from_now(boost::posix_time::
+ seconds(wait_server_time_out_));
+ wait_for_response_timer_->
+ async_wait(boost::bind(&SimpleClient::stopWaitingforResponse,
+ this));
+ }
+
+ void cancelTimer() { wait_for_response_timer_->cancel(); }
+
+ void getResponseCallBack(const asio::error_code& error, size_t
+ received_bytes)
+ {
+ cancelTimer();
+ if (!error)
+ received_data_len_ = received_bytes;
+ if (!get_response_call_back_.empty()) {
+ get_response_call_back_();
+ }
+ stopServer();
+ }
+
+
+ protected:
+ virtual void stopWaitingforResponse() = 0;
+
+ boost::shared_ptr<deadline_timer> wait_for_response_timer_;
+ char* received_data_;
+ size_t received_data_len_;
+ boost::function<void()> get_response_call_back_;
+ unsigned int wait_server_time_out_;
+};
+
+
+
+class UDPClient : public SimpleClient {
+ public:
+ //After 1 seconds without feedback client will stop wait
+ static const unsigned int server_time_out = 1;
+
+ UDPClient(asio::io_service& service, const ip::udp::endpoint& server) :
+ SimpleClient(service, server_time_out)
+ {
+ server_ = server;
+ socket_.reset(new ip::udp::socket(service));
+ socket_->open(ip::udp::v4());
+ }
+
+
+ void sendDataThenWaitForFeedback(const std::string& data) {
+ received_data_len_ = 0;
+ socket_->send_to(buffer(data.c_str(), data.size() + 1), server_);
+ socket_->async_receive_from(buffer(received_data_, MAX_DATA_LEN),
+ received_from_,
+ boost::bind(&SimpleClient::
+ getResponseCallBack, this, _1,
+ _2));
+ startTimer();
+ }
+
+ virtual std::string getReceivedData() const {
+ return (received_data_len_ == 0 ? std::string("") :
+ std::string(received_data_));
+ }
+
+ private:
+ void stopWaitingforResponse() {
+ socket_->close();
+ }
+
+ boost::shared_ptr<ip::udp::socket> socket_;
+ ip::udp::endpoint server_;
+ ip::udp::endpoint received_from_;
+};
+
+
+class TCPClient : public SimpleClient {
+ public:
+ // after 2 seconds without feedback client will stop wait,
+ // this includes connect, send message and recevice message
+ static const unsigned int server_time_out = 2;
+ TCPClient(asio::io_service& service, const ip::tcp::endpoint& server)
+ : SimpleClient(service, server_time_out)
+ {
+ server_ = server;
+ socket_.reset(new ip::tcp::socket(service));
+ socket_->open(ip::tcp::v4());
+ }
+
+
+ virtual void sendDataThenWaitForFeedback(const std::string &data) {
+ received_data_len_ = 0;
+ data_to_send_ = data;
+ data_to_send_len_ = data.size() + 1;
+ socket_->async_connect(server_, boost::bind(&TCPClient::connectHandler,
+ this, _1));
+ startTimer();
+ }
+
+ virtual std::string getReceivedData() const {
+ return (received_data_len_ == 0 ? std::string("") :
+ std::string(received_data_ + 2));
+ }
+
+ private:
+ void stopWaitingforResponse() {
+ socket_->close();
+ }
+
+ void connectHandler(const asio::error_code& error) {
+ if (!error) {
+ data_to_send_len_ = htons(data_to_send_len_);
+ socket_->async_send(buffer(&data_to_send_len_, 2),
+ boost::bind(&TCPClient::sendMessageBodyHandler,
+ this, _1, _2));
+ }
+ }
+
+ void sendMessageBodyHandler(const asio::error_code& error,
+ size_t send_bytes)
+ {
+ if (!error && send_bytes == 2) {
+ socket_->async_send(buffer(data_to_send_.c_str(),
+ data_to_send_.size() + 1),
+ boost::bind(&TCPClient::finishSendHandler, this, _1, _2));
+ }
+ }
+
+ void finishSendHandler(const asio::error_code& error, size_t send_bytes) {
+ if (!error && send_bytes == data_to_send_.size() + 1) {
+ socket_->async_receive(buffer(received_data_, MAX_DATA_LEN),
+ boost::bind(&SimpleClient::getResponseCallBack, this, _1,
+ _2));
+ }
+ }
+
+ boost::shared_ptr<ip::tcp::socket> socket_;
+ ip::tcp::endpoint server_;
+ std::string data_to_send_;
+ uint16_t data_to_send_len_;
+};
+
+
+
+// \brief provide the context which including two client and
+// two server, udp client will only communicate with udp server, same for tcp client
+class DNSServerTest : public::testing::Test {
+ protected:
+ void SetUp() {
+ ip::address server_address = ip::address::from_string(server_ip);
+ checker_ = new DummyChecker();
+ lookup_ = new DummyLookup();
+ answer_ = new SimpleAnswer();
+ udp_server_ = new UDPServer(service, server_address, server_port,
+ checker_, lookup_, answer_);
+ udp_client_ = new UDPClient(service,
+ ip::udp::endpoint(server_address,
+ server_port));
+ tcp_server_ = new TCPServer(service, server_address, server_port,
+ checker_, lookup_, answer_);
+ tcp_client_ = new TCPClient(service,
+ ip::tcp::endpoint(server_address,
+ server_port));
+ }
+
+
+ void TearDown() {
+ udp_server_->stop();
+ tcp_server_->stop();
+ delete checker_;
+ delete lookup_;
+ delete answer_;
+ delete udp_server_;
+ delete udp_client_;
+ delete tcp_server_;
+ delete tcp_client_;
+ }
+
+
+ void testStopServerByStopper(DNSServer* server, SimpleClient* client,
+ ServerStopper* stopper)
+ {
+ static const unsigned int io_service_time_out = 5;
+ io_service_is_time_out = false;
+ stopper->setServerToStop(server);
+ (*server)();
+ client->sendDataThenWaitForFeedback(query_message);
+ // Since thread hasn't been introduced into the tool box, using signal
+ // to make sure run function will eventually return even server stop
+ // failed
+ void (*prev_handler)(int) = std::signal(SIGALRM, DNSServerTest::stopIOService);
+ alarm(io_service_time_out);
+ service.run();
+ service.reset();
+ //cancel scheduled alarm
+ alarm(0);
+ std::signal(SIGALRM, prev_handler);
+ }
+
+
+ static void stopIOService(int _no_use_parameter) {
+ io_service_is_time_out = true;
+ service.stop();
+ }
+
+ bool serverStopSucceed() const {
+ return (!io_service_is_time_out);
+ }
+
+ DummyChecker* checker_;
+ DummyLookup* lookup_;
+ SimpleAnswer* answer_;
+ UDPServer* udp_server_;
+ UDPClient* udp_client_;
+ TCPClient* tcp_client_;
+ TCPServer* tcp_server_;
+
+ // To access them in signal handle function, the following
+ // variables have to be static.
+ static asio::io_service service;
+ static bool io_service_is_time_out;
+};
+
+bool DNSServerTest::io_service_is_time_out = false;
+asio::io_service DNSServerTest::service;
+
+// Test whether server stopped successfully after client get response
+// client will send query and start to wait for response, once client
+// get response, udp server will be stopped, the io service won't quit
+// if udp server doesn't stop successfully.
+TEST_F(DNSServerTest, stopUDPServerAfterOneQuery) {
+ testStopServerByStopper(udp_server_, udp_client_, udp_client_);
+ EXPECT_EQ(query_message, udp_client_->getReceivedData());
+ EXPECT_TRUE(serverStopSucceed());
+}
+
+// Test whether udp server stopped successfully before server start to serve
+TEST_F(DNSServerTest, stopUDPServerBeforeItStartServing) {
+ udp_server_->stop();
+ testStopServerByStopper(udp_server_, udp_client_, udp_client_);
+ EXPECT_EQ(std::string(""), udp_client_->getReceivedData());
+ EXPECT_TRUE(serverStopSucceed());
+}
+
+
+// Test whether udp server stopped successfully during message check
+TEST_F(DNSServerTest, stopUDPServerDuringMessageCheck) {
+ testStopServerByStopper(udp_server_, udp_client_, checker_);
+ EXPECT_EQ(std::string(""), udp_client_->getReceivedData());
+ EXPECT_TRUE(serverStopSucceed());
+}
+
+// Test whether udp server stopped successfully during query lookup
+TEST_F(DNSServerTest, stopUDPServerDuringQueryLookup) {
+ testStopServerByStopper(udp_server_, udp_client_, lookup_);
+ EXPECT_EQ(std::string(""), udp_client_->getReceivedData());
+ EXPECT_TRUE(serverStopSucceed());
+}
+
+// Test whether udp server stopped successfully during composing answer
+TEST_F(DNSServerTest, stopUDPServerDuringPrepareAnswer) {
+ testStopServerByStopper(udp_server_, udp_client_, answer_);
+ EXPECT_EQ(std::string(""), udp_client_->getReceivedData());
+ EXPECT_TRUE(serverStopSucceed());
+}
+
+static void stopServerManyTimes(DNSServer *server, unsigned int times) {
+ for (int i = 0; i < times; ++i) {
+ server->stop();
+ }
+}
+
+// Test whether udp server stop interface can be invoked several times without
+// throw any exception
+TEST_F(DNSServerTest, stopUDPServeMoreThanOnce) {
+ ASSERT_NO_THROW({
+ boost::function<void()> stop_server_3_times
+ = boost::bind(stopServerManyTimes, udp_server_, 3);
+ udp_client_->setGetFeedbackCallback(stop_server_3_times);
+ testStopServerByStopper(udp_server_, udp_client_, udp_client_);
+ EXPECT_EQ(query_message, udp_client_->getReceivedData());
+ });
+ EXPECT_TRUE(serverStopSucceed());
+}
+
+
+TEST_F(DNSServerTest, stopTCPServerAfterOneQuery) {
+ testStopServerByStopper(tcp_server_, tcp_client_, tcp_client_);
+ EXPECT_EQ(query_message, tcp_client_->getReceivedData());
+ EXPECT_TRUE(serverStopSucceed());
+}
+
+
+// Test whether tcp server stopped successfully before server start to serve
+TEST_F(DNSServerTest, stopTCPServerBeforeItStartServing) {
+ tcp_server_->stop();
+ testStopServerByStopper(tcp_server_, tcp_client_, tcp_client_);
+ EXPECT_EQ(std::string(""), tcp_client_->getReceivedData());
+ EXPECT_TRUE(serverStopSucceed());
+}
+
+
+// Test whether tcp server stopped successfully during message check
+TEST_F(DNSServerTest, stopTCPServerDuringMessageCheck) {
+ testStopServerByStopper(tcp_server_, tcp_client_, checker_);
+ EXPECT_EQ(std::string(""), tcp_client_->getReceivedData());
+ EXPECT_TRUE(serverStopSucceed());
+}
+
+// Test whether tcp server stopped successfully during query lookup
+TEST_F(DNSServerTest, stopTCPServerDuringQueryLookup) {
+ testStopServerByStopper(tcp_server_, tcp_client_, lookup_);
+ EXPECT_EQ(std::string(""), tcp_client_->getReceivedData());
+ EXPECT_TRUE(serverStopSucceed());
+}
+
+// Test whether tcp server stopped successfully during composing answer
+TEST_F(DNSServerTest, stopTCPServerDuringPrepareAnswer) {
+ testStopServerByStopper(tcp_server_, tcp_client_, answer_);
+ EXPECT_EQ(std::string(""), tcp_client_->getReceivedData());
+ EXPECT_TRUE(serverStopSucceed());
+}
+
+
+// Test whether tcp server stop interface can be invoked several times without
+// throw any exception
+TEST_F(DNSServerTest, stopTCPServeMoreThanOnce) {
+ ASSERT_NO_THROW({
+ boost::function<void()> stop_server_3_times
+ = boost::bind(stopServerManyTimes, tcp_server_, 3);
+ tcp_client_->setGetFeedbackCallback(stop_server_3_times);
+ testStopServerByStopper(tcp_server_, tcp_client_, tcp_client_);
+ EXPECT_EQ(query_message, tcp_client_->getReceivedData());
+ });
+ EXPECT_TRUE(serverStopSucceed());
+}
+
+}
diff --git a/src/lib/asiodns/tests/io_fetch_unittest.cc b/src/lib/asiodns/tests/io_fetch_unittest.cc
new file mode 100644
index 0000000..2464b6d
--- /dev/null
+++ b/src/lib/asiodns/tests/io_fetch_unittest.cc
@@ -0,0 +1,728 @@
+// Copyright (C) 2011 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 <algorithm>
+#include <cstdlib>
+#include <string>
+#include <iostream>
+#include <iomanip>
+#include <iterator>
+#include <vector>
+
+#include <gtest/gtest.h>
+#include <boost/bind.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+
+#include <asio.hpp>
+
+#include <util/buffer.h>
+#include <util/io_utilities.h>
+
+#include <dns/question.h>
+#include <dns/message.h>
+#include <dns/messagerenderer.h>
+#include <dns/opcode.h>
+#include <dns/name.h>
+#include <dns/rcode.h>
+
+#include <asiolink/io_address.h>
+#include <asiolink/io_endpoint.h>
+#include <asiolink/io_service.h>
+#include <asiodns/io_fetch.h>
+
+using namespace asio;
+using namespace isc::dns;
+using namespace isc::util;
+using namespace asio::ip;
+using namespace std;
+using namespace isc::asiolink;
+
+namespace isc {
+namespace asiodns {
+
+const asio::ip::address TEST_HOST(asio::ip::address::from_string("127.0.0.1"));
+const uint16_t TEST_PORT(5301);
+const int SEND_INTERVAL = 250; // Interval in ms between TCP sends
+const size_t MAX_SIZE = 64 * 1024; // Should be able to take 64kB
+
+// The tests are complex, so debug output has been left in (although disabled).
+// Set this to true to enable it.
+const bool DEBUG = false;
+
+/// \brief Test fixture for the asiolink::IOFetch.
+class IOFetchTest : public virtual ::testing::Test, public virtual IOFetch::Callback
+{
+public:
+ IOService service_; ///< Service to run the query
+ IOFetch::Result expected_; ///< Expected result of the callback
+ bool run_; ///< Did the callback run already?
+ Question question_; ///< What to ask
+ OutputBufferPtr result_buff_; ///< Buffer to hold result of fetch
+ OutputBufferPtr msgbuf_; ///< Buffer corresponding to known question
+ IOFetch udp_fetch_; ///< For UDP query test
+ IOFetch tcp_fetch_; ///< For TCP query test
+ IOFetch::Protocol protocol_; ///< Protocol being tested
+ size_t cumulative_; ///< Cumulative data received by "server".
+ deadline_timer timer_; ///< Timer to measure timeouts
+
+ // The next member is the buffer in which the "server" (implemented by the
+ // response handler methods in this class) receives the question sent by the
+ // fetch object.
+ uint8_t receive_buffer_[MAX_SIZE]; ///< Server receive buffer
+ OutputBufferPtr expected_buffer_; ///< Data we expect to receive
+ vector<uint8_t> send_buffer_; ///< Server send buffer
+ uint16_t send_cumulative_; ///< Data sent so far
+
+ // Other data.
+ string return_data_; ///< Data returned by server
+ string test_data_; ///< Large string - here for convenience
+ bool debug_; ///< true to enable debug output
+ size_t tcp_send_size_; ///< Max size of TCP send
+ uint8_t qid_0; ///< First octet of qid
+ uint8_t qid_1; ///< Second octet of qid
+
+ bool tcp_short_send_; ///< If set to true, we do not send
+ /// all data in the tcp response
+
+ /// \brief Constructor
+ IOFetchTest() :
+ service_(),
+ expected_(IOFetch::NOTSET),
+ run_(false),
+ question_(Name("example.net"), RRClass::IN(), RRType::A()),
+ result_buff_(new OutputBuffer(512)),
+ msgbuf_(new OutputBuffer(512)),
+ udp_fetch_(IOFetch::UDP, service_, question_, IOAddress(TEST_HOST),
+ TEST_PORT, result_buff_, this, 100),
+ tcp_fetch_(IOFetch::TCP, service_, question_, IOAddress(TEST_HOST),
+ TEST_PORT, result_buff_, this, (16 * SEND_INTERVAL)),
+ // Timeout interval chosen to ensure no timeout
+ protocol_(IOFetch::TCP), // for initialization - will be changed
+ cumulative_(0),
+ timer_(service_.get_io_service()),
+ receive_buffer_(),
+ expected_buffer_(new OutputBuffer(512)),
+ send_buffer_(),
+ send_cumulative_(0),
+ return_data_(""),
+ test_data_(""),
+ debug_(DEBUG),
+ tcp_send_size_(0),
+ qid_0(0),
+ qid_1(0),
+ tcp_short_send_(false)
+ {
+ // Construct the data buffer for question we expect to receive.
+ Message msg(Message::RENDER);
+ msg.setQid(0);
+ msg.setOpcode(Opcode::QUERY());
+ msg.setRcode(Rcode::NOERROR());
+ msg.setHeaderFlag(Message::HEADERFLAG_RD);
+ msg.addQuestion(question_);
+ MessageRenderer renderer(*msgbuf_);
+ msg.toWire(renderer);
+ MessageRenderer renderer2(*expected_buffer_);
+ msg.toWire(renderer2);
+
+ // 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
+ // the class.)
+ //
+ // We could initialize the data with a single character, but as an added
+ // check we'll make ssre that it has some structure.
+
+ test_data_.clear();
+ test_data_.reserve(MAX_SIZE);
+ while (test_data_.size() < MAX_SIZE) {
+ test_data_ += "A message to be returned to the client that has "
+ "some sort of structure.";
+ }
+ }
+
+ /// \brief UDP Response handler (the "remote UDP DNS server")
+ ///
+ /// When IOFetch is sending data, this response handler emulates the remote
+ /// DNS server. It checks that the data sent by the IOFetch object is what
+ /// was expected to have been sent, then sends back a known buffer of data.
+ ///
+ /// \param remote Endpoint to which to send the answer
+ /// \param socket Socket to use to send the answer
+ /// \param ec ASIO error code, completion code of asynchronous I/O issued
+ /// by the "server" to receive data.
+ /// \param bad_qid If set to true, the QID in the response will be mangled
+ /// \param second_send If set to true, (and bad_qid is too), after the
+ /// mangled qid response has been sent, a second packet will be
+ /// sent with the correct QID.
+ /// \param length Amount of data received.
+ void udpReceiveHandler(udp::endpoint* remote, udp::socket* socket,
+ error_code ec = error_code(), size_t length = 0,
+ bool bad_qid = false, bool second_send = false) {
+ if (debug_) {
+ cout << "udpReceiveHandler(): error = " << ec.value() <<
+ ", length = " << length << endl;
+ }
+
+ // The QID in the incoming data is random so set it to 0 for the
+ // data comparison check. (It is set to 0 in the buffer containing
+ // the expected data.)
+ qid_0 = receive_buffer_[0];
+ qid_1 = receive_buffer_[1];
+ receive_buffer_[0] = receive_buffer_[1] = 0;
+
+ // Check that length of the received data and the expected data are
+ // identical, then check that the data is identical as well.
+ EXPECT_EQ(msgbuf_->getLength(), length);
+ EXPECT_TRUE(equal(receive_buffer_, (receive_buffer_ + length - 1),
+ static_cast<const uint8_t*>(msgbuf_->getData())));
+
+ // Return a message back to the IOFetch object.
+ if (!bad_qid) {
+ expected_buffer_->writeUint8At(qid_0, 0);
+ expected_buffer_->writeUint8At(qid_1, 1);
+ } else {
+ expected_buffer_->writeUint8At(qid_0 + 1, 0);
+ expected_buffer_->writeUint8At(qid_1 + 1, 1);
+ }
+ socket->send_to(asio::buffer(expected_buffer_->getData(), length), *remote);
+
+ if (bad_qid && second_send) {
+ expected_buffer_->writeUint8At(qid_0, 0);
+ expected_buffer_->writeUint8At(qid_1, 1);
+ socket->send_to(asio::buffer(expected_buffer_->getData(),
+ expected_buffer_->getLength()), *remote);
+ }
+ if (debug_) {
+ cout << "udpReceiveHandler(): returned " << expected_buffer_->getLength() <<
+ " bytes to the client" << endl;
+ }
+ }
+
+ /// \brief Completion Handler for accepting TCP data
+ ///
+ /// Called when the remote system connects to the "server". It issues
+ /// an asynchronous read on the socket to read data.
+ ///
+ /// \param socket Socket on which data will be received
+ /// \param ec Boost error code, value should be zero.
+ void tcpAcceptHandler(tcp::socket* socket, error_code ec = error_code())
+ {
+ if (debug_) {
+ cout << "tcpAcceptHandler(): error = " << ec.value() << endl;
+ }
+
+ // Expect that the accept completed without a problem.
+ EXPECT_EQ(0, ec.value());
+
+ // Work out the maximum size of data we can send over it when we
+ // respond, then subtract 1kB or so for safety.
+ tcp::socket::send_buffer_size send_size;
+ socket->get_option(send_size);
+ if (send_size.value() < (2 * 1024)) {
+ FAIL() << "TCP send size is less than 2kB";
+ } else {
+ tcp_send_size_ = send_size.value() - 1024;
+ if (debug_) {
+ cout << "tcpacceptHandler(): will use send size = " << tcp_send_size_ << endl;
+ }
+ }
+
+ // Initiate a read on the socket.
+ cumulative_ = 0;
+ socket->async_receive(asio::buffer(receive_buffer_, sizeof(receive_buffer_)),
+ boost::bind(&IOFetchTest::tcpReceiveHandler, this, socket, _1, _2));
+ }
+
+ /// \brief Completion handler for receiving TCP data
+ ///
+ /// When IOFetch is sending data, this response handler emulates the remote
+ /// DNS server. It that all the data sent by the IOFetch object has been
+ /// received, issuing another read if not. If the data is complete, it is
+ /// compared to what is expected and a reply sent back to the IOFetch.
+ ///
+ /// \param socket Socket to use to send the answer
+ /// \param ec ASIO error code, completion code of asynchronous I/O issued
+ /// by the "server" to receive data.
+ /// \param length Amount of data received.
+ void tcpReceiveHandler(tcp::socket* socket, error_code ec = error_code(),
+ size_t length = 0)
+ {
+ if (debug_) {
+ cout << "tcpReceiveHandler(): error = " << ec.value() <<
+ ", length = " << length << endl;
+ }
+ // Expect that the receive completed without a problem.
+ EXPECT_EQ(0, ec.value());
+
+ // If we haven't received all the data, issue another read.
+ cumulative_ += length;
+ bool complete = false;
+ if (cumulative_ > 2) {
+ uint16_t dns_length = readUint16(receive_buffer_);
+ complete = ((dns_length + 2) == cumulative_);
+ }
+
+ if (!complete) {
+ socket->async_receive(asio::buffer((receive_buffer_ + cumulative_),
+ (sizeof(receive_buffer_) - cumulative_)),
+ boost::bind(&IOFetchTest::tcpReceiveHandler, this, socket, _1, _2));
+ return;
+ }
+
+ // Check that length of the DNS message received is that expected, then
+ // compare buffers, zeroing the QID in the received buffer to match
+ // that set in our expected question. Note that due to the length
+ // field the QID in the received buffer is in the third and fourth
+ // bytes.
+ EXPECT_EQ(msgbuf_->getLength() + 2, cumulative_);
+ qid_0 = receive_buffer_[2];
+ qid_1 = receive_buffer_[3];
+
+ receive_buffer_[2] = receive_buffer_[3] = 0;
+ EXPECT_TRUE(equal((receive_buffer_ + 2), (receive_buffer_ + cumulative_ - 2),
+ static_cast<const uint8_t*>(msgbuf_->getData())));
+
+ // ... and return a message back. This has to be preceded by a two-byte
+ // count field.
+
+ send_buffer_.clear();
+ send_buffer_.push_back(0);
+ send_buffer_.push_back(0);
+ writeUint16(return_data_.size(), &send_buffer_[0]);
+ copy(return_data_.begin(), return_data_.end(), back_inserter(send_buffer_));
+ if (return_data_.size() >= 2) {
+ send_buffer_[2] = qid_0;
+ send_buffer_[3] = qid_1;
+ }
+ // Send the data. This is done in multiple writes with a delay between
+ // each to check that the reassembly of TCP packets from fragments works.
+ send_cumulative_ = 0;
+ tcpSendData(socket);
+ }
+
+ /// \brief Sent Data Over TCP
+ ///
+ /// Send the TCP data back to the IOFetch object. The data is sent in
+ /// three chunks - two of 16 bytes and the remainder, with a 250ms gap
+ /// between each. (Amounts of data smaller than one 32 bytes are sent in
+ /// one or two packets.)
+ ///
+ /// \param socket Socket over which send should take place
+ void tcpSendData(tcp::socket* socket) {
+ if (debug_) {
+ cout << "tcpSendData()" << endl;
+ }
+
+ // Decide what to send based on the cumulative count. At most we'll do
+ // two chunks of 16 bytes (with a 250ms gap between) and then the
+ // remainder.
+ uint8_t* send_ptr = &send_buffer_[send_cumulative_];
+ // Pointer to data to send
+ size_t amount = 16; // Amount of data to send
+ if (send_cumulative_ < (2 * amount)) {
+
+ // First or second time through, send at most 16 bytes
+ amount = min(amount, (send_buffer_.size() - send_cumulative_));
+
+ } else {
+
+ // For all subsequent times, send the remainder, maximised to
+ // whatever we have chosen for the maximum send size.
+ amount = min(tcp_send_size_,
+ (send_buffer_.size() - send_cumulative_));
+ }
+
+ // This is for the short send test; reduce the actual amount of
+ // data we send
+ if (tcp_short_send_) {
+ if (debug_) {
+ cout << "tcpSendData(): sending incomplete data (" <<
+ (amount - 1) << " of " << amount << " bytes)" <<
+ endl;
+ }
+ --amount;
+ } else {
+ if (debug_) {
+ cout << "tcpSendData(): sending " << amount << " bytes" << endl;
+ }
+ }
+
+ // ... and send it. The amount sent is also passed as the first
+ // argument of the send callback, as a check.
+ socket->async_send(asio::buffer(send_ptr, amount),
+ boost::bind(&IOFetchTest::tcpSendHandler, this,
+ amount, socket, _1, _2));
+ }
+
+ /// \brief Completion Handler for Sending TCP data
+ ///
+ /// Called when the asynchronous send of data back to the IOFetch object
+ /// by the TCP "server" in this class has completed. (This send has to
+ /// be asynchronous because control needs to return to the caller in order
+ /// for the IOService "run()" method to be called to run the handlers.)
+ ///
+ /// If not all the data has been sent, a short delay is instigated (during
+ /// which control returns to the IOService). This should force the queued
+ /// data to actually be sent and the IOFetch receive handler to be triggered.
+ /// In this way, the ability of IOFetch to handle fragmented TCP packets
+ /// should be checked.
+ ///
+ /// \param expected Number of bytes that were expected to have been sent.
+ /// \param socket Socket over which the send took place. Only used to
+ /// pass back to the send method.
+ /// \param ec Boost error code, value should be zero.
+ /// \param length Number of bytes sent.
+ void tcpSendHandler(size_t expected, tcp::socket* socket,
+ error_code ec = error_code(), size_t length = 0)
+ {
+ if (debug_) {
+ cout << "tcpSendHandler(): error = " << ec.value() <<
+ ", length = " << length << endl;
+ }
+
+ EXPECT_EQ(0, ec.value()); // Expect no error
+ EXPECT_EQ(expected, length); // And that amount sent is as expected
+
+ // Do we need to send more?
+ send_cumulative_ += length;
+ if (send_cumulative_ < send_buffer_.size()) {
+
+ // Yes - set up a timer: the callback handler for the timer is
+ // tcpSendData, which will then send the next chunk. We pass the
+ // socket over which data should be sent as an argument to that
+ // function.
+ timer_.expires_from_now(boost::posix_time::milliseconds(SEND_INTERVAL));
+ timer_.async_wait(boost::bind(&IOFetchTest::tcpSendData, this,
+ socket));
+ }
+ }
+
+ /// \brief Fetch completion callback
+ ///
+ /// This is the callback's operator() method which is called when the fetch
+ /// is complete. It checks that the data received is the wire format of the
+ /// data sent back by the server.
+ ///
+ /// \param result Result indicated by the callback
+ void operator()(IOFetch::Result result) {
+ if (debug_) {
+ cout << "operator()(): result = " << result << endl;
+ }
+
+ EXPECT_EQ(expected_, result); // Check correct result returned
+ EXPECT_FALSE(run_); // Check it is run only once
+ run_ = true; // Note success
+
+ // If the expected result for SUCCESS, then this should have been called
+ // when one of the "servers" in this class has sent back return_data_.
+ // Check the data is as expected/
+ if (expected_ == IOFetch::SUCCESS) {
+ // In the case of UDP, we actually send back a real looking packet
+ // in the case of TCP, we send back a 'random' string
+ if (protocol_ == IOFetch::UDP) {
+ EXPECT_EQ(expected_buffer_->getLength(), result_buff_->getLength());
+ EXPECT_EQ(0, memcmp(expected_buffer_->getData(), result_buff_->getData(),
+ expected_buffer_->getLength()));
+ } else {
+ EXPECT_EQ(return_data_.size(), result_buff_->getLength());
+ // Overwrite the random qid with our own data for the
+ // comparison to succeed
+ if (result_buff_->getLength() >= 2) {
+ result_buff_->writeUint8At(return_data_[0], 0);
+ result_buff_->writeUint8At(return_data_[1], 1);
+ }
+ const uint8_t* start = static_cast<const uint8_t*>(result_buff_->getData());
+ EXPECT_TRUE(equal(return_data_.begin(), return_data_.end(), start));
+ }
+ }
+
+ // ... and cause the run loop to exit.
+ service_.stop();
+ }
+
+ // The next set of methods are the tests themselves. A number of the TCP
+ // and UDP tests are very similar.
+
+ /// \brief Check for stop()
+ ///
+ /// Test that when we run the query and stop it after it was run, it returns
+ /// "stopped" correctly. (That is why stop() is posted to the service_ as
+ /// well instead of calling it.)
+ ///
+ /// \param protocol Test protocol
+ /// \param fetch Fetch object being tested
+ void stopTest(IOFetch::Protocol protocol, IOFetch& fetch) {
+ protocol_ = protocol;
+ expected_ = IOFetch::STOPPED;
+
+ // Post the query
+ service_.get_io_service().post(fetch);
+
+ // Post query_.stop() (yes, the boost::bind thing is just
+ // query_.stop()).
+ service_.get_io_service().post(
+ boost::bind(&IOFetch::stop, fetch, IOFetch::STOPPED));
+
+ // Run both of them. run() returns when everything in the I/O service
+ // queue has completed.
+ service_.run();
+ EXPECT_TRUE(run_);
+ }
+
+ /// \brief Premature stop test
+ ///
+ /// Test that when we queue the query to service_ and call stop() before it
+ /// gets executed, it acts sanely as well (eg. has the same result as
+ /// running stop() after - calls the callback).
+ ///
+ /// \param protocol Test protocol
+ /// \param fetch Fetch object being tested
+ void prematureStopTest(IOFetch::Protocol protocol, IOFetch& fetch) {
+ protocol_ = protocol;
+ expected_ = IOFetch::STOPPED;
+
+ // Stop before it is started
+ fetch.stop();
+ service_.get_io_service().post(fetch);
+
+ service_.run();
+ EXPECT_TRUE(run_);
+ }
+
+ /// \brief Timeout test
+ ///
+ /// Test that fetch times out when no answer arrives.
+ ///
+ /// \param protocol Test protocol
+ /// \param fetch Fetch object being tested
+ void timeoutTest(IOFetch::Protocol protocol, IOFetch& fetch) {
+ protocol_ = protocol;
+ expected_ = IOFetch::TIME_OUT;
+
+ service_.get_io_service().post(fetch);
+ service_.run();
+ EXPECT_TRUE(run_);
+ }
+
+ /// \brief Send/Receive Test
+ ///
+ /// Send a query to the server then receives a response.
+ ///
+ /// \param Test data to return to client
+ /// \param short_send If true, do not send all data
+ /// (should result in timeout)
+ void tcpSendReturnTest(const std::string& return_data, bool short_send = false) {
+ if (debug_) {
+ cout << "tcpSendReturnTest(): data size = " << return_data.size() << endl;
+ }
+ return_data_ = return_data;
+ protocol_ = IOFetch::TCP;
+ if (short_send) {
+ tcp_short_send_ = true;
+ expected_ = IOFetch::TIME_OUT;
+ } else {
+ expected_ = IOFetch::SUCCESS;
+ }
+
+ // Socket into which the connection will be accepted.
+ tcp::socket socket(service_.get_io_service());
+
+ // Acceptor object - called when the connection is made, the handler
+ // will initiate a read on the socket.
+ tcp::acceptor acceptor(service_.get_io_service(),
+ tcp::endpoint(tcp::v4(), TEST_PORT));
+ acceptor.async_accept(socket,
+ boost::bind(&IOFetchTest::tcpAcceptHandler, this, &socket, _1));
+
+ // Post the TCP fetch object to send the query and receive the response.
+ service_.get_io_service().post(tcp_fetch_);
+
+ // ... and execute all the callbacks. This exits when the fetch
+ // completes.
+ service_.run();
+ EXPECT_TRUE(run_); // Make sure the callback did execute
+
+ // Tidy up
+ socket.close();
+ }
+
+ /// Perform a send/receive test over UDP
+ ///
+ /// \param bad_qid If true, do the test where the QID is mangled
+ /// in the response
+ /// \param second_send If true, do the test where the QID is
+ /// mangled in the response, but a second
+ /// (correct) packet is used
+ void udpSendReturnTest(bool bad_qid, bool second_send) {
+ protocol_ = IOFetch::UDP;
+
+ // Set up the server.
+ udp::socket socket(service_.get_io_service(), udp::v4());
+ socket.set_option(socket_base::reuse_address(true));
+ socket.bind(udp::endpoint(TEST_HOST, TEST_PORT));
+ 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));
+ service_.get_io_service().post(udp_fetch_);
+ if (debug_) {
+ cout << "udpSendReceive: async_receive_from posted, waiting for callback" <<
+ endl;
+ }
+ service_.run();
+
+ socket.close();
+
+ EXPECT_TRUE(run_);;
+ }
+};
+
+// Check the protocol
+TEST_F(IOFetchTest, Protocol) {
+ EXPECT_EQ(IOFetch::UDP, udp_fetch_.getProtocol());
+ EXPECT_EQ(IOFetch::TCP, tcp_fetch_.getProtocol());
+}
+
+// UDP Stop test - see IOFetchTest::stopTest() header.
+TEST_F(IOFetchTest, UdpStop) {
+ stopTest(IOFetch::UDP, udp_fetch_);
+}
+
+// UDP premature stop test - see IOFetchTest::prematureStopTest() header.
+TEST_F(IOFetchTest, UdpPrematureStop) {
+ prematureStopTest(IOFetch::UDP, udp_fetch_);
+}
+
+// UDP premature stop test - see IOFetchTest::timeoutTest() header.
+TEST_F(IOFetchTest, UdpTimeout) {
+ timeoutTest(IOFetch::UDP, udp_fetch_);
+}
+
+// UDP SendReceive test. Set up a UDP server then ports a UDP fetch object.
+// This will send question_ to the server and receive the answer back from it.
+TEST_F(IOFetchTest, UdpSendReceive) {
+ expected_ = IOFetch::SUCCESS;
+
+ udpSendReturnTest(false, false);
+
+ EXPECT_TRUE(run_);;
+}
+
+TEST_F(IOFetchTest, UdpSendReceiveBadQid) {
+ expected_ = IOFetch::TIME_OUT;
+
+ udpSendReturnTest(true, false);
+
+ EXPECT_TRUE(run_);;
+}
+
+TEST_F(IOFetchTest, UdpSendReceiveBadQidResend) {
+ expected_ = IOFetch::SUCCESS;
+
+ udpSendReturnTest(true, true);
+
+ EXPECT_TRUE(run_);;
+}
+
+// Do the same tests for TCP transport
+
+TEST_F(IOFetchTest, TcpStop) {
+ stopTest(IOFetch::TCP, tcp_fetch_);
+}
+
+TEST_F(IOFetchTest, TcpPrematureStop) {
+ prematureStopTest(IOFetch::TCP, tcp_fetch_);
+}
+
+TEST_F(IOFetchTest, TcpTimeout) {
+ timeoutTest(IOFetch::TCP, tcp_fetch_);
+}
+
+// Test with values at or near 2, then at or near the chunk size (16 and 32
+// bytes, the sizes of the first two packets) then up to 65535. These are done
+// in separate tests because in practice a new IOFetch is created for each
+// query/response exchange and we don't want to confuse matters in the test
+// by running the test with an IOFetch that has already done one exchange.
+//
+// Don't do 0 or 1; the server would not accept the packet
+// (since the length is too short to check the qid)
+TEST_F(IOFetchTest, TcpSendReceive2) {
+ tcpSendReturnTest(test_data_.substr(0, 2));
+}
+
+TEST_F(IOFetchTest, TcpSendReceive3) {
+ tcpSendReturnTest(test_data_.substr(0, 3));
+}
+
+TEST_F(IOFetchTest, TcpSendReceive15) {
+ tcpSendReturnTest(test_data_.substr(0, 15));
+}
+
+TEST_F(IOFetchTest, TcpSendReceive16) {
+ tcpSendReturnTest(test_data_.substr(0, 16));
+}
+
+TEST_F(IOFetchTest, TcpSendReceive17) {
+ tcpSendReturnTest(test_data_.substr(0, 17));
+}
+
+TEST_F(IOFetchTest, TcpSendReceive31) {
+ tcpSendReturnTest(test_data_.substr(0, 31));
+}
+
+TEST_F(IOFetchTest, TcpSendReceive32) {
+ tcpSendReturnTest(test_data_.substr(0, 32));
+}
+
+TEST_F(IOFetchTest, TcpSendReceive33) {
+ tcpSendReturnTest(test_data_.substr(0, 33));
+}
+
+TEST_F(IOFetchTest, TcpSendReceive4096) {
+ tcpSendReturnTest(test_data_.substr(0, 4096));
+}
+
+TEST_F(IOFetchTest, TcpSendReceive8192) {
+ tcpSendReturnTest(test_data_.substr(0, 8192));
+}
+
+TEST_F(IOFetchTest, TcpSendReceive16384) {
+ tcpSendReturnTest(test_data_.substr(0, 16384));
+}
+
+TEST_F(IOFetchTest, TcpSendReceive32768) {
+ tcpSendReturnTest(test_data_.substr(0, 32768));
+}
+
+TEST_F(IOFetchTest, TcpSendReceive65535) {
+ tcpSendReturnTest(test_data_.substr(0, 65535));
+}
+
+TEST_F(IOFetchTest, TcpSendReceive2ShortSend) {
+ tcpSendReturnTest(test_data_.substr(0, 2), true);
+}
+
+TEST_F(IOFetchTest, TcpSendReceive15ShortSend) {
+ tcpSendReturnTest(test_data_.substr(0, 15), true);
+}
+
+TEST_F(IOFetchTest, TcpSendReceive8192ShortSend) {
+ tcpSendReturnTest(test_data_.substr(0, 8192), true);
+}
+
+
+} // namespace asiodns
+} // namespace isc
diff --git a/src/lib/asiodns/tests/io_service_unittest.cc b/src/lib/asiodns/tests/io_service_unittest.cc
new file mode 100644
index 0000000..cc64022
--- /dev/null
+++ b/src/lib/asiodns/tests/io_service_unittest.cc
@@ -0,0 +1,118 @@
+// Copyright (C) 2011 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 <gtest/gtest.h>
+
+#include <asio.hpp>
+#include <asiolink/asiolink.h>
+#include <asiodns/asiodns.h>
+
+using namespace isc::asiolink;
+using namespace isc::asiodns;
+
+const char* const TEST_SERVER_PORT = "53535";
+const char* const TEST_CLIENT_PORT = "53536";
+const char* const TEST_IPV6_ADDR = "::1";
+const char* const TEST_IPV4_ADDR = "127.0.0.1";
+
+TEST(IOServiceTest, badPort) {
+ IOService io_service;
+ EXPECT_THROW(DNSService(io_service, *"65536", true, false, NULL, NULL, NULL), IOError);
+ EXPECT_THROW(DNSService(io_service, *"53210.0", true, false, NULL, NULL, NULL), IOError);
+ EXPECT_THROW(DNSService(io_service, *"-1", true, false, NULL, NULL, NULL), IOError);
+ EXPECT_THROW(DNSService(io_service, *"domain", true, false, NULL, NULL, NULL), IOError);
+}
+
+TEST(IOServiceTest, badAddress) {
+ IOService io_service;
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"192.0.2.1.1", NULL, NULL, NULL), IOError);
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"2001:db8:::1", NULL, NULL, NULL), IOError);
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"localhost", NULL, NULL, NULL), IOError);
+}
+
+TEST(IOServiceTest, unavailableAddress) {
+ IOService io_service;
+ // These addresses should generally be unavailable as a valid local
+ // address, although there's no guarantee in theory.
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"192.0.2.0", NULL, NULL, NULL), IOError);
+
+ // Some OSes would simply reject binding attempt for an AF_INET6 socket
+ // to an IPv4-mapped IPv6 address. Even if those that allow it, since
+ // the corresponding IPv4 address is the same as the one used in the
+ // AF_INET socket case above, it should at least show the same result
+ // as the previous one.
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"::ffff:192.0.2.0", NULL, NULL, NULL), IOError);
+}
+
+TEST(IOServiceTest, duplicateBind_v6) {
+ // In each sub test case, second attempt should fail due to duplicate bind
+ IOService io_service;
+
+ // IPv6, "any" address
+ DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, false, true, NULL, NULL, NULL);
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, false, true, NULL, NULL, NULL), IOError);
+ delete dns_service;
+
+}
+
+TEST(IOServiceTest, duplicateBind_v6_address) {
+ // In each sub test case, second attempt should fail due to duplicate bind
+ IOService io_service;
+
+ // IPv6, specific address
+ DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, *TEST_IPV6_ADDR, NULL, NULL, NULL);
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *TEST_IPV6_ADDR, NULL, NULL, NULL), IOError);
+ delete dns_service;
+
+}
+
+TEST(IOServiceTest, duplicateBind_v4) {
+ // In each sub test case, second attempt should fail due to duplicate bind
+ IOService io_service;
+
+ // IPv4, "any" address
+ DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, true, false, NULL, NULL, NULL);
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, true, false, NULL, NULL, NULL), IOError);
+ delete dns_service;
+
+}
+
+TEST(IOServiceTest, duplicateBind_v4_address) {
+ // In each sub test case, second attempt should fail due to duplicate bind
+ IOService io_service;
+
+ // IPv4, specific address
+ DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, *TEST_IPV4_ADDR, NULL, NULL, NULL);
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *TEST_IPV4_ADDR, NULL, NULL, NULL), IOError);
+ delete dns_service;
+}
+
+// Disabled because IPv4-mapped addresses don't seem to be working with
+// the IOService constructor
+TEST(IOServiceTest, DISABLED_IPv4MappedDuplicateBind) {
+ IOService io_service;
+ // Duplicate bind on IPv4-mapped IPv6 address
+ DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, *"127.0.0.1", NULL, NULL, NULL);
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"::ffff:127.0.0.1", NULL, NULL, NULL), IOError);
+ delete dns_service;
+
+ // XXX:
+ // Currently, this throws an "invalid argument" exception. I have
+ // not been able to get IPv4-mapped addresses to work.
+ dns_service = new DNSService(io_service, *TEST_SERVER_PORT, *"::ffff:127.0.0.1", NULL, NULL, NULL);
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"127.0.0.1", NULL, NULL, NULL), IOError);
+ delete dns_service;
+}
+
diff --git a/src/lib/asiodns/tests/run_unittests.cc b/src/lib/asiodns/tests/run_unittests.cc
new file mode 100644
index 0000000..c285f9e
--- /dev/null
+++ b/src/lib/asiodns/tests/run_unittests.cc
@@ -0,0 +1,28 @@
+// Copyright (C) 2009 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 <gtest/gtest.h>
+
+#include <log/root_logger_name.h>
+#include <dns/tests/unittest_util.h>
+
+int
+main(int argc, char* argv[])
+{
+ ::testing::InitGoogleTest(&argc, argv); // Initialize Google test
+ isc::log::setRootLoggerName("unittest"); // Set a root logger name
+ isc::UnitTestUtil::addDataPath(TEST_DATA_DIR); // Add location of test data
+
+ return (RUN_ALL_TESTS());
+}
diff --git a/src/lib/asiodns/udp_server.cc b/src/lib/asiodns/udp_server.cc
new file mode 100644
index 0000000..f103e5a
--- /dev/null
+++ b/src/lib/asiodns/udp_server.cc
@@ -0,0 +1,325 @@
+// Copyright (C) 2011 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 <netinet/in.h>
+#include <sys/socket.h>
+#include <unistd.h> // for some IPC/network system calls
+#include <errno.h>
+
+#include <boost/shared_array.hpp>
+
+#include <config.h>
+
+#include <log/dummylog.h>
+
+#include <asio.hpp>
+#include <asio/error.hpp>
+#include <asiolink/dummy_io_cb.h>
+#include <asiolink/udp_endpoint.h>
+#include <asiolink/udp_socket.h>
+#include "udp_server.h"
+
+#include <dns/opcode.h>
+
+using namespace asio;
+using asio::ip::udp;
+using isc::log::dlog;
+
+using namespace std;
+using namespace isc::dns;
+using namespace isc::util;
+using namespace isc::asiolink;
+
+namespace isc {
+namespace asiodns {
+
+/*
+ * Some of the member variables here are shared_ptrs and some are
+ * auto_ptrs. There will be one instance of Data for the lifetime
+ * of packet. The variables that are state only for a single packet
+ * use auto_ptr, as it is more lightweight. In the case of shared
+ * configuration (eg. the callbacks, socket), we use shared_ptrs.
+ */
+struct UDPServer::Data {
+ /*
+ * Constructor from parameters passed to UDPServer constructor.
+ * This instance will not be used to retrieve and answer the actual
+ * query, it will only hold parameters until we wait for the
+ * first packet. But we do initialize the socket in here.
+ */
+ Data(io_service& io_service, const ip::address& addr, const uint16_t port,
+ SimpleCallback* checkin, DNSLookup* lookup, DNSAnswer* answer) :
+ io_(io_service), done_(false),
+ checkin_callback_(checkin),lookup_callback_(lookup),
+ answer_callback_(answer)
+ {
+ // We must use different instantiations for v4 and v6;
+ // otherwise ASIO will bind to both
+ udp proto = addr.is_v4() ? udp::v4() : udp::v6();
+ socket_.reset(new udp::socket(io_service, proto));
+ socket_->set_option(socket_base::reuse_address(true));
+ if (addr.is_v6()) {
+ socket_->set_option(asio::ip::v6_only(true));
+ }
+ socket_->bind(udp::endpoint(addr, port));
+ }
+
+ /*
+ * Copy constructor. Default one would probably do, but it is unnecessary
+ * to copy many of the member variables every time we fork to handle
+ * another packet.
+ *
+ * We also allocate data for receiving the packet here.
+ */
+ Data(const Data& other) :
+ io_(other.io_), socket_(other.socket_), done_(false),
+ checkin_callback_(other.checkin_callback_),
+ lookup_callback_(other.lookup_callback_),
+ answer_callback_(other.answer_callback_)
+ {
+ // Instantiate the data buffer and endpoint that will
+ // be used by the asynchronous receive call.
+ data_.reset(new char[MAX_LENGTH]);
+ sender_.reset(new udp::endpoint());
+ }
+
+ // The ASIO service object
+ asio::io_service& io_;
+
+ // Class member variables which are dynamic, and changes to which
+ // need to accessible from both sides of a coroutine fork or from
+ // outside of the coroutine (i.e., from an asynchronous I/O call),
+ // should be declared here as pointers and allocated in the
+ // constructor or in the coroutine. This allows state information
+ // to persist when an individual copy of the coroutine falls out
+ // scope while waiting for an event, *so long as* there is another
+ // object that is referencing the same data. As a side-benefit, using
+ // pointers also reduces copy overhead for coroutine objects.
+ //
+ // Note: Currently these objects are allocated by "new" in the
+ // constructor, or in the function operator while processing a query.
+ // Repeated allocations from the heap for every incoming query is
+ // clearly a performance issue; this must be optimized in the future.
+ // The plan is to have a structure pre-allocate several "Data"
+ // objects which can be pulled off a free list and placed on an in-use
+ // list whenever a query comes in. This will serve the dual purpose
+ // of improving performance and guaranteeing that state information
+ // will *not* be destroyed when any one instance of the coroutine
+ // falls out of scope while waiting for an event.
+ //
+ // Socket used to for listen for queries. Created in the
+ // constructor and stored in a shared_ptr because socket objects
+ // are not copyable.
+ boost::shared_ptr<asio::ip::udp::socket> socket_;
+
+ // The ASIO-internal endpoint object representing the client
+ std::auto_ptr<asio::ip::udp::endpoint> sender_;
+
+ // \c IOMessage and \c Message objects to be passed to the
+ // DNS lookup and answer providers
+ std::auto_ptr<asiolink::IOMessage> io_message_;
+
+ // The original query as sent by the client
+ isc::dns::MessagePtr query_message_;
+
+ // The response message we are building
+ isc::dns::MessagePtr answer_message_;
+
+ // The buffer into which the response is written
+ isc::util::OutputBufferPtr respbuf_;
+
+ // The buffer into which the query packet is written
+ boost::shared_array<char> data_;
+
+ // State information that is entirely internal to a given instance
+ // of the coroutine can be declared here.
+ size_t bytes_;
+ bool done_;
+
+
+ // Callback functions provided by the caller
+ const SimpleCallback* checkin_callback_;
+ const DNSLookup* lookup_callback_;
+ const DNSAnswer* answer_callback_;
+
+ std::auto_ptr<IOEndpoint> peer_;
+ std::auto_ptr<IOSocket> iosock_;
+};
+
+/// The following functions implement the \c UDPServer class.
+///
+/// The constructor. It just creates new internal state object
+/// and lets it handle the initialization.
+UDPServer::UDPServer(io_service& io_service, const ip::address& addr,
+ const uint16_t port, SimpleCallback* checkin, DNSLookup* lookup,
+ DNSAnswer* answer) :
+ data_(new Data(io_service, addr, port, checkin, lookup, answer))
+{ }
+
+/// The function operator is implemented with the "stackless coroutine"
+/// pattern; see internal/coroutine.h for details.
+void
+UDPServer::operator()(error_code ec, size_t length) {
+ /// Because the coroutine reentry block is implemented as
+ /// a switch statement, inline variable declarations are not
+ /// permitted. Certain variables used below can be declared here.
+
+ CORO_REENTER (this) {
+ do {
+ /*
+ * This is preparation for receiving a packet. We get a new
+ * state object for the lifetime of the next packet to come.
+ * It allocates the buffers to receive data into.
+ */
+ data_.reset(new Data(*data_));
+
+ do {
+ // Begin an asynchronous receive, then yield.
+ // When the receive event is posted, the coroutine
+ // will resume immediately after this point.
+ CORO_YIELD data_->socket_->async_receive_from(
+ buffer(data_->data_.get(), MAX_LENGTH), *data_->sender_,
+ *this);
+
+ // Abort on fatal errors
+ // TODO: add log
+ if (ec) {
+ using namespace asio::error;
+ if (ec.value() != would_block && ec.value() != try_again &&
+ ec.value() != interrupted) {
+ return;
+ }
+ }
+
+ } while (ec || length == 0);
+
+ data_->bytes_ = length;
+
+ /*
+ * We fork the coroutine now. One (the child) will keep
+ * the current state and handle the packet, then die and
+ * drop ownership of the state. The other (parent) will just
+ * go into the loop again and replace the current state with
+ * a new one for a new object.
+ *
+ * Actually, both of the coroutines will be a copy of this
+ * one, but that's just internal implementation detail.
+ */
+ CORO_FORK data_->io_.post(UDPServer(*this));
+ } while (is_parent());
+
+ // Create an \c IOMessage object to store the query.
+ //
+ // (XXX: It would be good to write a factory function
+ // that would quickly generate an IOMessage object without
+ // all these calls to "new".)
+ data_->peer_.reset(new UDPEndpoint(*data_->sender_));
+
+ // 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.
+ data_->iosock_.reset(
+ new UDPSocket<DummyIOCallback>(*data_->socket_));
+
+ data_->io_message_.reset(new IOMessage(data_->data_.get(),
+ data_->bytes_, *data_->iosock_, *data_->peer_));
+
+ // Perform any necessary operations prior to processing an incoming
+ // query (e.g., checking for queued configuration messages).
+ //
+ // (XXX: it may be a performance issue to check in for every single
+ // incoming query; we may wish to throttle this in the future.)
+ if (data_->checkin_callback_ != NULL) {
+ (*data_->checkin_callback_)(*data_->io_message_);
+ }
+
+ // If we don't have a DNS Lookup provider, there's no point in
+ // continuing; we exit the coroutine permanently.
+ if (data_->lookup_callback_ == NULL) {
+ CORO_YIELD return;
+ }
+
+ // Instantiate objects that will be needed by the
+ // asynchronous DNS lookup and/or by the send call.
+ data_->respbuf_.reset(new OutputBuffer(0));
+ data_->query_message_.reset(new Message(Message::PARSE));
+ data_->answer_message_.reset(new Message(Message::RENDER));
+
+ // Schedule a DNS lookup, and yield. When the lookup is
+ // finished, the coroutine will resume immediately after
+ // this point.
+ CORO_YIELD data_->io_.post(AsyncLookup<UDPServer>(*this));
+
+ // The 'done_' flag indicates whether we have an answer
+ // to send back. If not, exit the coroutine permanently.
+ if (!data_->done_) {
+ CORO_YIELD return;
+ }
+
+ // Call the DNS answer provider to render the answer into
+ // wire format
+ (*data_->answer_callback_)(*data_->io_message_, data_->query_message_,
+ data_->answer_message_, data_->respbuf_);
+
+ // Begin an asynchronous send, and then yield. When the
+ // send completes, we will resume immediately after this point
+ // (though we have nothing further to do, so the coroutine
+ // will simply exit at that time).
+ CORO_YIELD data_->socket_->async_send_to(
+ buffer(data_->respbuf_->getData(), data_->respbuf_->getLength()),
+ *data_->sender_, *this);
+ }
+}
+
+/// Call the DNS lookup provider. (Expected to be called by the
+/// AsyncLookup<UDPServer> handler.)
+void
+UDPServer::asyncLookup() {
+ (*data_->lookup_callback_)(*data_->io_message_,
+ data_->query_message_, data_->answer_message_, data_->respbuf_, this);
+}
+
+/// Stop the UDPServer
+void
+UDPServer::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
+ data_->socket_->close();
+}
+
+/// 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
+UDPServer::resume(const bool done) {
+ data_->done_ = 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
new file mode 100644
index 0000000..4c19544
--- /dev/null
+++ b/src/lib/asiodns/udp_server.h
@@ -0,0 +1,108 @@
+// Copyright (C) 2011 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 __UDP_SERVER_H
+#define __UDP_SERVER_H 1
+
+#ifndef ASIO_HPP
+#error "asio.hpp must be included before including this, see asiolink.h as to why"
+#endif
+
+#include <asiolink/simple_callback.h>
+#include <asiodns/dns_answer.h>
+#include <asiodns/dns_lookup.h>
+#include <asiodns/dns_server.h>
+
+#include <coroutine.h>
+
+namespace isc {
+namespace asiodns {
+
+//
+// Asynchronous UDP server coroutine
+//
+///
+/// \brief This class implements the coroutine to handle UDP
+/// DNS query event. As such, it is both a \c DNSServer and
+/// a \c coroutine
+///
+class UDPServer : public virtual DNSServer, public virtual coroutine {
+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 UDPServer(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 The function operator
+ void operator()(asio::error_code ec = asio::error_code(),
+ size_t length = 0);
+
+ /// \brief Calls the lookup callback
+ void asyncLookup();
+
+ /// \brief Stop the running server
+ /// \note once the server stopped, it can't restart
+ void stop();
+
+ /// \brief Resume operation
+ ///
+ /// \param done Set this to true if the lookup action is done and
+ /// 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
+ DNSServer* clone() {
+ UDPServer* s = new UDPServer(*this);
+ return (s);
+ }
+
+private:
+ enum { MAX_LENGTH = 4096 };
+
+ /**
+ * \brief Internal state and data.
+ *
+ * We use the pimple design pattern, but not because we need to hide
+ * internal data. This class and whole header is for private use anyway.
+ * It turned out that UDPServer is copied a lot, because it is a coroutine.
+ * This way the overhead of copying is lower, we copy only one shared
+ * pointer instead of about 10 of them.
+ */
+ class Data;
+ boost::shared_ptr<Data> data_;
+};
+
+} // namespace asiodns
+} // namespace isc
+#endif // __UDP_SERVER_H
diff --git a/src/lib/asiolink/Makefile.am b/src/lib/asiolink/Makefile.am
index f4a9028..66d5eda 100644
--- a/src/lib/asiolink/Makefile.am
+++ b/src/lib/asiolink/Makefile.am
@@ -13,31 +13,21 @@ CLEANFILES = *.gcno *.gcda
# which would make the build fail with -Werror (our default setting).
lib_LTLIBRARIES = libasiolink.la
libasiolink_la_SOURCES = asiolink.h
-libasiolink_la_SOURCES += asiodef.cc asiodef.h
-libasiolink_la_SOURCES += dns_answer.h
-libasiolink_la_SOURCES += dns_lookup.h
-libasiolink_la_SOURCES += dns_server.h
-libasiolink_la_SOURCES += dns_service.cc dns_service.h
libasiolink_la_SOURCES += dummy_io_cb.h
libasiolink_la_SOURCES += interval_timer.cc interval_timer.h
libasiolink_la_SOURCES += io_address.cc io_address.h
libasiolink_la_SOURCES += io_asio_socket.h
libasiolink_la_SOURCES += io_endpoint.cc io_endpoint.h
libasiolink_la_SOURCES += io_error.h
-libasiolink_la_SOURCES += io_fetch.cc io_fetch.h
libasiolink_la_SOURCES += io_message.h
libasiolink_la_SOURCES += io_service.h io_service.cc
libasiolink_la_SOURCES += io_socket.h io_socket.cc
libasiolink_la_SOURCES += simple_callback.h
libasiolink_la_SOURCES += tcp_endpoint.h
-libasiolink_la_SOURCES += tcp_server.cc tcp_server.h
libasiolink_la_SOURCES += tcp_socket.h
libasiolink_la_SOURCES += udp_endpoint.h
-libasiolink_la_SOURCES += udp_server.cc udp_server.h
libasiolink_la_SOURCES += udp_socket.h
-EXTRA_DIST = asiodef.msg
-
# Note: the ordering matters: -Wno-... must follow -Wextra (defined in
# B10_CXXFLAGS)
libasiolink_la_CXXFLAGS = $(AM_CXXFLAGS)
diff --git a/src/lib/asiolink/README b/src/lib/asiolink/README
index 6bd1a73..66091b1 100644
--- a/src/lib/asiolink/README
+++ b/src/lib/asiolink/README
@@ -16,167 +16,7 @@ including:
them in only one place allows us to relax strictness here, while
leaving it in place elsewhere.
-Currently, the asiolink library only supports DNS servers (i.e., b10-auth
-and b10-resolver). The plan is to make it more generic and allow it to
-support other modules as well.
-
Some of the classes defined here--for example, IOSocket, IOEndpoint,
and IOAddress--are to be used by BIND 10 modules as wrappers around
ASIO-specific classes.
-Other classes implement the DNS protocol on behalf of BIND 10 modules.
-
-These DNS server and client routines are written using the "stackless
-coroutine" pattern invented by Chris Kohlhoff and described at
-http://blog.think-async.com/2010/03/potted-guide-to-stackless-coroutines.html.
-This is intended to simplify development a bit, since it allows the
-routines to be written in a straightfowrard step-step-step fashion rather
-than as a complex chain of separate handler functions.
-
-Coroutine objects (i.e., UDPServer, TCPServer and IOFetch) are objects
-with reenterable operator() members. When an instance of one of these
-classes is called as a function, it resumes at the position where it left
-off. Thus, a UDPServer can issue an asynchronous I/O call and specify
-itself as the handler object; when the call completes, the UDPServer
-carries on at the same position. As a result, the code can look as
-if it were using synchronous, not asynchronous, I/O, providing some of
-the benefit of threading but with minimal switching overhead.
-
-So, in simplified form, the behavior of a DNS Server is:
-
- REENTER:
- while true:
- YIELD packet = read_packet
- FORK
- if not parent:
- break
-
- # This callback informs the caller that a packet has arrived, and
- # gives it a chance to update configuration, etc
- SimpleCallback(packet)
- YIELD answer = DNSLookup(packet, this)
- response = DNSAnswer(answer)
- YIELD send(response)
-
-At each "YIELD" point, the coroutine initiates an asynchronous operation,
-then pauses and turns over control to some other task on the ASIO service
-queue. When the operation completes, the coroutine resumes.
-
-DNSLookup, DNSAnswer and SimpleCallback define callback methods
-used by a DNS Server to communicate with the module that called it.
-They are abstract-only classes whose concrete implementations
-are supplied by the calling module.
-
-The DNSLookup callback always runs asynchronously. Concrete
-implementations must be sure to call the server's "resume" method when
-it is finished.
-
-In an authoritative server, the DNSLookup implementation would examine
-the query, look up the answer, then call "resume". (See the diagram
-in doc/auth_process.jpg.)
-
-In a recursive server, the DNSLookup impelemtation would initiate a
-DNSQuery, which in turn would be responsible for calling the server's
-"resume" method. (See the diagram in doc/recursive_process.jpg.)
-
-A DNSQuery object is intended to handle resolution of a query over
-the network when the local authoritative data sources or cache are not
-sufficient. The plan is that it will make use of subsidiary DNSFetch
-calls to get data from particular authoritative servers, and when it has
-gotten a complete answer, it calls "resume".
-
-In current form, however, DNSQuery is much simpler; it forwards queries
-to a single upstream resolver and passes the answers back to the client.
-It is constructed with the address of the forward server. Queries are
-initiated with the question to ask the forward server, a buffer into
-which to write the answer, and a pointer to the coroutine to be resumed
-when the answer has arrived. In simplified form, the DNSQuery routine is:
-
- REENTER:
- render the question into a wire-format query packet
- YIELD send(query)
- YIELD response = read_packet
- server->resume
-
-Currently, DNSQuery is only implemented for UDP queries. In future work
-it will be necessary to write code to fall back to TCP when circumstances
-require it.
-
-
-Upstream Fetches
-================
-Upstream fetches (queries by the resolver on behalf of a client) are made
-using a slightly-modified version of the pattern described above.
-
-Sockets
--------
-First, it will be useful to understand the class hierarchy used in the
-fetch logic:
-
- IOSocket
- |
- IOAsioSocket
- |
- +-----+-----+
- | |
-UDPSocket TCPSocket
-
-IOSocket is a wrapper class for a socket and is used by the authoritative
-server code. It is an abstract base class, providing little more that the ability to hold the socket and to return the protocol in use.
-
-Built on this is IOAsioSocket, which adds the open, close, asyncSend and
-asyncReceive methods. This is a template class, which takes as template
-argument the class of the object that will be used as the callback when the
-asynchronous operation completes. This object can be of any type, but must
-include an operator() method with the signature:
-
- operator()(asio::error_code ec, size_t length)
-
-... the two arguments being the status of the completed I/O operation and
-the number of bytes transferred. (In the case of the open method, the second
-argument will be zero.)
-
-Finally, the TCPSocket and UDPSocket classes provide the body of the
-asynchronous operations.
-
-Fetch Sequence
---------------
-The fetch is implemented by the IOFetch class, which takes as argument the
-protocol to use. The sequence is:
-
- REENTER:
- render the question into a wire-format query packet
- open() // Open socket and optionally connect
- if (! synchronous) {
- YIELD;
- }
- YIELD asyncSend(query) // Send query
- do {
- YIELD asyncReceive(response) // Read response
- } while (! complete(response))
- close() // Drop connection and close socket
- server->resume
-
-The open() method opens a socket for use. On TCP, it also makes a
-connection to the remote end. So under UDP the operation will complete
-immediately, but under TCP it could take a long time. One solution would be
-for the open operation to post an event to the I/O queue; then both cases
-could be regarded as being equivalent, with the completion being signalled
-by the posting of the completion event. However UDP is the most common case
-and that would involve extra overhead. So the open() returns a status
-indicating whether the operation completed asynchronously. If it did, the
-code yields back to the coroutine; if not the yield is bypassed.
-
-The asynchronous send is straightforward, invoking the underlying ASIO
-function. (Note that the address/port is supplied to both the open() and
-asyncSend() methods - it is used by the TCPSocket in open() and by the
-UDPSocket in asyncSend().)
-
-The asyncReceive() method issues an asynchronous read and waits for completion.
-The fetch object keeps track of the amount of data received so far and when
-the receive completes it calls a method on the socket to determine if the
-entire message has been received. (This will always be the case for UDP. On
-TCP though, the message is preceded by a count field as several reads may be
-required to read all the data.) The fetch loops until all the data is read.
-
-Finally, the socket is closed and the server called to resume operation.
diff --git a/src/lib/asiolink/asiodef.cc b/src/lib/asiolink/asiodef.cc
deleted file mode 100644
index 94c71b5..0000000
--- a/src/lib/asiolink/asiodef.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// File created from asiodef.msg on Mon Feb 28 17:15:30 2011
-
-#include <cstddef>
-#include <log/message_types.h>
-#include <log/message_initializer.h>
-
-namespace asiolink {
-
-extern const isc::log::MessageID ASIO_FETCHCOMP = "FETCHCOMP";
-extern const isc::log::MessageID ASIO_FETCHSTOP = "FETCHSTOP";
-extern const isc::log::MessageID ASIO_OPENSOCK = "OPENSOCK";
-extern const isc::log::MessageID ASIO_RECVSOCK = "RECVSOCK";
-extern const isc::log::MessageID ASIO_RECVTMO = "RECVTMO";
-extern const isc::log::MessageID ASIO_SENDSOCK = "SENDSOCK";
-extern const isc::log::MessageID ASIO_UNKORIGIN = "UNKORIGIN";
-extern const isc::log::MessageID ASIO_UNKRESULT = "UNKRESULT";
-
-} // namespace asiolink
-
-namespace {
-
-const char* values[] = {
- "FETCHCOMP", "upstream fetch to %s(%d) has now completed",
- "FETCHSTOP", "upstream fetch to %s(%d) has been stopped",
- "OPENSOCK", "error %d opening %s socket to %s(%d)",
- "RECVSOCK", "error %d reading %s data from %s(%d)",
- "RECVTMO", "receive timeout while waiting for data from %s(%d)",
- "SENDSOCK", "error %d sending data using %s to %s(%d)",
- "UNKORIGIN", "unknown origin for ASIO error code %d (protocol: %s, address %s)",
- "UNKRESULT", "unknown result (%d) when IOFetch::stop() was executed for I/O to %s(%d)",
- NULL
-};
-
-const isc::log::MessageInitializer initializer(values);
-
-} // Anonymous namespace
-
diff --git a/src/lib/asiolink/asiodef.h b/src/lib/asiolink/asiodef.h
deleted file mode 100644
index ba77817..0000000
--- a/src/lib/asiolink/asiodef.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// File created from asiodef.msg on Mon Feb 28 17:15:30 2011
-
-#ifndef __ASIODEF_H
-#define __ASIODEF_H
-
-#include <log/message_types.h>
-
-namespace asiolink {
-
-extern const isc::log::MessageID ASIO_FETCHCOMP;
-extern const isc::log::MessageID ASIO_FETCHSTOP;
-extern const isc::log::MessageID ASIO_OPENSOCK;
-extern const isc::log::MessageID ASIO_RECVSOCK;
-extern const isc::log::MessageID ASIO_RECVTMO;
-extern const isc::log::MessageID ASIO_SENDSOCK;
-extern const isc::log::MessageID ASIO_UNKORIGIN;
-extern const isc::log::MessageID ASIO_UNKRESULT;
-
-} // namespace asiolink
-
-#endif // __ASIODEF_H
diff --git a/src/lib/asiolink/asiodef.msg b/src/lib/asiolink/asiodef.msg
deleted file mode 100644
index 2fcadd1..0000000
--- a/src/lib/asiolink/asiodef.msg
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright (C) 2011 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.
-
-$PREFIX ASIO_
-$NAMESPACE asiolink
-
-FETCHCOMP upstream fetch to %s(%d) has now completed
-+ A debug message, this records the the upstream fetch (a query made by the
-+ resolver on behalf of its client) to the specified address has completed.
-
-FETCHSTOP upstream fetch to %s(%d) has been stopped
-+ An external component has requested the halting of an upstream fetch. This
-+ is an allowed operation, and the message should only appear if debug is
-+ enabled.
-
-OPENSOCK error %d opening %s socket to %s(%d)
-+ The asynchronous I/O code encountered an error when trying to open a socket
-+ of the specified protocol in order to send a message to the target address.
-+ The the number of the system error that cause the problem is given in the
-+ message.
-
-RECVSOCK error %d reading %s data from %s(%d)
-+ The asynchronous I/O code encountered an error when trying read data from
-+ the specified address on the given protocol. The the number of the system
-+ error that cause the problem is given in the message.
-
-SENDSOCK error %d sending data using %s to %s(%d)
-+ The asynchronous I/O code encountered an error when trying send data to
-+ the specified address on the given protocol. The the number of the system
-+ error that cause the problem is given in the message.
-
-RECVTMO receive timeout while waiting for data from %s(%d)
-+ An upstream fetch from the specified address timed out. This may happen for
-+ any number of reasons and is most probably a problem at the remote server
-+ or a problem on the network. The message will only appear if debug is
-+ enabled.
-
-UNKORIGIN unknown origin for ASIO error code %d (protocol: %s, address %s)
-+ This message should not appear and indicates an internal error if it does.
-+ Please enter a bug report.
-
-UNKRESULT unknown result (%d) when IOFetch::stop() was executed for I/O to %s(%d)
-+ The termination method of the resolver's upstream fetch class was called with
-+ an unknown result code (which is given in the message). This message should
-+ not appear and may indicate an internal error. Please enter a bug report.
diff --git a/src/lib/asiolink/asiolink.h b/src/lib/asiolink/asiolink.h
index 6e8fe84..51d3a14 100644
--- a/src/lib/asiolink/asiolink.h
+++ b/src/lib/asiolink/asiolink.h
@@ -20,10 +20,6 @@
// See the description of the namespace below.
#include <asiolink/io_service.h>
-#include <asiolink/dns_service.h>
-#include <asiolink/dns_server.h>
-#include <asiolink/dns_lookup.h>
-#include <asiolink/dns_answer.h>
#include <asiolink/simple_callback.h>
#include <asiolink/interval_timer.h>
@@ -62,11 +58,6 @@
/// this module. The resulting interfaces are thus straightforward mapping
/// to the ASIO counterparts.
///
-/// Notes to developers:
-/// Currently the wrapper interface is fairly specific to use by a
-/// DNS server, i.e., b10-auth or b10-resolver. But the plan is to
-/// generalize it and have other modules use it as well.
-///
/// One obvious drawback of this approach is performance overhead
/// due to the additional layer. We should eventually evaluate the cost
/// of the wrapper abstraction in benchmark tests. Another drawback is
diff --git a/src/lib/asiolink/dns_answer.h b/src/lib/asiolink/dns_answer.h
deleted file mode 100644
index e6e404d..0000000
--- a/src/lib/asiolink/dns_answer.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (C) 2011 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 __ASIOLINK_DNS_ANSWER_H
-#define __ASIOLINK_DNS_ANSWER_H 1
-
-#include <asiolink/io_message.h>
-
-namespace asiolink {
-
-/// \brief The \c DNSAnswer class is an abstract base class for a DNS
-/// Answer provider function.
-///
-/// Specific derived class implementations are hidden within the
-/// implementation. Instances of the derived classes can be called
-/// as functions via the operator() interface. Pointers to these
-/// instances can then be provided to the \c IOService class
-/// via its constructor.
-///
-/// A DNS Answer provider function takes answer data that has been obtained
-/// from a DNS Lookup provider functon and readies it to be sent to the
-/// client. After it has run, the OutputBuffer object passed to it should
-/// contain the answer to the query rendered into wire format.
-class DNSAnswer {
- ///
- /// \name Constructors and Destructor
- ///
- /// Note: The copy constructor and the assignment operator are
- /// intentionally defined as private, making this class non-copyable.
- //@{
-private:
- DNSAnswer(const DNSAnswer& source);
- DNSAnswer& operator=(const DNSAnswer& source);
-protected:
- /// \brief The default constructor.
- ///
- /// This is intentionally defined as \c protected as this base class
- /// should never be instantiated (except as part of a derived class).
- DNSAnswer() {}
-public:
- /// \brief The destructor
- virtual ~DNSAnswer() {}
- //@}
- /// \brief The function operator
- ///
- /// This makes its call indirectly via the "self" pointer, ensuring
- /// that the function ultimately invoked will be the one in the derived
- /// class.
- ///
- /// \param io_message The event message to handle
- /// \param query_message The DNS MessagePtr of the original query
- /// \param answer_message The DNS MessagePtr of the answer we are
- /// building
- /// \param buffer Intermediate data results are put here
- virtual void operator()(const IOMessage& io_message,
- isc::dns::MessagePtr query_message,
- isc::dns::MessagePtr answer_message,
- isc::util::OutputBufferPtr buffer) const = 0;
-};
-
-} // namespace asiolink
-#endif // __ASIOLINK_DNS_ANSWER_H
diff --git a/src/lib/asiolink/dns_lookup.h b/src/lib/asiolink/dns_lookup.h
deleted file mode 100644
index 2e87c4b..0000000
--- a/src/lib/asiolink/dns_lookup.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (C) 2011 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 __ASIOLINK_DNS_LOOKUP_H
-#define __ASIOLINK_DNS_LOOKUP_H 1
-
-#include <asiolink/io_message.h>
-#include <asiolink/dns_server.h>
-#include <util/buffer.h>
-#include <dns/message.h>
-
-namespace asiolink {
-
-/// \brief The \c DNSLookup class is an abstract base class for a DNS
-/// Lookup provider function.
-///
-/// Specific derived class implementations are hidden within the
-/// implementation. Instances of the derived classes can be called
-/// as functions via the operator() interface. Pointers to these
-/// instances can then be provided to the \c IOService class
-/// via its constructor.
-///
-/// A DNS Lookup provider function obtains the data needed to answer
-/// a DNS query (e.g., from authoritative data source, cache, or upstream
-/// query). After it has run, the OutputBuffer object passed to it
-/// should contain the answer to the query, in an internal representation.
-class DNSLookup {
- ///
- /// \name Constructors and Destructor
- ///
- /// Note: The copy constructor and the assignment operator are
- /// intentionally defined as private, making this class non-copyable.
- //@{
-private:
- DNSLookup(const DNSLookup& source);
- DNSLookup& operator=(const DNSLookup& source);
-protected:
- /// \brief The default constructor.
- ///
- /// This is intentionally defined as \c protected as this base class
- /// should never be instantiated (except as part of a derived class).
- DNSLookup() : self_(this) {}
-public:
- /// \brief The destructor
- virtual ~DNSLookup() {}
- //@}
- /// \brief The function operator
- ///
- /// This makes its call indirectly via the "self" pointer, ensuring
- /// that the function ultimately invoked will be the one in the derived
- /// class.
- ///
- /// \param io_message The event message to handle
- /// \param message The DNS MessagePtr that needs handling
- /// \param answer_message The final answer will be constructed in
- /// this MessagePtr
- /// \param buffer The final answer is put here
- /// \param server DNSServer object to use
- virtual void operator()(const IOMessage& io_message,
- isc::dns::MessagePtr message,
- isc::dns::MessagePtr answer_message,
- isc::util::OutputBufferPtr buffer,
- DNSServer* server) const
- {
- (*self_)(io_message, message, answer_message, buffer, server);
- }
-private:
- DNSLookup* self_;
-};
-
-} // namespace asiolink
-#endif // __ASIOLINK_DNS_LOOKUP_H
diff --git a/src/lib/asiolink/dns_server.h b/src/lib/asiolink/dns_server.h
deleted file mode 100644
index f15f808..0000000
--- a/src/lib/asiolink/dns_server.h
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright (C) 2011 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 __ASIOLINK_DNS_SERVER_H
-#define __ASIOLINK_DNS_SERVER_H 1
-
-#include <asiolink/io_message.h>
-
-namespace asiolink {
-
-/// \brief The \c DNSServer class is a wrapper (and base class) for
-/// classes which provide DNS server functionality.
-///
-/// The classes derived from this one, \c TCPServer and \c UDPServer,
-/// act as the interface layer between clients sending queries, and
-/// functions defined elsewhere that provide answers to those queries.
-/// Those functions are described in more detail below under
-/// \c SimpleCallback, \c DNSLookup, and \c DNSAnswer.
-///
-/// Notes to developers:
-/// When constructed, this class (and its derived classes) will have its
-/// "self_" member set to point to "this". Objects of this class (as
-/// instantiated through a base class) are sometimes passed by
-/// reference (as this superclass); calls to methods in the base
-/// class are then rerouted via this pointer to methods in the derived
-/// class. This allows code from outside asiolink, with no specific
-/// knowledge of \c TCPServer or \c UDPServer, to access their methods.
-///
-/// This class is both assignable and copy-constructable. Its subclasses
-/// use the "stackless coroutine" pattern, meaning that it will copy itself
-/// when "forking", and that instances will be posted as ASIO handler
-/// objects, which are always copied.
-///
-/// Because these objects are frequently copied, it is recommended
-/// that derived classes be kept small to reduce copy overhead.
-class DNSServer {
-protected:
- ///
- /// \name Constructors and destructors
- ///
- /// This is intentionally defined as \c protected, as this base class
- /// should never be instantiated except as part of a derived class.
- //@{
- DNSServer() : self_(this) {}
-public:
- /// \brief The destructor
- virtual ~DNSServer() {}
- //@}
-
- ///
- /// \name Class methods
- ///
- /// These methods all make their calls indirectly via the "self_"
- /// pointer, ensuring that the functions ultimately invoked will be
- /// the ones in the derived class. This makes it possible to pass
- /// instances of derived classes as references to this base class
- /// without losing access to derived class data.
- ///
- //@{
- /// \brief The funtion operator
- virtual void operator()(asio::error_code ec = asio::error_code(),
- size_t length = 0)
- {
- (*self_)(ec, length);
- }
-
- /// \brief Stop current running server
- virtual void stop() { self_->stop();}
-
- /// \brief Resume processing of the server coroutine after an
- /// asynchronous call (e.g., to the DNS Lookup provider) has completed.
- ///
- /// \param done If true, this signals the system there is an answer
- /// 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
- /// normally be another \c DNSServer object containing a copy
- /// of the original "self_" pointer. Calling clone() guarantees
- /// that the underlying object is also correctly copied.
- ///
- /// \return A deep copy of this DNSServer object
- virtual DNSServer* clone() { return (self_->clone()); }
- //@}
-
-protected:
- /// \brief Lookup handler object.
- ///
- /// This is a protected class; it can only be instantiated
- /// from within a derived class of \c DNSServer.
- ///
- /// A server object that has received a query creates an instance
- /// of this class and scheudles it on the ASIO service queue
- /// using asio::io_service::post(). When the handler executes, it
- /// calls the asyncLookup() method in the server object to start a
- /// DNS lookup. When the lookup is complete, the server object is
- /// scheduled to resume, again using io_service::post().
- ///
- /// Note that the calling object is copied into the handler object,
- /// not referenced. This is because, once the calling object yields
- /// control to the handler, it falls out of scope and may disappear
- template <typename T>
- class AsyncLookup {
- public:
- AsyncLookup(T& caller) : caller_(caller) {}
- void operator()() { caller_.asyncLookup(); }
- private:
- T caller_;
- };
-
- /// \brief Carries out a DNS lookup.
- ///
- /// This function calls the \c DNSLookup object specified by the
- /// DNS server when the \c IOService was created, passing along
- /// the details of the query and a pointer back to the current
- /// server object. It is called asynchronously via the AsyncLookup
- /// handler class.
- virtual void asyncLookup() { self_->asyncLookup(); }
-
-private:
- DNSServer* self_;
-};
-
-
-} // asiolink
-#endif // __ASIOLINK_DNS_SERVER_H
diff --git a/src/lib/asiolink/dns_service.cc b/src/lib/asiolink/dns_service.cc
deleted file mode 100644
index f17bb44..0000000
--- a/src/lib/asiolink/dns_service.cc
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright (C) 2011 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 <netinet/in.h>
-#include <sys/socket.h>
-#include <unistd.h> // for some IPC/network system calls
-
-#include <boost/lexical_cast.hpp>
-
-#include <config.h>
-
-#include <log/dummylog.h>
-
-#include <asio.hpp>
-#include <asiolink/dns_service.h>
-#include <asiolink/io_service.h>
-#include <asiolink/io_service.h>
-#include <asiolink/tcp_server.h>
-#include <asiolink/udp_server.h>
-
-#include <log/dummylog.h>
-
-#include <boost/lexical_cast.hpp>
-#include <boost/foreach.hpp>
-
-using isc::log::dlog;
-
-namespace asiolink {
-
-class SimpleCallback;
-class DNSLookup;
-class DNSAnswer;
-
-namespace {
-
-asio::ip::address
-convertAddr(const std::string& address) {
- asio::error_code err;
- asio::ip::address addr = asio::ip::address::from_string(address, err);
- if (err) {
- isc_throw(IOError, "Invalid IP address '" << &address << "': "
- << err.message());
- }
- return (addr);
-}
-
-}
-
-
-class DNSServiceImpl {
-public:
- DNSServiceImpl(IOService& io_service, const char& port,
- const asio::ip::address* v4addr,
- const asio::ip::address* v6addr,
- SimpleCallback* checkin, DNSLookup* lookup,
- DNSAnswer* answer);
-
- IOService& io_service_;
-
- typedef boost::shared_ptr<UDPServer> UDPServerPtr;
- typedef boost::shared_ptr<TCPServer> TCPServerPtr;
- typedef boost::shared_ptr<DNSServer> DNSServerPtr;
- std::vector<DNSServerPtr> servers_;
- SimpleCallback *checkin_;
- DNSLookup *lookup_;
- DNSAnswer *answer_;
-
- void addServer(uint16_t port, const asio::ip::address& address) {
- try {
- dlog(std::string("Initialize TCP server at ") + address.to_string() + ":" + boost::lexical_cast<std::string>(port));
- TCPServerPtr tcpServer(new TCPServer(io_service_.get_io_service(),
- address, port, checkin_, lookup_, answer_));
- (*tcpServer)();
- servers_.push_back(tcpServer);
- dlog(std::string("Initialize UDP server at ") + address.to_string() + ":" + boost::lexical_cast<std::string>(port));
- UDPServerPtr udpServer(new UDPServer(io_service_.get_io_service(),
- address, port, checkin_, lookup_, answer_));
- (*udpServer)();
- servers_.push_back(udpServer);
- }
- catch (const asio::system_error& err) {
- // We need to catch and convert any ASIO level exceptions.
- // This can happen for unavailable address, binding a privilege port
- // without the privilege, etc.
- isc_throw(IOError, "Failed to initialize network servers: " <<
- err.what());
- }
- }
- void addServer(const char& port, const asio::ip::address& address) {
- uint16_t portnum;
- try {
- // XXX: SunStudio with stlport4 doesn't reject some invalid
- // representation such as "-1" by lexical_cast<uint16_t>, so
- // we convert it into a signed integer of a larger size and perform
- // range check ourselves.
- const int32_t portnum32 = boost::lexical_cast<int32_t>(&port);
- if (portnum32 < 0 || portnum32 > 65535) {
- isc_throw(IOError, "Invalid port number '" << &port);
- }
- portnum = portnum32;
- } catch (const boost::bad_lexical_cast& ex) {
- isc_throw(IOError, "Invalid port number '" << &port << "': " <<
- ex.what());
- }
- addServer(portnum, address);
- }
-};
-
-DNSServiceImpl::DNSServiceImpl(IOService& io_service,
- const char& port,
- const asio::ip::address* const v4addr,
- const asio::ip::address* const v6addr,
- SimpleCallback* checkin,
- DNSLookup* lookup,
- DNSAnswer* answer) :
- io_service_(io_service),
- checkin_(checkin),
- lookup_(lookup),
- answer_(answer)
-{
-
- if (v4addr) {
- addServer(port, *v4addr);
- }
- if (v6addr) {
- addServer(port, *v6addr);
- }
-}
-
-DNSService::DNSService(IOService& io_service,
- const char& port, const char& address,
- SimpleCallback* checkin,
- DNSLookup* lookup,
- DNSAnswer* answer) :
- impl_(new DNSServiceImpl(io_service, port, NULL, NULL, checkin, lookup,
- answer)), io_service_(io_service)
-{
- addServer(port, &address);
-}
-
-DNSService::DNSService(IOService& io_service,
- const char& port,
- const bool use_ipv4, const bool use_ipv6,
- SimpleCallback* checkin,
- DNSLookup* lookup,
- DNSAnswer* answer) :
- impl_(NULL), io_service_(io_service)
-{
- const asio::ip::address v4addr_any =
- asio::ip::address(asio::ip::address_v4::any());
- const asio::ip::address* const v4addrp = use_ipv4 ? &v4addr_any : NULL;
- const asio::ip::address v6addr_any =
- asio::ip::address(asio::ip::address_v6::any());
- const asio::ip::address* const v6addrp = use_ipv6 ? &v6addr_any : NULL;
- impl_ = new DNSServiceImpl(io_service, port, v4addrp, v6addrp, checkin, lookup, answer);
-}
-
-DNSService::DNSService(IOService& io_service, SimpleCallback* checkin,
- DNSLookup* lookup, DNSAnswer *answer) :
- impl_(new DNSServiceImpl(io_service, *"0", NULL, NULL, checkin, lookup,
- answer)), io_service_(io_service)
-{
-}
-
-DNSService::~DNSService() {
- delete impl_;
-}
-
-void
-DNSService::addServer(const char& port, const std::string& address) {
- impl_->addServer(port, convertAddr(address));
-}
-
-void
-DNSService::addServer(uint16_t port, const std::string& address) {
- impl_->addServer(port, convertAddr(address));
-}
-
-void
-DNSService::clearServers() {
- BOOST_FOREACH(const DNSServiceImpl::DNSServerPtr& s, impl_->servers_) {
- s->stop();
- }
- impl_->servers_.clear();
-}
-
-
-
-} // namespace asiolink
diff --git a/src/lib/asiolink/dns_service.h b/src/lib/asiolink/dns_service.h
deleted file mode 100644
index 9a3fb4c..0000000
--- a/src/lib/asiolink/dns_service.h
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (C) 2011 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 __ASIOLINK_DNS_SERVICE_H
-#define __ASIOLINK_DNS_SERVICE_H 1
-
-#include <resolve/resolver_interface.h>
-
-#include <asiolink/io_service.h>
-
-namespace asiolink {
-
-class SimpleCallback;
-class DNSLookup;
-class DNSAnswer;
-class DNSServiceImpl;
-
-/// \brief Handle DNS Queries
-///
-/// DNSService is the service that handles DNS queries and answers with
-/// a given IOService. This class is mainly intended to hold all the
-/// logic that is shared between the authoritative and the recursive
-/// server implementations. As such, it handles asio, including config
-/// updates (through the 'Checkinprovider'), and listening sockets.
-class DNSService {
- ///
- /// \name Constructors and Destructor
- ///
- /// Note: The copy constructor and the assignment operator are
- /// intentionally defined as private, making this class non-copyable.
- //@{
-private:
- DNSService(const DNSService& source);
- DNSService& operator=(const DNSService& source);
-
-public:
- /// \brief The constructor with a specific IP address and port on which
- /// the services listen on.
- ///
- /// \param io_service The IOService to work with
- /// \param port the port to listen on
- /// \param address the IP address to listen on
- /// \param checkin Provider for cc-channel events (see \c SimpleCallback)
- /// \param lookup The lookup provider (see \c DNSLookup)
- /// \param answer The answer provider (see \c DNSAnswer)
- DNSService(IOService& io_service, const char& port,
- const char& address, SimpleCallback* checkin,
- DNSLookup* lookup, DNSAnswer* answer);
- /// \brief The constructor with a specific port on which the services
- /// listen on.
- ///
- /// It effectively listens on "any" IPv4 and/or IPv6 addresses.
- /// IPv4/IPv6 services will be available if and only if \c use_ipv4
- /// or \c use_ipv6 is \c true, respectively.
- ///
- /// \param io_service The IOService to work with
- /// \param port the port to listen on
- /// \param use_ipv4 If true, listen on ipv4 'any'
- /// \param use_ipv6 If true, listen on ipv6 'any'
- /// \param checkin Provider for cc-channel events (see \c SimpleCallback)
- /// \param lookup The lookup provider (see \c DNSLookup)
- /// \param answer The answer provider (see \c DNSAnswer)
- DNSService(IOService& io_service, const char& port,
- const bool use_ipv4, const bool use_ipv6,
- SimpleCallback* checkin, DNSLookup* lookup,
- DNSAnswer* answer);
- /// \brief The constructor without any servers.
- ///
- /// Use addServer() to add some servers.
- DNSService(IOService& io_service, SimpleCallback* checkin,
- DNSLookup* lookup, DNSAnswer* answer);
- /// \brief The destructor.
- ~DNSService();
- //@}
-
- /// \brief Add another server to the service
- void addServer(uint16_t port, const std::string &address);
- void addServer(const char &port, const std::string &address);
- /// \brief Remove all servers from the service
- void clearServers();
-
- /// \brief Return the native \c io_service object used in this wrapper.
- ///
- /// This is a short term work around to support other BIND 10 modules
- /// that share the same \c io_service with the authoritative server.
- /// It will eventually be removed once the wrapper interface is
- /// generalized.
- asio::io_service& get_io_service() { return io_service_.get_io_service(); }
-
- /// \brief Return the IO Service Object
- ///
- /// \return IOService object for this DNS service.
- asiolink::IOService& getIOService() { return (io_service_);}
-
-private:
- DNSServiceImpl* impl_;
- IOService& io_service_;
-};
-
-} // namespace asiolink
-#endif // __ASIOLINK_DNS_SERVICE_H
diff --git a/src/lib/asiolink/dummy_io_cb.h b/src/lib/asiolink/dummy_io_cb.h
index 0006b95..2081906 100644
--- a/src/lib/asiolink/dummy_io_cb.h
+++ b/src/lib/asiolink/dummy_io_cb.h
@@ -20,6 +20,7 @@
#include <asio/error.hpp>
#include <asio/error_code.hpp>
+namespace isc {
namespace asiolink {
/// \brief Asynchronous I/O Completion Callback
@@ -55,5 +56,6 @@ public:
};
} // namespace asiolink
+} // namespace isc
#endif // __DUMMY_IO_CB_H
diff --git a/src/lib/asiolink/interval_timer.cc b/src/lib/asiolink/interval_timer.cc
index 8efb102..0ed06eb 100644
--- a/src/lib/asiolink/interval_timer.cc
+++ b/src/lib/asiolink/interval_timer.cc
@@ -26,6 +26,7 @@
#include <asiolink/interval_timer.h>
#include <asiolink/io_service.h>
+namespace isc {
namespace asiolink {
class IntervalTimerImpl {
@@ -133,4 +134,5 @@ IntervalTimer::getInterval() const {
return (impl_->getInterval());
}
-}
+} // namespace asiolink
+} // namespace isc
diff --git a/src/lib/asiolink/interval_timer.h b/src/lib/asiolink/interval_timer.h
index 6c43327..0831d44 100644
--- a/src/lib/asiolink/interval_timer.h
+++ b/src/lib/asiolink/interval_timer.h
@@ -19,6 +19,7 @@
#include <asiolink/io_service.h>
+namespace isc {
namespace asiolink {
struct IntervalTimerImpl;
@@ -129,5 +130,6 @@ private:
IntervalTimerImpl* impl_;
};
-} // namespace asiolink
+} // namespace asiolink
+} // namespace isc
#endif // __ASIOLINK_INTERVAL_TIMER_H
diff --git a/src/lib/asiolink/io_address.cc b/src/lib/asiolink/io_address.cc
index 70e8374..7f7a6fc 100644
--- a/src/lib/asiolink/io_address.cc
+++ b/src/lib/asiolink/io_address.cc
@@ -31,6 +31,7 @@ using asio::ip::tcp;
using namespace std;
+namespace isc {
namespace asiolink {
// XXX: we cannot simply construct the address in the initialization list,
@@ -62,4 +63,5 @@ IOAddress::getFamily() const {
}
}
-}
+} // namespace asiolink
+} // namespace isc
diff --git a/src/lib/asiolink/io_address.h b/src/lib/asiolink/io_address.h
index 53c1a7a..655b727 100644
--- a/src/lib/asiolink/io_address.h
+++ b/src/lib/asiolink/io_address.h
@@ -26,6 +26,7 @@
#include <exceptions/exceptions.h>
+namespace isc {
namespace asiolink {
/// \brief The \c IOAddress class represents an IP addresses (version
@@ -119,5 +120,6 @@ private:
asio::ip::address asio_address_;
};
-} // asiolink
+} // namespace asiolink
+} // namespace isc
#endif // __IO_ADDRESS_H
diff --git a/src/lib/asiolink/io_asio_socket.h b/src/lib/asiolink/io_asio_socket.h
index 9d22990..864708c 100644
--- a/src/lib/asiolink/io_asio_socket.h
+++ b/src/lib/asiolink/io_asio_socket.h
@@ -31,7 +31,7 @@
#include <asiolink/io_error.h>
#include <asiolink/io_socket.h>
-
+namespace isc {
namespace asiolink {
/// \brief Socket not open
@@ -395,5 +395,6 @@ private:
};
} // namespace asiolink
+} // namespace isc
#endif // __IO_ASIO_SOCKET_H
diff --git a/src/lib/asiolink/io_endpoint.cc b/src/lib/asiolink/io_endpoint.cc
index e0b1a9e..63830a5 100644
--- a/src/lib/asiolink/io_endpoint.cc
+++ b/src/lib/asiolink/io_endpoint.cc
@@ -28,6 +28,7 @@
using namespace std;
+namespace isc {
namespace asiolink {
const IOEndpoint*
@@ -57,4 +58,5 @@ IOEndpoint::operator!=(const IOEndpoint& other) const {
return (!operator==(other));
}
-}
+} // namespace asiolink
+} // namespace isc
diff --git a/src/lib/asiolink/io_endpoint.h b/src/lib/asiolink/io_endpoint.h
index d21da96..756fa3b 100644
--- a/src/lib/asiolink/io_endpoint.h
+++ b/src/lib/asiolink/io_endpoint.h
@@ -26,6 +26,7 @@
#include <exceptions/exceptions.h>
#include <asiolink/io_address.h>
+namespace isc {
namespace asiolink {
/// \brief The \c IOEndpoint class is an abstract base class to represent
@@ -117,5 +118,6 @@ public:
const unsigned short port);
};
-} // asiolink
+} // namespace asiolink
+} // namespace isc
#endif // __IO_ENDPOINT_H
diff --git a/src/lib/asiolink/io_error.h b/src/lib/asiolink/io_error.h
index 2869e0b..c19d91c 100644
--- a/src/lib/asiolink/io_error.h
+++ b/src/lib/asiolink/io_error.h
@@ -18,6 +18,7 @@
#include <exceptions/exceptions.h>
+namespace isc {
namespace asiolink {
/// \brief An exception that is thrown if an error occurs within the IO
@@ -30,6 +31,7 @@ public:
};
-} // asiolink
+} // namespace asiolink
+} // namespace isc
#endif // __IO_ERROR_H
diff --git a/src/lib/asiolink/io_fetch.cc b/src/lib/asiolink/io_fetch.cc
deleted file mode 100644
index f38a1f5..0000000
--- a/src/lib/asiolink/io_fetch.cc
+++ /dev/null
@@ -1,381 +0,0 @@
-// Copyright (C) 2011 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 <unistd.h> // for some IPC/network system calls
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-#include <boost/bind.hpp>
-#include <boost/scoped_ptr.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
-
-#include <dns/message.h>
-#include <dns/messagerenderer.h>
-#include <dns/opcode.h>
-#include <dns/rcode.h>
-#include <log/logger.h>
-
-#include <util/buffer.h>
-#include <util/random/qid_gen.h>
-
-#include <asio.hpp>
-#include <asio/deadline_timer.hpp>
-
-#include <asiolink/asiodef.h>
-#include <asiolink/io_address.h>
-#include <asiolink/io_asio_socket.h>
-#include <asiolink/io_endpoint.h>
-#include <asiolink/io_fetch.h>
-#include <asiolink/io_service.h>
-#include <asiolink/tcp_endpoint.h>
-#include <asiolink/tcp_socket.h>
-#include <asiolink/udp_endpoint.h>
-#include <asiolink/udp_socket.h>
-
-#include <stdint.h>
-
-using namespace asio;
-using namespace isc::dns;
-using namespace isc::util;
-using namespace isc::util::random;
-using namespace isc::log;
-using namespace std;
-
-namespace asiolink {
-
-/// Use the ASIO logger
-
-isc::log::Logger logger("asiolink");
-
-/// \brief IOFetch Data
-///
-/// The data for IOFetch is held in a separate struct pointed to by a shared_ptr
-/// object. This is because the IOFetch object will be copied often (it is used
-/// as a coroutine and passed as callback to many async_*() functions) and we
-/// want keep the same data). Organising the data in this way keeps copying to
-/// a minimum.
-struct IOFetchData {
-
- // The first two members are shared pointers to a base class because what is
- // actually instantiated depends on whether the fetch is over UDP or TCP,
- // which is not known until construction of the IOFetch. Use of a shared
- // pointer here is merely to ensure deletion when the data object is deleted.
- boost::scoped_ptr<IOAsioSocket<IOFetch> > socket;
- ///< Socket to use for I/O
- boost::scoped_ptr<IOEndpoint> remote_snd;///< Where the fetch is sent
- boost::scoped_ptr<IOEndpoint> remote_rcv;///< Where the response came from
- isc::dns::Question question; ///< Question to be asked
- OutputBufferPtr msgbuf; ///< Wire buffer for question
- OutputBufferPtr received; ///< Received data put here
- IOFetch::Callback* callback; ///< Called on I/O Completion
- asio::deadline_timer timer; ///< Timer to measure timeouts
- IOFetch::Protocol protocol; ///< Protocol being used
- size_t cumulative; ///< Cumulative received amount
- size_t expected; ///< Expected amount of data
- size_t offset; ///< Offset to receive data
- bool stopped; ///< Have we stopped running?
- int timeout; ///< Timeout in ms
-
- // In case we need to log an error, the origin of the last asynchronous
- // I/O is recorded. To save time and simplify the code, this is recorded
- // as the ID of the error message that would be generated if the I/O failed.
- // This means that we must make sure that all possible "origins" take the
- // same arguments in their message in the same order.
- isc::log::MessageID origin; ///< Origin of last asynchronous I/O
- uint8_t staging[IOFetch::STAGING_LENGTH];
- ///< Temporary array for received data
- isc::dns::qid_t qid; ///< The QID set in the query
-
- /// \brief Constructor
- ///
- /// Just fills in the data members of the IOFetchData structure
- ///
- /// \param proto Either IOFetch::TCP or IOFetch::UDP.
- /// \param service I/O Service object to handle the asynchronous
- /// operations.
- /// \param query DNS question to send to the upstream server.
- /// \param address IP address of upstream server
- /// \param port Port to use for the query
- /// \param buff Output buffer into which the response (in wire format)
- /// is written (if a response is received).
- /// \param cb Callback object containing the callback to be called
- /// when we terminate. The caller is responsible for managing this
- /// object and deleting it if necessary.
- /// \param wait Timeout for the fetch (in ms).
- ///
- /// TODO: May need to alter constructor (see comment 4 in Trac ticket #554)
- IOFetchData(IOFetch::Protocol proto, IOService& service,
- const isc::dns::Question& query, const IOAddress& address,
- uint16_t port, OutputBufferPtr& buff, IOFetch::Callback* cb, int wait)
- :
- socket((proto == IOFetch::UDP) ?
- static_cast<IOAsioSocket<IOFetch>*>(
- new UDPSocket<IOFetch>(service)) :
- static_cast<IOAsioSocket<IOFetch>*>(
- new TCPSocket<IOFetch>(service))
- ),
- remote_snd((proto == IOFetch::UDP) ?
- static_cast<IOEndpoint*>(new UDPEndpoint(address, port)) :
- static_cast<IOEndpoint*>(new TCPEndpoint(address, port))
- ),
- remote_rcv((proto == IOFetch::UDP) ?
- static_cast<IOEndpoint*>(new UDPEndpoint(address, port)) :
- static_cast<IOEndpoint*>(new TCPEndpoint(address, port))
- ),
- question(query),
- msgbuf(new OutputBuffer(512)),
- received(buff),
-
- callback(cb),
- timer(service.get_io_service()),
- protocol(proto),
- cumulative(0),
- expected(0),
- offset(0),
- stopped(false),
- timeout(wait),
- origin(ASIO_UNKORIGIN),
- staging(),
- qid(QidGenerator::getInstance().generateQid())
- {}
-
- // Checks if the response we received was ok;
- // - data contains the buffer we read, as well as the address
- // we sent to and the address we received from.
- // length is provided by the operator() in IOFetch.
- // Addresses must match, number of octets read must be at least
- // 2, and the first two octets must match the qid of the message
- // we sent.
- bool responseOK() {
- return (*remote_snd == *remote_rcv && cumulative >= 2 &&
- readUint16(received->getData()) == qid);
- }
-};
-
-/// IOFetch Constructor - just initialize the private data
-
-IOFetch::IOFetch(Protocol protocol, IOService& service,
- const isc::dns::Question& question, const IOAddress& address, uint16_t port,
- OutputBufferPtr& buff, Callback* cb, int wait)
- :
- data_(new IOFetchData(protocol, service, question, address,
- port, buff, cb, wait))
-{
-}
-
-// Return protocol in use.
-
-IOFetch::Protocol
-IOFetch::getProtocol() const {
- return (data_->protocol);
-}
-
-/// The function operator is implemented with the "stackless coroutine"
-/// pattern; see internal/coroutine.h for details.
-
-void
-IOFetch::operator()(asio::error_code ec, size_t length) {
-
- if (data_->stopped) {
- return;
- } else if (ec) {
- logIOFailure(ec);
- return;
- }
-
- CORO_REENTER (this) {
-
- /// Generate the upstream query and render it to wire format
- /// This is done in a different scope to allow inline variable
- /// declarations.
- {
- Message msg(Message::RENDER);
- msg.setQid(data_->qid);
- msg.setOpcode(Opcode::QUERY());
- msg.setRcode(Rcode::NOERROR());
- msg.setHeaderFlag(Message::HEADERFLAG_RD);
- msg.addQuestion(data_->question);
- MessageRenderer renderer(*data_->msgbuf);
- msg.toWire(renderer);
- }
-
- // If we timeout, we stop, which will can cancel outstanding I/Os and
- // shutdown everything.
- if (data_->timeout != -1) {
- data_->timer.expires_from_now(boost::posix_time::milliseconds(
- data_->timeout));
- data_->timer.async_wait(boost::bind(&IOFetch::stop, *this,
- TIME_OUT));
- }
-
- // Open a connection to the target system. For speed, if the operation
- // is synchronous (i.e. UDP operation) we bypass the yield.
- data_->origin = ASIO_OPENSOCK;
- if (data_->socket->isOpenSynchronous()) {
- data_->socket->open(data_->remote_snd.get(), *this);
- } else {
- CORO_YIELD data_->socket->open(data_->remote_snd.get(), *this);
- }
-
- do {
- // Begin an asynchronous send, and then yield. When the send completes,
- // we will resume immediately after this point.
- data_->origin = ASIO_SENDSOCK;
- CORO_YIELD data_->socket->asyncSend(data_->msgbuf->getData(),
- data_->msgbuf->getLength(), data_->remote_snd.get(), *this);
-
- // Now receive the response. Since TCP may not receive the entire
- // message in one operation, we need to loop until we have received
- // it. (This can't be done within the asyncReceive() method because
- // each I/O operation will be done asynchronously and between each one
- // we need to yield ... and we *really* don't want to set up another
- // coroutine within that method.) So after each receive (and yield),
- // we check if the operation is complete and if not, loop to read again.
- //
- // Another concession to TCP is that the amount of is contained in the
- // first two bytes. This leads to two problems:
- //
- // a) We don't want those bytes in the return buffer.
- // b) They may not both arrive in the first I/O.
- //
- // So... we need to loop until we have at least two bytes, then store
- // the expected amount of data. Then we need to loop until we have
- // received all the data before copying it back to the user's buffer.
- // And we want to minimise the amount of copying...
-
- data_->origin = ASIO_RECVSOCK;
- data_->cumulative = 0; // No data yet received
- data_->offset = 0; // First data into start of buffer
- data_->received->clear(); // Clear the receive buffer
- do {
- CORO_YIELD data_->socket->asyncReceive(data_->staging,
- static_cast<size_t>(STAGING_LENGTH),
- data_->offset,
- data_->remote_rcv.get(), *this);
- } while (!data_->socket->processReceivedData(data_->staging, length,
- data_->cumulative, data_->offset,
- data_->expected, data_->received));
- } while (!data_->responseOK());
-
- // Finished with this socket, so close it. This will not generate an
- // I/O error, but reset the origin to unknown in case we change this.
- data_->origin = ASIO_UNKORIGIN;
- data_->socket->close();
-
- /// We are done
- stop(SUCCESS);
- }
-}
-
-// Function that stops the coroutine sequence. It is called either when the
-// query finishes or when the timer times out. Either way, it sets the
-// "stopped_" flag and cancels anything that is in progress.
-//
-// As the function may be entered multiple times as things wind down, it checks
-// if the stopped_ flag is already set. If it is, the call is a no-op.
-
-void
-IOFetch::stop(Result result) {
-
- if (!data_->stopped) {
-
- // Mark the fetch as stopped to prevent other completion callbacks
- // (invoked because of the calls to cancel()) from executing the
- // cancel calls again.
- //
- // In a single threaded environment, the callbacks won't be invoked
- // until this one completes. In a multi-threaded environment, they may
- // well be, in which case the testing (and setting) of the stopped_
- // variable should be done inside a mutex (and the stopped_ variable
- // declared as "volatile").
- //
- // The numeric arguments indicate the debug level, with the lower
- // numbers indicating the most important information. The relative
- // values are somewhat arbitrary.
- //
- // Although Logger::debug checks the debug flag internally, doing it
- // below before calling Logger::debug avoids the overhead of a string
- // conversion in the common case when debug is not enabled.
- //
- // TODO: Update testing of stopped_ if threads are used.
- data_->stopped = true;
- switch (result) {
- case TIME_OUT:
- if (logger.isDebugEnabled(1)) {
- logger.debug(20, ASIO_RECVTMO,
- data_->remote_snd->getAddress().toText().c_str(),
- static_cast<int>(data_->remote_snd->getPort()));
- }
- break;
-
- case SUCCESS:
- if (logger.isDebugEnabled(50)) {
- logger.debug(30, ASIO_FETCHCOMP,
- data_->remote_rcv->getAddress().toText().c_str(),
- static_cast<int>(data_->remote_rcv->getPort()));
- }
- break;
-
- case STOPPED:
- // Fetch has been stopped for some other reason. This is
- // allowed but as it is unusual it is logged, but with a lower
- // debug level than a timeout (which is totally normal).
- logger.debug(1, ASIO_FETCHSTOP,
- data_->remote_snd->getAddress().toText().c_str(),
- static_cast<int>(data_->remote_snd->getPort()));
- break;
-
- default:
- logger.error(ASIO_UNKRESULT, static_cast<int>(result),
- data_->remote_snd->getAddress().toText().c_str(),
- static_cast<int>(data_->remote_snd->getPort()));
- }
-
- // Stop requested, cancel and I/O's on the socket and shut it down,
- // and cancel the timer.
- data_->socket->cancel();
- data_->socket->close();
-
- data_->timer.cancel();
-
- // Execute the I/O completion callback (if present).
- if (data_->callback) {
- (*(data_->callback))(result);
- }
- }
-}
-
-// Log an error - called on I/O failure
-
-void IOFetch::logIOFailure(asio::error_code ec) {
-
- // Should only get here with a known error code.
- assert((data_->origin == ASIO_OPENSOCK) ||
- (data_->origin == ASIO_SENDSOCK) ||
- (data_->origin == ASIO_RECVSOCK) ||
- (data_->origin == ASIO_UNKORIGIN));
-
- static const char* PROTOCOL[2] = {"TCP", "UDP"};
- logger.error(data_->origin,
- ec.value(),
- ((data_->remote_snd->getProtocol() == IPPROTO_TCP) ?
- PROTOCOL[0] : PROTOCOL[1]),
- data_->remote_snd->getAddress().toText().c_str(),
- static_cast<int>(data_->remote_snd->getPort()));
-}
-
-} // namespace asiolink
-
diff --git a/src/lib/asiolink/io_fetch.h b/src/lib/asiolink/io_fetch.h
deleted file mode 100644
index 8a522d6..0000000
--- a/src/lib/asiolink/io_fetch.h
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright (C) 2010 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 __IO_FETCH_H
-#define __IO_FETCH_H 1
-
-#include <config.h>
-
-#include <boost/shared_array.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
-
-#include <coroutine.h>
-
-#include <asio/error_code.hpp>
-
-#include <util/buffer.h>
-#include <dns/question.h>
-
-namespace asiolink {
-
-// Forward declarations
-class IOAddress;
-class IOFetchData;
-class IOService;
-
-/// \brief Upstream Fetch Processing
-///
-/// IOFetch is the class used to send upstream fetches and to handle responses.
-///
-/// \param E Endpoint type to use.
-
-class IOFetch : public coroutine {
-public:
- /// \brief Protocol to use on the fetch
- enum Protocol {
- UDP = 0,
- TCP = 1
- };
-
- /// \brief Origin of Asynchronous I/O Call
- ///
- /// Indicates what initiated an asynchronous I/O call and used in deciding
- /// what error message to output if the I/O fails.
- enum Origin {
- NONE = 0, ///< No asynchronous call outstanding
- OPEN = 1,
- SEND = 2,
- RECEIVE = 3,
- CLOSE = 4
- };
-
- /// \brief Result of Upstream Fetch
- ///
- /// Note that this applies to the status of I/Os in the fetch - a fetch
- /// that resulted in a packet being received from the server is a SUCCESS,
- /// even if the contents of the packet indicate that some error occurred.
- enum Result {
- SUCCESS = 0, ///< Success, fetch completed
- TIME_OUT = 1, ///< Failure, fetch timed out
- STOPPED = 2, ///< Control code, fetch has been stopped
- NOTSET = 3 ///< For testing, indicates value not set
- };
-
- // The next enum is a "trick" to allow constants to be defined in a class
- // declaration.
-
- /// \brief Integer Constants
- enum {
- STAGING_LENGTH = 8192 ///< Size of staging buffer
- };
-
- /// \brief I/O Fetch Callback
- ///
- /// Class of callback object for when the fetch itself has completed - an
- /// object of this class is passed to the IOFetch constructor and its
- /// operator() method called when the fetch completes.
- ///
- /// Note the difference between the two operator() methods:
- /// - IOFetch::operator() callback is called when an asynchronous I/O has
- /// completed.
- /// - IOFetch::Callback::operator() is called when an upstream fetch - which
- /// may have involved several asynchronous I/O operations - has completed.
- ///
- /// This is an abstract class.
- class Callback {
- public:
- /// \brief Default Constructor
- Callback()
- {}
-
- /// \brief Virtual Destructor
- virtual ~Callback()
- {}
-
- /// \brief Callback method
- ///
- /// This is the method called when the fetch completes.
- ///
- /// \param result Result of the fetch
- virtual void operator()(Result result) = 0;
- };
-
- /// \brief Constructor.
- ///
- /// Creates the object that will handle the upstream fetch.
- ///
- /// TODO: Need to randomise the source port
- ///
- /// \param protocol Fetch protocol, either IOFetch::TCP or IOFetch::UDP
- /// \param service I/O Service object to handle the asynchronous
- /// operations.
- /// \param question DNS question to send to the upstream server.
- /// \param buff Output buffer into which the response (in wire format)
- /// is written (if a response is received).
- /// \param cb Callback object containing the callback to be called
- /// when we terminate. The caller is responsible for managing this
- /// object and deleting it if necessary.
- /// \param address IP address of upstream server
- /// \param port Port to which to connect on the upstream server
- /// (default = 53)
- /// \param wait Timeout for the fetch (in ms). The default value of
- /// -1 indicates no timeout.
- IOFetch(Protocol protocol, IOService& service,
- const isc::dns::Question& question, const IOAddress& address,
- uint16_t port, isc::util::OutputBufferPtr& buff, Callback* cb,
- int wait = -1);
-
- /// \brief Return Current Protocol
- ///
- /// \return Protocol associated with this IOFetch object.
- Protocol getProtocol() const;
-
- /// \brief Coroutine entry point
- ///
- /// The operator() method is the method in which the coroutine code enters
- /// this object when an operation has been completed.
- ///
- /// \param ec Error code, the result of the last asynchronous I/O operation.
- /// \param length Amount of data received on the last asynchronous read
- void operator()(asio::error_code ec = asio::error_code(), size_t length = 0);
-
- /// \brief Terminate query
- ///
- /// This method can be called at any point. It terminates the current
- /// query with the specified reason.
- ///
- /// \param reason Reason for terminating the query
- void stop(Result reason = STOPPED);
-
-private:
- /// \brief Log I/O Failure
- ///
- /// Records an I/O failure to the log file
- ///
- /// \param ec ASIO error code
- void logIOFailure(asio::error_code ec);
-
- // Member variables. All data is in a structure pointed to by a shared
- // pointer. The IOFetch object is copied a number of times during its
- // life, and only requiring a pointer to be copied reduces overhead.
- boost::shared_ptr<IOFetchData> data_; ///< Private data
-
-};
-
-} // namespace asiolink
-
-#endif // __IO_FETCH_H
diff --git a/src/lib/asiolink/io_message.h b/src/lib/asiolink/io_message.h
index e857bd9..81f6da1 100644
--- a/src/lib/asiolink/io_message.h
+++ b/src/lib/asiolink/io_message.h
@@ -28,6 +28,7 @@
#include <asiolink/io_endpoint.h>
#include <asiolink/io_socket.h>
+namespace isc {
namespace asiolink {
/// \brief The \c IOMessage class encapsulates an incoming message received
@@ -96,5 +97,6 @@ private:
};
-} // asiolink
+} // namespace asiolink
+} // namespace isc
#endif // __IO_MESSAGE_H
diff --git a/src/lib/asiolink/io_service.cc b/src/lib/asiolink/io_service.cc
index 55fc4b3..70cc18b 100644
--- a/src/lib/asiolink/io_service.cc
+++ b/src/lib/asiolink/io_service.cc
@@ -21,6 +21,7 @@
#include <asio.hpp>
#include <asiolink/io_service.h>
+namespace isc {
namespace asiolink {
class IOServiceImpl {
@@ -95,4 +96,5 @@ IOService::get_io_service() {
return (io_impl_->get_io_service());
}
-} // namepsace asiolink
+} // namespace asiolink
+} // namespace isc
diff --git a/src/lib/asiolink/io_service.h b/src/lib/asiolink/io_service.h
index 66558b7..438667c 100644
--- a/src/lib/asiolink/io_service.h
+++ b/src/lib/asiolink/io_service.h
@@ -19,6 +19,7 @@ namespace asio {
class io_service;
}
+namespace isc {
namespace asiolink {
struct IOServiceImpl;
@@ -73,5 +74,6 @@ private:
IOServiceImpl* io_impl_;
};
-} // namespace asiolink
+} // namespace asiolink
+} // namespace isc
#endif // __ASIOLINK_IO_SERVICE_H
diff --git a/src/lib/asiolink/io_socket.cc b/src/lib/asiolink/io_socket.cc
index c386ca1..e1498dc 100644
--- a/src/lib/asiolink/io_socket.cc
+++ b/src/lib/asiolink/io_socket.cc
@@ -16,8 +16,7 @@
#include <asio.hpp>
-using namespace asio;
-
+namespace isc {
namespace asiolink {
/// \brief The \c DummySocket class is a concrete derived class of
@@ -62,4 +61,5 @@ IOSocket::getDummyTCPSocket() {
return (socket);
}
-}
+} // namespace asiolink
+} // namespace isc
diff --git a/src/lib/asiolink/io_socket.h b/src/lib/asiolink/io_socket.h
index bebc8b6..ab6479c 100644
--- a/src/lib/asiolink/io_socket.h
+++ b/src/lib/asiolink/io_socket.h
@@ -25,6 +25,7 @@
#include <exceptions/exceptions.h>
+namespace isc {
namespace asiolink {
/// \brief The \c IOSocket class is an abstract base class to represent
@@ -120,5 +121,6 @@ public:
};
} // namespace asiolink
+} // namespace isc
#endif // __IO_SOCKET_H
diff --git a/src/lib/asiolink/simple_callback.h b/src/lib/asiolink/simple_callback.h
index ab5deaf..92093ec 100644
--- a/src/lib/asiolink/simple_callback.h
+++ b/src/lib/asiolink/simple_callback.h
@@ -17,6 +17,7 @@
#include <asiolink/io_message.h>
+namespace isc {
namespace asiolink {
/// \brief The \c SimpleCallback class is an abstract base class for a
@@ -67,5 +68,6 @@ private:
SimpleCallback* self_;
};
-} // namespace asiolink
+} // namespace asiolink
+} // namespace isc
#endif // __ASIOLINK_SIMPLE_CALLBACK_H
diff --git a/src/lib/asiolink/tcp_endpoint.h b/src/lib/asiolink/tcp_endpoint.h
index 158ca4a..3e420f3 100644
--- a/src/lib/asiolink/tcp_endpoint.h
+++ b/src/lib/asiolink/tcp_endpoint.h
@@ -21,6 +21,7 @@
#include <asiolink/io_endpoint.h>
+namespace isc {
namespace asiolink {
/// \brief The \c TCPEndpoint class is a concrete derived class of
@@ -109,5 +110,6 @@ private:
asio::ip::tcp::endpoint& asio_endpoint_;
};
-} // namespace asiolink
+} // namespace asiolink
+} // namespace isc
#endif // __TCP_ENDPOINT_H
diff --git a/src/lib/asiolink/tcp_server.cc b/src/lib/asiolink/tcp_server.cc
deleted file mode 100644
index 6ea862b..0000000
--- a/src/lib/asiolink/tcp_server.cc
+++ /dev/null
@@ -1,242 +0,0 @@
-// Copyright (C) 2011 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 <netinet/in.h>
-#include <sys/socket.h>
-#include <unistd.h> // for some IPC/network system calls
-#include <errno.h>
-
-#include <boost/shared_array.hpp>
-
-#include <log/dummylog.h>
-
-#include <util/buffer.h>
-
-#include <asio.hpp>
-#include <asiolink/dummy_io_cb.h>
-#include <asiolink/tcp_endpoint.h>
-#include <asiolink/tcp_socket.h>
-#include <asiolink/tcp_server.h>
-
-
-using namespace asio;
-using asio::ip::udp;
-using asio::ip::tcp;
-
-using namespace std;
-using namespace isc::dns;
-using namespace isc::util;
-
-namespace asiolink {
-
-/// The following functions implement the \c TCPServer class.
-///
-/// The constructor
-TCPServer::TCPServer(io_service& io_service,
- const ip::address& addr, const uint16_t port,
- const SimpleCallback* checkin,
- const DNSLookup* lookup,
- const DNSAnswer* answer) :
- io_(io_service), done_(false),
- checkin_callback_(checkin), lookup_callback_(lookup),
- answer_callback_(answer)
-{
- tcp::endpoint endpoint(addr, port);
- acceptor_.reset(new tcp::acceptor(io_service));
- acceptor_->open(endpoint.protocol());
- // Set v6-only (we use a separate instantiation for v4,
- // otherwise asio will bind to both v4 and v6
- if (addr.is_v6()) {
- acceptor_->set_option(ip::v6_only(true));
- }
- acceptor_->set_option(tcp::acceptor::reuse_address(true));
- acceptor_->bind(endpoint);
- acceptor_->listen();
-}
-
-void
-TCPServer::operator()(error_code ec, size_t length) {
- /// Because the coroutine reentry block is implemented as
- /// a switch statement, inline variable declarations are not
- /// permitted. Certain variables used below can be declared here.
-
- boost::array<const_buffer,2> bufs;
- OutputBuffer lenbuf(TCP_MESSAGE_LENGTHSIZE);
-
- CORO_REENTER (this) {
- do {
- /// Create a socket to listen for connections
- socket_.reset(new tcp::socket(acceptor_->get_io_service()));
-
- /// Wait for new connections. In the event of non-fatal error,
- /// try again
- do {
- CORO_YIELD acceptor_->async_accept(*socket_, *this);
-
- // Abort on fatal errors
- // TODO: Log error?
- if (ec) {
- using namespace asio::error;
- if (ec.value() != would_block && ec.value() != try_again &&
- ec.value() != connection_aborted &&
- ec.value() != interrupted) {
- return;
- }
- }
- } while (ec);
-
- /// Fork the coroutine by creating a copy of this one and
- /// scheduling it on the ASIO service queue. The parent
- /// will continue listening for DNS connections while the
- /// handles the one that has just arrived.
- CORO_FORK io_.post(TCPServer(*this));
- } while (is_parent());
-
- /// Instantiate the data buffer that will be used by the
- /// asynchronous read call.
- data_.reset(new char[MAX_LENGTH]);
-
- /// Read the message, in two parts. First, the message length:
- CORO_YIELD async_read(*socket_, asio::buffer(data_.get(),
- TCP_MESSAGE_LENGTHSIZE), *this);
- if (ec) {
- socket_->close();
- CORO_YIELD return;
- }
-
- /// Now read the message itself. (This is done in a different scope
- /// to allow inline variable declarations.)
- CORO_YIELD {
- InputBuffer dnsbuffer(data_.get(), length);
- uint16_t msglen = dnsbuffer.readUint16();
- async_read(*socket_, asio::buffer(data_.get(), msglen), *this);
- }
-
- if (ec) {
- socket_->close();
- CORO_YIELD return;
- }
-
-
- // Create an \c IOMessage object to store the query.
- //
- // (XXX: It would be good to write a factory function
- // that would quickly generate an IOMessage object without
- // all these calls to "new".)
- peer_.reset(new TCPEndpoint(socket_->remote_endpoint()));
-
- // The TCP socket class has been extended with asynchronous functions
- // and takes as a template parameter a completion callback class. As
- // TCPServer does not use these extended functions (only those defined
- // in the IOSocket base class) - but needs a TCPSocket to get hold of
- // the underlying Boost TCP socket - DummyIOCallback is used. This
- // provides the appropriate operator() but is otherwise functionless.
- iosock_.reset(new TCPSocket<DummyIOCallback>(*socket_));
- io_message_.reset(new IOMessage(data_.get(), length, *iosock_, *peer_));
- bytes_ = length;
-
- // Perform any necessary operations prior to processing the incoming
- // packet (e.g., checking for queued configuration messages).
- //
- // (XXX: it may be a performance issue to have this called for
- // every single incoming packet; we may wish to throttle it somehow
- // in the future.)
- if (checkin_callback_ != NULL) {
- (*checkin_callback_)(*io_message_);
- }
-
- // If we don't have a DNS Lookup provider, there's no point in
- // continuing; we exit the coroutine permanently.
- if (lookup_callback_ == NULL) {
- socket_->close();
- CORO_YIELD return;
- }
-
- // Reset or instantiate objects that will be needed by the
- // DNS lookup and the write call.
- respbuf_.reset(new OutputBuffer(0));
- query_message_.reset(new Message(Message::PARSE));
- answer_message_.reset(new Message(Message::RENDER));
-
- // Schedule a DNS lookup, and yield. When the lookup is
- // finished, the coroutine will resume immediately after
- // this point.
- CORO_YIELD io_.post(AsyncLookup<TCPServer>(*this));
-
- // The 'done_' flag indicates whether we have an answer
- // to send back. If not, exit the coroutine permanently.
- if (!done_) {
- // TODO: should we keep the connection open for a short time
- // to see if new requests come in?
- socket_->close();
- CORO_YIELD return;
- }
-
- if (ec) {
- CORO_YIELD return;
- }
- // Call the DNS answer provider to render the answer into
- // wire format
- (*answer_callback_)(*io_message_, query_message_,
- answer_message_, respbuf_);
-
- // Set up the response, beginning with two length bytes.
- lenbuf.writeUint16(respbuf_->getLength());
- bufs[0] = buffer(lenbuf.getData(), lenbuf.getLength());
- bufs[1] = buffer(respbuf_->getData(), respbuf_->getLength());
-
- // Begin an asynchronous send, and then yield. When the
- // send completes, we will resume immediately after this point
- // (though we have nothing further to do, so the coroutine
- // will simply exit at that time).
- CORO_YIELD async_write(*socket_, bufs, *this);
-
- // TODO: should we keep the connection open for a short time
- // to see if new requests come in?
- socket_->close();
- }
-}
-
-/// Call the DNS lookup provider. (Expected to be called by the
-/// AsyncLookup<TCPServer> handler.)
-void
-TCPServer::asyncLookup() {
- (*lookup_callback_)(*io_message_, query_message_,
- answer_message_, respbuf_, this);
-}
-
-void TCPServer::stop() {
- /// we use close instead of cancel, with the same reason
- /// with udp server stop, refer to the udp server code
-
- acceptor_->close();
- // User may stop the server even when it hasn't started to
- // run, in that that socket_ is empty
- if (socket_) {
- socket_->close();
- }
-}
-/// 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
-TCPServer::resume(const bool done) {
- done_ = done;
- io_.post(*this);
-}
-
-} // namespace asiolink
-
diff --git a/src/lib/asiolink/tcp_server.h b/src/lib/asiolink/tcp_server.h
deleted file mode 100644
index a4449f7..0000000
--- a/src/lib/asiolink/tcp_server.h
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright (C) 2011 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 __TCP_SERVER_H
-#define __TCP_SERVER_H 1
-
-#ifndef ASIO_HPP
-#error "asio.hpp must be included before including this, see asiolink.h as to why"
-#endif
-
-#include <boost/shared_array.hpp>
-#include <boost/shared_ptr.hpp>
-
-#include <asiolink/asiolink.h>
-#include <coroutine.h>
-
-
-namespace asiolink {
-
-/// \brief A TCP-specific \c DNSServer object.
-///
-/// This class inherits from both \c DNSServer and from \c coroutine,
-/// defined in coroutine.h.
-class TCPServer : public virtual DNSServer, public virtual coroutine {
-public:
- explicit TCPServer(asio::io_service& io_service,
- const asio::ip::address& addr, const uint16_t port,
- const SimpleCallback* checkin = NULL,
- const DNSLookup* lookup = NULL,
- const DNSAnswer* answer = NULL);
-
- void operator()(asio::error_code ec = asio::error_code(),
- size_t length = 0);
- 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);
- }
-
-private:
- enum { MAX_LENGTH = 65535 };
- static const size_t TCP_MESSAGE_LENGTHSIZE = 2;
-
- // The ASIO service object
- asio::io_service& io_;
-
- // Class member variables which are dynamic, and changes to which
- // need to accessible from both sides of a coroutine fork or from
- // outside of the coroutine (i.e., from an asynchronous I/O call),
- // should be declared here as pointers and allocated in the
- // constructor or in the coroutine. This allows state information
- // to persist when an individual copy of the coroutine falls out
- // scope while waiting for an event, *so long as* there is another
- // object that is referencing the same data. As a side-benefit, using
- // pointers also reduces copy overhead for coroutine objects.
- //
- // Note: Currently these objects are allocated by "new" in the
- // constructor, or in the function operator while processing a query.
- // Repeated allocations from the heap for every incoming query is
- // clearly a performance issue; this must be optimized in the future.
- // The plan is to have a structure pre-allocate several "server state"
- // objects which can be pulled off a free list and placed on an in-use
- // list whenever a query comes in. This will serve the dual purpose
- // of improving performance and guaranteeing that state information
- // will *not* be destroyed when any one instance of the coroutine
- // falls out of scope while waiting for an event.
- //
- // An ASIO acceptor object to handle new connections. Created in
- // the constructor.
- boost::shared_ptr<asio::ip::tcp::acceptor> acceptor_;
-
- // Socket used to for listen for queries. Created in the
- // constructor and stored in a shared_ptr because socket objects
- // are not copyable.
- boost::shared_ptr<asio::ip::tcp::socket> socket_;
-
- // The buffer into which the response is written
- boost::shared_ptr<isc::util::OutputBuffer> respbuf_;
-
- // \c IOMessage and \c Message objects to be passed to the
- // DNS lookup and answer providers
- boost::shared_ptr<asiolink::IOMessage> io_message_;
- isc::dns::MessagePtr query_message_;
- isc::dns::MessagePtr answer_message_;
-
- // The buffer into which the query packet is written
- boost::shared_array<char>data_;
-
- // State information that is entirely internal to a given instance
- // of the coroutine can be declared here.
- size_t bytes_;
- bool done_;
-
- // Callback functions provided by the caller
- const SimpleCallback* checkin_callback_;
- const DNSLookup* lookup_callback_;
- const DNSAnswer* answer_callback_;
-
- boost::shared_ptr<IOEndpoint> peer_;
- boost::shared_ptr<IOSocket> iosock_;
-};
-
-} // namespace asiolink
-#endif // __TCP_SERVER_H
diff --git a/src/lib/asiolink/tcp_socket.h b/src/lib/asiolink/tcp_socket.h
index 3488cc5..c8876c8 100644
--- a/src/lib/asiolink/tcp_socket.h
+++ b/src/lib/asiolink/tcp_socket.h
@@ -41,6 +41,7 @@
#include <asiolink/io_service.h>
#include <asiolink/tcp_endpoint.h>
+namespace isc {
namespace asiolink {
/// \brief Buffer Too Large
@@ -412,5 +413,6 @@ TCPSocket<C>::close() {
}
} // namespace asiolink
+} // namespace isc
#endif // __TCP_SOCKET_H
diff --git a/src/lib/asiolink/tests/Makefile.am b/src/lib/asiolink/tests/Makefile.am
index 4e9216a..37d9ef3 100644
--- a/src/lib/asiolink/tests/Makefile.am
+++ b/src/lib/asiolink/tests/Makefile.am
@@ -21,15 +21,12 @@ run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.h
run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.cc
run_unittests_SOURCES += io_address_unittest.cc
run_unittests_SOURCES += io_endpoint_unittest.cc
-run_unittests_SOURCES += io_fetch_unittest.cc
run_unittests_SOURCES += io_socket_unittest.cc
-run_unittests_SOURCES += io_service_unittest.cc
run_unittests_SOURCES += interval_timer_unittest.cc
run_unittests_SOURCES += tcp_endpoint_unittest.cc
run_unittests_SOURCES += tcp_socket_unittest.cc
run_unittests_SOURCES += udp_endpoint_unittest.cc
run_unittests_SOURCES += udp_socket_unittest.cc
-run_unittests_SOURCES += dns_server_unittest.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
diff --git a/src/lib/asiolink/tests/dns_server_unittest.cc b/src/lib/asiolink/tests/dns_server_unittest.cc
deleted file mode 100644
index 181387d..0000000
--- a/src/lib/asiolink/tests/dns_server_unittest.cc
+++ /dev/null
@@ -1,502 +0,0 @@
-// Copyright (C) 2011 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 <gtest/gtest.h>
-
-#include <asio.hpp>
-#include <asiolink/io_endpoint.h>
-#include <asiolink/io_error.h>
-#include <asiolink/udp_server.h>
-#include <asiolink/tcp_server.h>
-#include <asiolink/dns_answer.h>
-#include <asiolink/dns_lookup.h>
-#include <string>
-#include <csignal>
-#include <unistd.h> //for alarm
-
-#include <boost/shared_ptr.hpp>
-#include <boost/bind.hpp>
-#include <boost/function.hpp>
-
-
-/// The following tests focus on stop interface for udp and
-/// tcp server, there are lots of things can be shared to test
-/// both tcp and udp server, so they are in the same unittest
-
-/// The general work flow for dns server, is that wait for user
-/// query, once get one query, we will check the data is valid or
-/// not, if it passed, we will try to loop up the question, then
-/// compose the answer and finally send it back to user. The server
-/// may be stopped at any point during this porcess, so the test strategy
-/// is that we define 5 stop point and stop the server at these
-/// 5 points, to check whether stop is successful
-/// The 5 test points are :
-/// Before the server start to run
-/// After we get the query and check whether it's valid
-/// After we lookup the query
-/// After we compoisite the answer
-/// After user get the final result.
-
-/// The standard about whether we stop the server successfully or not
-/// is based on the fact that if the server is still running, the io
-/// service won't quit since it will wait for some asynchronized event for
-/// server. So if the io service block function run returns we assume
-/// that the server is stopped. To avoid stop interface failure which
-/// will block followed tests, using alarm signal to stop the blocking
-/// io service
-///
-/// The whole test context including one server and one client, and
-/// five stop checkpoints, we call them ServerStopper exclude the first
-/// stop point. Once the unittest fired, the client will send message
-/// to server, and the stopper may stop the server at the checkpoint, then
-/// we check the client get feedback or not. Since there is no DNS logic
-/// involved so the message sending between client and server is plain text
-/// And the valid checker, question lookup and answer composition are dummy.
-
-using namespace asiolink;
-using namespace asio;
-
-namespace {
-static const std::string server_ip = "127.0.0.1";
-const int server_port = 5553;
-//message client send to udp server, which isn't dns package
-//just for simple testing
-static const std::string query_message("BIND10 is awesome");
-
-// \brief provide capacity to derived class the ability
-// to stop DNSServer at certern point
-class ServerStopper {
- public:
- ServerStopper() : server_to_stop_(NULL) {}
- virtual ~ServerStopper(){}
-
- void setServerToStop(DNSServer* server) {
- server_to_stop_ = server;
- }
-
- void stopServer() const {
- if (server_to_stop_) {
- server_to_stop_->stop();
- }
- }
-
- private:
- DNSServer* server_to_stop_;
-};
-
-// \brief no check logic at all,just provide a checkpoint to stop the server
-class DummyChecker : public SimpleCallback, public ServerStopper {
- public:
- virtual void operator()(const IOMessage&) const {
- stopServer();
- }
-};
-
-// \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();
- server->resume(true);
- }
-};
-
-// \brief copy the data received from user to the answer part
-// provide checkpoint to stop server
-class SimpleAnswer : public DNSAnswer, public ServerStopper {
- public:
- void operator()(const IOMessage& message,
- isc::dns::MessagePtr query_message,
- isc::dns::MessagePtr answer_message,
- isc::util::OutputBufferPtr buffer) const
- {
- //copy what we get from user
- buffer->writeData(message.getData(), message.getDataSize());
- stopServer();
- }
-
-};
-
-// \brief simple client, send one string to server and wait for response
-// in case, server stopped and client cann't get response, there is a timer wait
-// for specified seconds (the value is just a estimate since server process logic is quite
-// simple, and all the intercommunication is local) then cancel the waiting.
-class SimpleClient : public ServerStopper {
- public:
- static const size_t MAX_DATA_LEN = 256;
- SimpleClient(asio::io_service& service,
- unsigned int wait_server_time_out)
- {
- wait_for_response_timer_.reset(new deadline_timer(service));
- received_data_ = new char[MAX_DATA_LEN];
- received_data_len_ = 0;
- wait_server_time_out_ = wait_server_time_out;
- }
-
- virtual ~SimpleClient() {
- delete [] received_data_;
- }
-
- void setGetFeedbackCallback(boost::function<void()>& func) {
- get_response_call_back_ = func;
- }
-
- virtual void sendDataThenWaitForFeedback(const std::string& data) = 0;
- virtual std::string getReceivedData() const = 0;
-
- void startTimer() {
- wait_for_response_timer_->cancel();
- wait_for_response_timer_->
- expires_from_now(boost::posix_time::
- seconds(wait_server_time_out_));
- wait_for_response_timer_->
- async_wait(boost::bind(&SimpleClient::stopWaitingforResponse,
- this));
- }
-
- void cancelTimer() { wait_for_response_timer_->cancel(); }
-
- void getResponseCallBack(const asio::error_code& error, size_t
- received_bytes)
- {
- cancelTimer();
- if (!error)
- received_data_len_ = received_bytes;
- if (!get_response_call_back_.empty()) {
- get_response_call_back_();
- }
- stopServer();
- }
-
-
- protected:
- virtual void stopWaitingforResponse() = 0;
-
- boost::shared_ptr<deadline_timer> wait_for_response_timer_;
- char* received_data_;
- size_t received_data_len_;
- boost::function<void()> get_response_call_back_;
- unsigned int wait_server_time_out_;
-};
-
-
-
-class UDPClient : public SimpleClient {
- public:
- //After 1 seconds without feedback client will stop wait
- static const unsigned int server_time_out = 1;
-
- UDPClient(asio::io_service& service, const ip::udp::endpoint& server) :
- SimpleClient(service, server_time_out)
- {
- server_ = server;
- socket_.reset(new ip::udp::socket(service));
- socket_->open(ip::udp::v4());
- }
-
-
- void sendDataThenWaitForFeedback(const std::string& data) {
- received_data_len_ = 0;
- socket_->send_to(buffer(data.c_str(), data.size() + 1), server_);
- socket_->async_receive_from(buffer(received_data_, MAX_DATA_LEN),
- received_from_,
- boost::bind(&SimpleClient::
- getResponseCallBack, this, _1,
- _2));
- startTimer();
- }
-
- virtual std::string getReceivedData() const {
- return (received_data_len_ == 0 ? std::string("") :
- std::string(received_data_));
- }
-
- private:
- void stopWaitingforResponse() {
- socket_->close();
- }
-
- boost::shared_ptr<ip::udp::socket> socket_;
- ip::udp::endpoint server_;
- ip::udp::endpoint received_from_;
-};
-
-
-class TCPClient : public SimpleClient {
- public:
- // after 2 seconds without feedback client will stop wait,
- // this includes connect, send message and recevice message
- static const unsigned int server_time_out = 2;
- TCPClient(asio::io_service& service, const ip::tcp::endpoint& server)
- : SimpleClient(service, server_time_out)
- {
- server_ = server;
- socket_.reset(new ip::tcp::socket(service));
- socket_->open(ip::tcp::v4());
- }
-
-
- virtual void sendDataThenWaitForFeedback(const std::string &data) {
- received_data_len_ = 0;
- data_to_send_ = data;
- data_to_send_len_ = data.size() + 1;
- socket_->async_connect(server_, boost::bind(&TCPClient::connectHandler,
- this, _1));
- startTimer();
- }
-
- virtual std::string getReceivedData() const {
- return (received_data_len_ == 0 ? std::string("") :
- std::string(received_data_ + 2));
- }
-
- private:
- void stopWaitingforResponse() {
- socket_->close();
- }
-
- void connectHandler(const asio::error_code& error) {
- if (!error) {
- data_to_send_len_ = htons(data_to_send_len_);
- socket_->async_send(buffer(&data_to_send_len_, 2),
- boost::bind(&TCPClient::sendMessageBodyHandler,
- this, _1, _2));
- }
- }
-
- void sendMessageBodyHandler(const asio::error_code& error,
- size_t send_bytes)
- {
- if (!error && send_bytes == 2) {
- socket_->async_send(buffer(data_to_send_.c_str(),
- data_to_send_.size() + 1),
- boost::bind(&TCPClient::finishSendHandler, this, _1, _2));
- }
- }
-
- void finishSendHandler(const asio::error_code& error, size_t send_bytes) {
- if (!error && send_bytes == data_to_send_.size() + 1) {
- socket_->async_receive(buffer(received_data_, MAX_DATA_LEN),
- boost::bind(&SimpleClient::getResponseCallBack, this, _1,
- _2));
- }
- }
-
- boost::shared_ptr<ip::tcp::socket> socket_;
- ip::tcp::endpoint server_;
- std::string data_to_send_;
- uint16_t data_to_send_len_;
-};
-
-
-
-// \brief provide the context which including two client and
-// two server, udp client will only communicate with udp server, same for tcp client
-class DNSServerTest : public::testing::Test {
- protected:
- void SetUp() {
- ip::address server_address = ip::address::from_string(server_ip);
- checker_ = new DummyChecker();
- lookup_ = new DummyLookup();
- answer_ = new SimpleAnswer();
- udp_server_ = new UDPServer(service, server_address, server_port,
- checker_, lookup_, answer_);
- udp_client_ = new UDPClient(service,
- ip::udp::endpoint(server_address,
- server_port));
- tcp_server_ = new TCPServer(service, server_address, server_port,
- checker_, lookup_, answer_);
- tcp_client_ = new TCPClient(service,
- ip::tcp::endpoint(server_address,
- server_port));
- }
-
-
- void TearDown() {
- udp_server_->stop();
- tcp_server_->stop();
- delete checker_;
- delete lookup_;
- delete answer_;
- delete udp_server_;
- delete udp_client_;
- delete tcp_server_;
- delete tcp_client_;
- }
-
-
- void testStopServerByStopper(DNSServer* server, SimpleClient* client,
- ServerStopper* stopper)
- {
- static const unsigned int io_service_time_out = 5;
- io_service_is_time_out = false;
- stopper->setServerToStop(server);
- (*server)();
- client->sendDataThenWaitForFeedback(query_message);
- // Since thread hasn't been introduced into the tool box, using signal
- // to make sure run function will eventually return even server stop
- // failed
- void (*prev_handler)(int) = std::signal(SIGALRM, DNSServerTest::stopIOService);
- alarm(io_service_time_out);
- service.run();
- service.reset();
- //cancel scheduled alarm
- alarm(0);
- std::signal(SIGALRM, prev_handler);
- }
-
-
- static void stopIOService(int _no_use_parameter) {
- io_service_is_time_out = true;
- service.stop();
- }
-
- bool serverStopSucceed() const {
- return (!io_service_is_time_out);
- }
-
- DummyChecker* checker_;
- DummyLookup* lookup_;
- SimpleAnswer* answer_;
- UDPServer* udp_server_;
- UDPClient* udp_client_;
- TCPClient* tcp_client_;
- TCPServer* tcp_server_;
-
- // To access them in signal handle function, the following
- // variables have to be static.
- static asio::io_service service;
- static bool io_service_is_time_out;
-};
-
-bool DNSServerTest::io_service_is_time_out = false;
-asio::io_service DNSServerTest::service;
-
-// Test whether server stopped successfully after client get response
-// client will send query and start to wait for response, once client
-// get response, udp server will be stopped, the io service won't quit
-// if udp server doesn't stop successfully.
-TEST_F(DNSServerTest, stopUDPServerAfterOneQuery) {
- testStopServerByStopper(udp_server_, udp_client_, udp_client_);
- EXPECT_EQ(query_message, udp_client_->getReceivedData());
- EXPECT_TRUE(serverStopSucceed());
-}
-
-// Test whether udp server stopped successfully before server start to serve
-TEST_F(DNSServerTest, stopUDPServerBeforeItStartServing) {
- udp_server_->stop();
- testStopServerByStopper(udp_server_, udp_client_, udp_client_);
- EXPECT_EQ(std::string(""), udp_client_->getReceivedData());
- EXPECT_TRUE(serverStopSucceed());
-}
-
-
-// Test whether udp server stopped successfully during message check
-TEST_F(DNSServerTest, stopUDPServerDuringMessageCheck) {
- testStopServerByStopper(udp_server_, udp_client_, checker_);
- EXPECT_EQ(std::string(""), udp_client_->getReceivedData());
- EXPECT_TRUE(serverStopSucceed());
-}
-
-// Test whether udp server stopped successfully during query lookup
-TEST_F(DNSServerTest, stopUDPServerDuringQueryLookup) {
- testStopServerByStopper(udp_server_, udp_client_, lookup_);
- EXPECT_EQ(std::string(""), udp_client_->getReceivedData());
- EXPECT_TRUE(serverStopSucceed());
-}
-
-// Test whether udp server stopped successfully during composing answer
-TEST_F(DNSServerTest, stopUDPServerDuringPrepareAnswer) {
- testStopServerByStopper(udp_server_, udp_client_, answer_);
- EXPECT_EQ(std::string(""), udp_client_->getReceivedData());
- EXPECT_TRUE(serverStopSucceed());
-}
-
-static void stopServerManyTimes(DNSServer *server, unsigned int times) {
- for (int i = 0; i < times; ++i) {
- server->stop();
- }
-}
-
-// Test whether udp server stop interface can be invoked several times without
-// throw any exception
-TEST_F(DNSServerTest, stopUDPServeMoreThanOnce) {
- ASSERT_NO_THROW({
- boost::function<void()> stop_server_3_times
- = boost::bind(stopServerManyTimes, udp_server_, 3);
- udp_client_->setGetFeedbackCallback(stop_server_3_times);
- testStopServerByStopper(udp_server_, udp_client_, udp_client_);
- EXPECT_EQ(query_message, udp_client_->getReceivedData());
- });
- EXPECT_TRUE(serverStopSucceed());
-}
-
-
-TEST_F(DNSServerTest, stopTCPServerAfterOneQuery) {
- testStopServerByStopper(tcp_server_, tcp_client_, tcp_client_);
- EXPECT_EQ(query_message, tcp_client_->getReceivedData());
- EXPECT_TRUE(serverStopSucceed());
-}
-
-
-// Test whether tcp server stopped successfully before server start to serve
-TEST_F(DNSServerTest, stopTCPServerBeforeItStartServing) {
- tcp_server_->stop();
- testStopServerByStopper(tcp_server_, tcp_client_, tcp_client_);
- EXPECT_EQ(std::string(""), tcp_client_->getReceivedData());
- EXPECT_TRUE(serverStopSucceed());
-}
-
-
-// Test whether tcp server stopped successfully during message check
-TEST_F(DNSServerTest, stopTCPServerDuringMessageCheck) {
- testStopServerByStopper(tcp_server_, tcp_client_, checker_);
- EXPECT_EQ(std::string(""), tcp_client_->getReceivedData());
- EXPECT_TRUE(serverStopSucceed());
-}
-
-// Test whether tcp server stopped successfully during query lookup
-TEST_F(DNSServerTest, stopTCPServerDuringQueryLookup) {
- testStopServerByStopper(tcp_server_, tcp_client_, lookup_);
- EXPECT_EQ(std::string(""), tcp_client_->getReceivedData());
- EXPECT_TRUE(serverStopSucceed());
-}
-
-// Test whether tcp server stopped successfully during composing answer
-TEST_F(DNSServerTest, stopTCPServerDuringPrepareAnswer) {
- testStopServerByStopper(tcp_server_, tcp_client_, answer_);
- EXPECT_EQ(std::string(""), tcp_client_->getReceivedData());
- EXPECT_TRUE(serverStopSucceed());
-}
-
-
-// Test whether tcp server stop interface can be invoked several times without
-// throw any exception
-TEST_F(DNSServerTest, stopTCPServeMoreThanOnce) {
- ASSERT_NO_THROW({
- boost::function<void()> stop_server_3_times
- = boost::bind(stopServerManyTimes, tcp_server_, 3);
- tcp_client_->setGetFeedbackCallback(stop_server_3_times);
- testStopServerByStopper(tcp_server_, tcp_client_, tcp_client_);
- EXPECT_EQ(query_message, tcp_client_->getReceivedData());
- });
- EXPECT_TRUE(serverStopSucceed());
-}
-
-}
diff --git a/src/lib/asiolink/tests/interval_timer_unittest.cc b/src/lib/asiolink/tests/interval_timer_unittest.cc
index 7e0e7bc..c24e60e 100644
--- a/src/lib/asiolink/tests/interval_timer_unittest.cc
+++ b/src/lib/asiolink/tests/interval_timer_unittest.cc
@@ -26,7 +26,7 @@ const boost::posix_time::time_duration TIMER_MARGIN_MSEC =
boost::posix_time::milliseconds(50);
}
-using namespace asiolink;
+using namespace isc::asiolink;
// This fixture is for testing IntervalTimer. Some callback functors are
// registered as callback function of the timer to test if they are called
diff --git a/src/lib/asiolink/tests/io_address_unittest.cc b/src/lib/asiolink/tests/io_address_unittest.cc
index 894f143..18b181e 100644
--- a/src/lib/asiolink/tests/io_address_unittest.cc
+++ b/src/lib/asiolink/tests/io_address_unittest.cc
@@ -18,7 +18,7 @@
#include <asiolink/io_error.h>
#include <asiolink/io_address.h>
-using namespace asiolink;
+using namespace isc::asiolink;
TEST(IOAddressTest, fromText) {
IOAddress io_address_v4("192.0.2.1");
diff --git a/src/lib/asiolink/tests/io_endpoint_unittest.cc b/src/lib/asiolink/tests/io_endpoint_unittest.cc
index 5170f7d..ce21fde 100644
--- a/src/lib/asiolink/tests/io_endpoint_unittest.cc
+++ b/src/lib/asiolink/tests/io_endpoint_unittest.cc
@@ -18,7 +18,7 @@
#include <asiolink/io_endpoint.h>
#include <asiolink/io_error.h>
-using namespace asiolink;
+using namespace isc::asiolink;
TEST(IOEndpointTest, createUDPv4) {
const IOEndpoint* ep;
diff --git a/src/lib/asiolink/tests/io_fetch_unittest.cc b/src/lib/asiolink/tests/io_fetch_unittest.cc
deleted file mode 100644
index bec6104..0000000
--- a/src/lib/asiolink/tests/io_fetch_unittest.cc
+++ /dev/null
@@ -1,725 +0,0 @@
-// Copyright (C) 2011 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 <algorithm>
-#include <cstdlib>
-#include <string>
-#include <iostream>
-#include <iomanip>
-#include <iterator>
-#include <vector>
-
-#include <gtest/gtest.h>
-#include <boost/bind.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
-
-#include <asio.hpp>
-
-#include <util/buffer.h>
-#include <util/io_utilities.h>
-
-#include <dns/question.h>
-#include <dns/message.h>
-#include <dns/messagerenderer.h>
-#include <dns/opcode.h>
-#include <dns/name.h>
-#include <dns/rcode.h>
-
-#include <asiolink/io_address.h>
-#include <asiolink/io_endpoint.h>
-#include <asiolink/io_fetch.h>
-#include <asiolink/io_service.h>
-
-using namespace asio;
-using namespace isc::dns;
-using namespace isc::util;
-using namespace asio::ip;
-using namespace std;
-
-namespace asiolink {
-
-const asio::ip::address TEST_HOST(asio::ip::address::from_string("127.0.0.1"));
-const uint16_t TEST_PORT(5301);
-const int SEND_INTERVAL = 250; // Interval in ms between TCP sends
-const size_t MAX_SIZE = 64 * 1024; // Should be able to take 64kB
-
-// The tests are complex, so debug output has been left in (although disabled).
-// Set this to true to enable it.
-const bool DEBUG = false;
-
-/// \brief Test fixture for the asiolink::IOFetch.
-class IOFetchTest : public virtual ::testing::Test, public virtual IOFetch::Callback
-{
-public:
- IOService service_; ///< Service to run the query
- IOFetch::Result expected_; ///< Expected result of the callback
- bool run_; ///< Did the callback run already?
- Question question_; ///< What to ask
- OutputBufferPtr result_buff_; ///< Buffer to hold result of fetch
- OutputBufferPtr msgbuf_; ///< Buffer corresponding to known question
- IOFetch udp_fetch_; ///< For UDP query test
- IOFetch tcp_fetch_; ///< For TCP query test
- IOFetch::Protocol protocol_; ///< Protocol being tested
- size_t cumulative_; ///< Cumulative data received by "server".
- deadline_timer timer_; ///< Timer to measure timeouts
-
- // The next member is the buffer in which the "server" (implemented by the
- // response handler methods in this class) receives the question sent by the
- // fetch object.
- uint8_t receive_buffer_[MAX_SIZE]; ///< Server receive buffer
- OutputBufferPtr expected_buffer_; ///< Data we expect to receive
- vector<uint8_t> send_buffer_; ///< Server send buffer
- uint16_t send_cumulative_; ///< Data sent so far
-
- // Other data.
- string return_data_; ///< Data returned by server
- string test_data_; ///< Large string - here for convenience
- bool debug_; ///< true to enable debug output
- size_t tcp_send_size_; ///< Max size of TCP send
- uint8_t qid_0; ///< First octet of qid
- uint8_t qid_1; ///< Second octet of qid
-
- bool tcp_short_send_; ///< If set to true, we do not send
- /// all data in the tcp response
-
- /// \brief Constructor
- IOFetchTest() :
- service_(),
- expected_(IOFetch::NOTSET),
- run_(false),
- question_(Name("example.net"), RRClass::IN(), RRType::A()),
- result_buff_(new OutputBuffer(512)),
- msgbuf_(new OutputBuffer(512)),
- udp_fetch_(IOFetch::UDP, service_, question_, IOAddress(TEST_HOST),
- TEST_PORT, result_buff_, this, 100),
- tcp_fetch_(IOFetch::TCP, service_, question_, IOAddress(TEST_HOST),
- TEST_PORT, result_buff_, this, (16 * SEND_INTERVAL)),
- // Timeout interval chosen to ensure no timeout
- protocol_(IOFetch::TCP), // for initialization - will be changed
- cumulative_(0),
- timer_(service_.get_io_service()),
- receive_buffer_(),
- expected_buffer_(new OutputBuffer(512)),
- send_buffer_(),
- send_cumulative_(0),
- return_data_(""),
- test_data_(""),
- debug_(DEBUG),
- tcp_send_size_(0),
- qid_0(0),
- qid_1(0),
- tcp_short_send_(false)
- {
- // Construct the data buffer for question we expect to receive.
- Message msg(Message::RENDER);
- msg.setQid(0);
- msg.setOpcode(Opcode::QUERY());
- msg.setRcode(Rcode::NOERROR());
- msg.setHeaderFlag(Message::HEADERFLAG_RD);
- msg.addQuestion(question_);
- MessageRenderer renderer(*msgbuf_);
- msg.toWire(renderer);
- MessageRenderer renderer2(*expected_buffer_);
- msg.toWire(renderer2);
-
- // 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
- // the class.)
- //
- // We could initialize the data with a single character, but as an added
- // check we'll make ssre that it has some structure.
-
- test_data_.clear();
- test_data_.reserve(MAX_SIZE);
- while (test_data_.size() < MAX_SIZE) {
- test_data_ += "A message to be returned to the client that has "
- "some sort of structure.";
- }
- }
-
- /// \brief UDP Response handler (the "remote UDP DNS server")
- ///
- /// When IOFetch is sending data, this response handler emulates the remote
- /// DNS server. It checks that the data sent by the IOFetch object is what
- /// was expected to have been sent, then sends back a known buffer of data.
- ///
- /// \param remote Endpoint to which to send the answer
- /// \param socket Socket to use to send the answer
- /// \param ec ASIO error code, completion code of asynchronous I/O issued
- /// by the "server" to receive data.
- /// \param bad_qid If set to true, the QID in the response will be mangled
- /// \param second_send If set to true, (and bad_qid is too), after the
- /// mangled qid response has been sent, a second packet will be
- /// sent with the correct QID.
- /// \param length Amount of data received.
- void udpReceiveHandler(udp::endpoint* remote, udp::socket* socket,
- error_code ec = error_code(), size_t length = 0,
- bool bad_qid = false, bool second_send = false) {
- if (debug_) {
- cout << "udpReceiveHandler(): error = " << ec.value() <<
- ", length = " << length << endl;
- }
-
- // The QID in the incoming data is random so set it to 0 for the
- // data comparison check. (It is set to 0 in the buffer containing
- // the expected data.)
- qid_0 = receive_buffer_[0];
- qid_1 = receive_buffer_[1];
- receive_buffer_[0] = receive_buffer_[1] = 0;
-
- // Check that length of the received data and the expected data are
- // identical, then check that the data is identical as well.
- EXPECT_EQ(msgbuf_->getLength(), length);
- EXPECT_TRUE(equal(receive_buffer_, (receive_buffer_ + length - 1),
- static_cast<const uint8_t*>(msgbuf_->getData())));
-
- // Return a message back to the IOFetch object.
- if (!bad_qid) {
- expected_buffer_->writeUint8At(qid_0, 0);
- expected_buffer_->writeUint8At(qid_1, 1);
- } else {
- expected_buffer_->writeUint8At(qid_0 + 1, 0);
- expected_buffer_->writeUint8At(qid_1 + 1, 1);
- }
- socket->send_to(asio::buffer(expected_buffer_->getData(), length), *remote);
-
- if (bad_qid && second_send) {
- expected_buffer_->writeUint8At(qid_0, 0);
- expected_buffer_->writeUint8At(qid_1, 1);
- socket->send_to(asio::buffer(expected_buffer_->getData(),
- expected_buffer_->getLength()), *remote);
- }
- if (debug_) {
- cout << "udpReceiveHandler(): returned " << expected_buffer_->getLength() <<
- " bytes to the client" << endl;
- }
- }
-
- /// \brief Completion Handler for accepting TCP data
- ///
- /// Called when the remote system connects to the "server". It issues
- /// an asynchronous read on the socket to read data.
- ///
- /// \param socket Socket on which data will be received
- /// \param ec Boost error code, value should be zero.
- void tcpAcceptHandler(tcp::socket* socket, error_code ec = error_code())
- {
- if (debug_) {
- cout << "tcpAcceptHandler(): error = " << ec.value() << endl;
- }
-
- // Expect that the accept completed without a problem.
- EXPECT_EQ(0, ec.value());
-
- // Work out the maximum size of data we can send over it when we
- // respond, then subtract 1kB or so for safety.
- tcp::socket::send_buffer_size send_size;
- socket->get_option(send_size);
- if (send_size.value() < (2 * 1024)) {
- FAIL() << "TCP send size is less than 2kB";
- } else {
- tcp_send_size_ = send_size.value() - 1024;
- if (debug_) {
- cout << "tcpacceptHandler(): will use send size = " << tcp_send_size_ << endl;
- }
- }
-
- // Initiate a read on the socket.
- cumulative_ = 0;
- socket->async_receive(asio::buffer(receive_buffer_, sizeof(receive_buffer_)),
- boost::bind(&IOFetchTest::tcpReceiveHandler, this, socket, _1, _2));
- }
-
- /// \brief Completion handler for receiving TCP data
- ///
- /// When IOFetch is sending data, this response handler emulates the remote
- /// DNS server. It that all the data sent by the IOFetch object has been
- /// received, issuing another read if not. If the data is complete, it is
- /// compared to what is expected and a reply sent back to the IOFetch.
- ///
- /// \param socket Socket to use to send the answer
- /// \param ec ASIO error code, completion code of asynchronous I/O issued
- /// by the "server" to receive data.
- /// \param length Amount of data received.
- void tcpReceiveHandler(tcp::socket* socket, error_code ec = error_code(),
- size_t length = 0)
- {
- if (debug_) {
- cout << "tcpReceiveHandler(): error = " << ec.value() <<
- ", length = " << length << endl;
- }
- // Expect that the receive completed without a problem.
- EXPECT_EQ(0, ec.value());
-
- // If we haven't received all the data, issue another read.
- cumulative_ += length;
- bool complete = false;
- if (cumulative_ > 2) {
- uint16_t dns_length = readUint16(receive_buffer_);
- complete = ((dns_length + 2) == cumulative_);
- }
-
- if (!complete) {
- socket->async_receive(asio::buffer((receive_buffer_ + cumulative_),
- (sizeof(receive_buffer_) - cumulative_)),
- boost::bind(&IOFetchTest::tcpReceiveHandler, this, socket, _1, _2));
- return;
- }
-
- // Check that length of the DNS message received is that expected, then
- // compare buffers, zeroing the QID in the received buffer to match
- // that set in our expected question. Note that due to the length
- // field the QID in the received buffer is in the third and fourth
- // bytes.
- EXPECT_EQ(msgbuf_->getLength() + 2, cumulative_);
- qid_0 = receive_buffer_[2];
- qid_1 = receive_buffer_[3];
-
- receive_buffer_[2] = receive_buffer_[3] = 0;
- EXPECT_TRUE(equal((receive_buffer_ + 2), (receive_buffer_ + cumulative_ - 2),
- static_cast<const uint8_t*>(msgbuf_->getData())));
-
- // ... and return a message back. This has to be preceded by a two-byte
- // count field.
-
- send_buffer_.clear();
- send_buffer_.push_back(0);
- send_buffer_.push_back(0);
- writeUint16(return_data_.size(), &send_buffer_[0]);
- copy(return_data_.begin(), return_data_.end(), back_inserter(send_buffer_));
- if (return_data_.size() >= 2) {
- send_buffer_[2] = qid_0;
- send_buffer_[3] = qid_1;
- }
- // Send the data. This is done in multiple writes with a delay between
- // each to check that the reassembly of TCP packets from fragments works.
- send_cumulative_ = 0;
- tcpSendData(socket);
- }
-
- /// \brief Sent Data Over TCP
- ///
- /// Send the TCP data back to the IOFetch object. The data is sent in
- /// three chunks - two of 16 bytes and the remainder, with a 250ms gap
- /// between each. (Amounts of data smaller than one 32 bytes are sent in
- /// one or two packets.)
- ///
- /// \param socket Socket over which send should take place
- void tcpSendData(tcp::socket* socket) {
- if (debug_) {
- cout << "tcpSendData()" << endl;
- }
-
- // Decide what to send based on the cumulative count. At most we'll do
- // two chunks of 16 bytes (with a 250ms gap between) and then the
- // remainder.
- uint8_t* send_ptr = &send_buffer_[send_cumulative_];
- // Pointer to data to send
- size_t amount = 16; // Amount of data to send
- if (send_cumulative_ < (2 * amount)) {
-
- // First or second time through, send at most 16 bytes
- amount = min(amount, (send_buffer_.size() - send_cumulative_));
-
- } else {
-
- // For all subsequent times, send the remainder, maximised to
- // whatever we have chosen for the maximum send size.
- amount = min(tcp_send_size_,
- (send_buffer_.size() - send_cumulative_));
- }
-
- // This is for the short send test; reduce the actual amount of
- // data we send
- if (tcp_short_send_) {
- if (debug_) {
- cout << "tcpSendData(): sending incomplete data (" <<
- (amount - 1) << " of " << amount << " bytes)" <<
- endl;
- }
- --amount;
- } else {
- if (debug_) {
- cout << "tcpSendData(): sending " << amount << " bytes" << endl;
- }
- }
-
- // ... and send it. The amount sent is also passed as the first
- // argument of the send callback, as a check.
- socket->async_send(asio::buffer(send_ptr, amount),
- boost::bind(&IOFetchTest::tcpSendHandler, this,
- amount, socket, _1, _2));
- }
-
- /// \brief Completion Handler for Sending TCP data
- ///
- /// Called when the asynchronous send of data back to the IOFetch object
- /// by the TCP "server" in this class has completed. (This send has to
- /// be asynchronous because control needs to return to the caller in order
- /// for the IOService "run()" method to be called to run the handlers.)
- ///
- /// If not all the data has been sent, a short delay is instigated (during
- /// which control returns to the IOService). This should force the queued
- /// data to actually be sent and the IOFetch receive handler to be triggered.
- /// In this way, the ability of IOFetch to handle fragmented TCP packets
- /// should be checked.
- ///
- /// \param expected Number of bytes that were expected to have been sent.
- /// \param socket Socket over which the send took place. Only used to
- /// pass back to the send method.
- /// \param ec Boost error code, value should be zero.
- /// \param length Number of bytes sent.
- void tcpSendHandler(size_t expected, tcp::socket* socket,
- error_code ec = error_code(), size_t length = 0)
- {
- if (debug_) {
- cout << "tcpSendHandler(): error = " << ec.value() <<
- ", length = " << length << endl;
- }
-
- EXPECT_EQ(0, ec.value()); // Expect no error
- EXPECT_EQ(expected, length); // And that amount sent is as expected
-
- // Do we need to send more?
- send_cumulative_ += length;
- if (send_cumulative_ < send_buffer_.size()) {
-
- // Yes - set up a timer: the callback handler for the timer is
- // tcpSendData, which will then send the next chunk. We pass the
- // socket over which data should be sent as an argument to that
- // function.
- timer_.expires_from_now(boost::posix_time::milliseconds(SEND_INTERVAL));
- timer_.async_wait(boost::bind(&IOFetchTest::tcpSendData, this,
- socket));
- }
- }
-
- /// \brief Fetch completion callback
- ///
- /// This is the callback's operator() method which is called when the fetch
- /// is complete. It checks that the data received is the wire format of the
- /// data sent back by the server.
- ///
- /// \param result Result indicated by the callback
- void operator()(IOFetch::Result result) {
- if (debug_) {
- cout << "operator()(): result = " << result << endl;
- }
-
- EXPECT_EQ(expected_, result); // Check correct result returned
- EXPECT_FALSE(run_); // Check it is run only once
- run_ = true; // Note success
-
- // If the expected result for SUCCESS, then this should have been called
- // when one of the "servers" in this class has sent back return_data_.
- // Check the data is as expected/
- if (expected_ == IOFetch::SUCCESS) {
- // In the case of UDP, we actually send back a real looking packet
- // in the case of TCP, we send back a 'random' string
- if (protocol_ == IOFetch::UDP) {
- EXPECT_EQ(expected_buffer_->getLength(), result_buff_->getLength());
- EXPECT_EQ(0, memcmp(expected_buffer_->getData(), result_buff_->getData(),
- expected_buffer_->getLength()));
- } else {
- EXPECT_EQ(return_data_.size(), result_buff_->getLength());
- // Overwrite the random qid with our own data for the
- // comparison to succeed
- if (result_buff_->getLength() >= 2) {
- result_buff_->writeUint8At(return_data_[0], 0);
- result_buff_->writeUint8At(return_data_[1], 1);
- }
- const uint8_t* start = static_cast<const uint8_t*>(result_buff_->getData());
- EXPECT_TRUE(equal(return_data_.begin(), return_data_.end(), start));
- }
- }
-
- // ... and cause the run loop to exit.
- service_.stop();
- }
-
- // The next set of methods are the tests themselves. A number of the TCP
- // and UDP tests are very similar.
-
- /// \brief Check for stop()
- ///
- /// Test that when we run the query and stop it after it was run, it returns
- /// "stopped" correctly. (That is why stop() is posted to the service_ as
- /// well instead of calling it.)
- ///
- /// \param protocol Test protocol
- /// \param fetch Fetch object being tested
- void stopTest(IOFetch::Protocol protocol, IOFetch& fetch) {
- protocol_ = protocol;
- expected_ = IOFetch::STOPPED;
-
- // Post the query
- service_.get_io_service().post(fetch);
-
- // Post query_.stop() (yes, the boost::bind thing is just
- // query_.stop()).
- service_.get_io_service().post(
- boost::bind(&IOFetch::stop, fetch, IOFetch::STOPPED));
-
- // Run both of them. run() returns when everything in the I/O service
- // queue has completed.
- service_.run();
- EXPECT_TRUE(run_);
- }
-
- /// \brief Premature stop test
- ///
- /// Test that when we queue the query to service_ and call stop() before it
- /// gets executed, it acts sanely as well (eg. has the same result as
- /// running stop() after - calls the callback).
- ///
- /// \param protocol Test protocol
- /// \param fetch Fetch object being tested
- void prematureStopTest(IOFetch::Protocol protocol, IOFetch& fetch) {
- protocol_ = protocol;
- expected_ = IOFetch::STOPPED;
-
- // Stop before it is started
- fetch.stop();
- service_.get_io_service().post(fetch);
-
- service_.run();
- EXPECT_TRUE(run_);
- }
-
- /// \brief Timeout test
- ///
- /// Test that fetch times out when no answer arrives.
- ///
- /// \param protocol Test protocol
- /// \param fetch Fetch object being tested
- void timeoutTest(IOFetch::Protocol protocol, IOFetch& fetch) {
- protocol_ = protocol;
- expected_ = IOFetch::TIME_OUT;
-
- service_.get_io_service().post(fetch);
- service_.run();
- EXPECT_TRUE(run_);
- }
-
- /// \brief Send/Receive Test
- ///
- /// Send a query to the server then receives a response.
- ///
- /// \param Test data to return to client
- /// \param short_send If true, do not send all data
- /// (should result in timeout)
- void tcpSendReturnTest(const std::string& return_data, bool short_send = false) {
- if (debug_) {
- cout << "tcpSendReturnTest(): data size = " << return_data.size() << endl;
- }
- return_data_ = return_data;
- protocol_ = IOFetch::TCP;
- if (short_send) {
- tcp_short_send_ = true;
- expected_ = IOFetch::TIME_OUT;
- } else {
- expected_ = IOFetch::SUCCESS;
- }
-
- // Socket into which the connection will be accepted.
- tcp::socket socket(service_.get_io_service());
-
- // Acceptor object - called when the connection is made, the handler
- // will initiate a read on the socket.
- tcp::acceptor acceptor(service_.get_io_service(),
- tcp::endpoint(tcp::v4(), TEST_PORT));
- acceptor.async_accept(socket,
- boost::bind(&IOFetchTest::tcpAcceptHandler, this, &socket, _1));
-
- // Post the TCP fetch object to send the query and receive the response.
- service_.get_io_service().post(tcp_fetch_);
-
- // ... and execute all the callbacks. This exits when the fetch
- // completes.
- service_.run();
- EXPECT_TRUE(run_); // Make sure the callback did execute
-
- // Tidy up
- socket.close();
- }
-
- /// Perform a send/receive test over UDP
- ///
- /// \param bad_qid If true, do the test where the QID is mangled
- /// in the response
- /// \param second_send If true, do the test where the QID is
- /// mangled in the response, but a second
- /// (correct) packet is used
- void udpSendReturnTest(bool bad_qid, bool second_send) {
- protocol_ = IOFetch::UDP;
-
- // Set up the server.
- udp::socket socket(service_.get_io_service(), udp::v4());
- socket.set_option(socket_base::reuse_address(true));
- socket.bind(udp::endpoint(TEST_HOST, TEST_PORT));
- 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));
- service_.get_io_service().post(udp_fetch_);
- if (debug_) {
- cout << "udpSendReceive: async_receive_from posted, waiting for callback" <<
- endl;
- }
- service_.run();
-
- socket.close();
-
- EXPECT_TRUE(run_);;
- }
-};
-
-// Check the protocol
-TEST_F(IOFetchTest, Protocol) {
- EXPECT_EQ(IOFetch::UDP, udp_fetch_.getProtocol());
- EXPECT_EQ(IOFetch::TCP, tcp_fetch_.getProtocol());
-}
-
-// UDP Stop test - see IOFetchTest::stopTest() header.
-TEST_F(IOFetchTest, UdpStop) {
- stopTest(IOFetch::UDP, udp_fetch_);
-}
-
-// UDP premature stop test - see IOFetchTest::prematureStopTest() header.
-TEST_F(IOFetchTest, UdpPrematureStop) {
- prematureStopTest(IOFetch::UDP, udp_fetch_);
-}
-
-// UDP premature stop test - see IOFetchTest::timeoutTest() header.
-TEST_F(IOFetchTest, UdpTimeout) {
- timeoutTest(IOFetch::UDP, udp_fetch_);
-}
-
-// UDP SendReceive test. Set up a UDP server then ports a UDP fetch object.
-// This will send question_ to the server and receive the answer back from it.
-TEST_F(IOFetchTest, UdpSendReceive) {
- expected_ = IOFetch::SUCCESS;
-
- udpSendReturnTest(false, false);
-
- EXPECT_TRUE(run_);;
-}
-
-TEST_F(IOFetchTest, UdpSendReceiveBadQid) {
- expected_ = IOFetch::TIME_OUT;
-
- udpSendReturnTest(true, false);
-
- EXPECT_TRUE(run_);;
-}
-
-TEST_F(IOFetchTest, UdpSendReceiveBadQidResend) {
- expected_ = IOFetch::SUCCESS;
-
- udpSendReturnTest(true, true);
-
- EXPECT_TRUE(run_);;
-}
-
-// Do the same tests for TCP transport
-
-TEST_F(IOFetchTest, TcpStop) {
- stopTest(IOFetch::TCP, tcp_fetch_);
-}
-
-TEST_F(IOFetchTest, TcpPrematureStop) {
- prematureStopTest(IOFetch::TCP, tcp_fetch_);
-}
-
-TEST_F(IOFetchTest, TcpTimeout) {
- timeoutTest(IOFetch::TCP, tcp_fetch_);
-}
-
-// Test with values at or near 2, then at or near the chunk size (16 and 32
-// bytes, the sizes of the first two packets) then up to 65535. These are done
-// in separate tests because in practice a new IOFetch is created for each
-// query/response exchange and we don't want to confuse matters in the test
-// by running the test with an IOFetch that has already done one exchange.
-//
-// Don't do 0 or 1; the server would not accept the packet
-// (since the length is too short to check the qid)
-TEST_F(IOFetchTest, TcpSendReceive2) {
- tcpSendReturnTest(test_data_.substr(0, 2));
-}
-
-TEST_F(IOFetchTest, TcpSendReceive3) {
- tcpSendReturnTest(test_data_.substr(0, 3));
-}
-
-TEST_F(IOFetchTest, TcpSendReceive15) {
- tcpSendReturnTest(test_data_.substr(0, 15));
-}
-
-TEST_F(IOFetchTest, TcpSendReceive16) {
- tcpSendReturnTest(test_data_.substr(0, 16));
-}
-
-TEST_F(IOFetchTest, TcpSendReceive17) {
- tcpSendReturnTest(test_data_.substr(0, 17));
-}
-
-TEST_F(IOFetchTest, TcpSendReceive31) {
- tcpSendReturnTest(test_data_.substr(0, 31));
-}
-
-TEST_F(IOFetchTest, TcpSendReceive32) {
- tcpSendReturnTest(test_data_.substr(0, 32));
-}
-
-TEST_F(IOFetchTest, TcpSendReceive33) {
- tcpSendReturnTest(test_data_.substr(0, 33));
-}
-
-TEST_F(IOFetchTest, TcpSendReceive4096) {
- tcpSendReturnTest(test_data_.substr(0, 4096));
-}
-
-TEST_F(IOFetchTest, TcpSendReceive8192) {
- tcpSendReturnTest(test_data_.substr(0, 8192));
-}
-
-TEST_F(IOFetchTest, TcpSendReceive16384) {
- tcpSendReturnTest(test_data_.substr(0, 16384));
-}
-
-TEST_F(IOFetchTest, TcpSendReceive32768) {
- tcpSendReturnTest(test_data_.substr(0, 32768));
-}
-
-TEST_F(IOFetchTest, TcpSendReceive65535) {
- tcpSendReturnTest(test_data_.substr(0, 65535));
-}
-
-TEST_F(IOFetchTest, TcpSendReceive2ShortSend) {
- tcpSendReturnTest(test_data_.substr(0, 2), true);
-}
-
-TEST_F(IOFetchTest, TcpSendReceive15ShortSend) {
- tcpSendReturnTest(test_data_.substr(0, 15), true);
-}
-
-TEST_F(IOFetchTest, TcpSendReceive8192ShortSend) {
- tcpSendReturnTest(test_data_.substr(0, 8192), true);
-}
-
-
-} // namespace asiolink
diff --git a/src/lib/asiolink/tests/io_service_unittest.cc b/src/lib/asiolink/tests/io_service_unittest.cc
deleted file mode 100644
index 779d03e..0000000
--- a/src/lib/asiolink/tests/io_service_unittest.cc
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (C) 2011 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 <gtest/gtest.h>
-
-#include <asio.hpp>
-#include <asiolink/asiolink.h>
-
-using namespace asiolink;
-
-const char* const TEST_SERVER_PORT = "53535";
-const char* const TEST_CLIENT_PORT = "53536";
-const char* const TEST_IPV6_ADDR = "::1";
-const char* const TEST_IPV4_ADDR = "127.0.0.1";
-
-TEST(IOServiceTest, badPort) {
- IOService io_service;
- EXPECT_THROW(DNSService(io_service, *"65536", true, false, NULL, NULL, NULL), IOError);
- EXPECT_THROW(DNSService(io_service, *"53210.0", true, false, NULL, NULL, NULL), IOError);
- EXPECT_THROW(DNSService(io_service, *"-1", true, false, NULL, NULL, NULL), IOError);
- EXPECT_THROW(DNSService(io_service, *"domain", true, false, NULL, NULL, NULL), IOError);
-}
-
-TEST(IOServiceTest, badAddress) {
- IOService io_service;
- EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"192.0.2.1.1", NULL, NULL, NULL), IOError);
- EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"2001:db8:::1", NULL, NULL, NULL), IOError);
- EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"localhost", NULL, NULL, NULL), IOError);
-}
-
-TEST(IOServiceTest, unavailableAddress) {
- IOService io_service;
- // These addresses should generally be unavailable as a valid local
- // address, although there's no guarantee in theory.
- EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"192.0.2.0", NULL, NULL, NULL), IOError);
-
- // Some OSes would simply reject binding attempt for an AF_INET6 socket
- // to an IPv4-mapped IPv6 address. Even if those that allow it, since
- // the corresponding IPv4 address is the same as the one used in the
- // AF_INET socket case above, it should at least show the same result
- // as the previous one.
- EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"::ffff:192.0.2.0", NULL, NULL, NULL), IOError);
-}
-
-TEST(IOServiceTest, duplicateBind_v6) {
- // In each sub test case, second attempt should fail due to duplicate bind
- IOService io_service;
-
- // IPv6, "any" address
- DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, false, true, NULL, NULL, NULL);
- EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, false, true, NULL, NULL, NULL), IOError);
- delete dns_service;
-
-}
-
-TEST(IOServiceTest, duplicateBind_v6_address) {
- // In each sub test case, second attempt should fail due to duplicate bind
- IOService io_service;
-
- // IPv6, specific address
- DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, *TEST_IPV6_ADDR, NULL, NULL, NULL);
- EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *TEST_IPV6_ADDR, NULL, NULL, NULL), IOError);
- delete dns_service;
-
-}
-
-TEST(IOServiceTest, duplicateBind_v4) {
- // In each sub test case, second attempt should fail due to duplicate bind
- IOService io_service;
-
- // IPv4, "any" address
- DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, true, false, NULL, NULL, NULL);
- EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, true, false, NULL, NULL, NULL), IOError);
- delete dns_service;
-
-}
-
-TEST(IOServiceTest, duplicateBind_v4_address) {
- // In each sub test case, second attempt should fail due to duplicate bind
- IOService io_service;
-
- // IPv4, specific address
- DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, *TEST_IPV4_ADDR, NULL, NULL, NULL);
- EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *TEST_IPV4_ADDR, NULL, NULL, NULL), IOError);
- delete dns_service;
-}
-
-// Disabled because IPv4-mapped addresses don't seem to be working with
-// the IOService constructor
-TEST(IOServiceTest, DISABLED_IPv4MappedDuplicateBind) {
- IOService io_service;
- // Duplicate bind on IPv4-mapped IPv6 address
- DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, *"127.0.0.1", NULL, NULL, NULL);
- EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"::ffff:127.0.0.1", NULL, NULL, NULL), IOError);
- delete dns_service;
-
- // XXX:
- // Currently, this throws an "invalid argument" exception. I have
- // not been able to get IPv4-mapped addresses to work.
- dns_service = new DNSService(io_service, *TEST_SERVER_PORT, *"::ffff:127.0.0.1", NULL, NULL, NULL);
- EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"127.0.0.1", NULL, NULL, NULL), IOError);
- delete dns_service;
-}
-
diff --git a/src/lib/asiolink/tests/io_socket_unittest.cc b/src/lib/asiolink/tests/io_socket_unittest.cc
index 6538550..15afc17 100644
--- a/src/lib/asiolink/tests/io_socket_unittest.cc
+++ b/src/lib/asiolink/tests/io_socket_unittest.cc
@@ -20,7 +20,7 @@
#include <asio.hpp>
#include <asiolink/io_socket.h>
-using namespace asiolink;
+using namespace isc::asiolink;
TEST(IOSocketTest, dummySockets) {
EXPECT_EQ(IPPROTO_UDP, IOSocket::getDummyUDPSocket().getProtocol());
diff --git a/src/lib/asiolink/tests/tcp_endpoint_unittest.cc b/src/lib/asiolink/tests/tcp_endpoint_unittest.cc
index 3787e1c..6988082 100644
--- a/src/lib/asiolink/tests/tcp_endpoint_unittest.cc
+++ b/src/lib/asiolink/tests/tcp_endpoint_unittest.cc
@@ -22,7 +22,7 @@
#include <asiolink/io_address.h>
#include <asiolink/tcp_endpoint.h>
-using namespace asiolink;
+using namespace isc::asiolink;
using namespace std;
// This test checks that the endpoint can manage its own internal
diff --git a/src/lib/asiolink/tests/tcp_socket_unittest.cc b/src/lib/asiolink/tests/tcp_socket_unittest.cc
index 1784aa2..538cf48 100644
--- a/src/lib/asiolink/tests/tcp_socket_unittest.cc
+++ b/src/lib/asiolink/tests/tcp_socket_unittest.cc
@@ -46,8 +46,8 @@
using namespace asio;
using namespace asio::ip;
-using namespace asiolink;
using namespace isc::util;
+using namespace isc::asiolink;
using namespace std;
namespace {
diff --git a/src/lib/asiolink/tests/udp_endpoint_unittest.cc b/src/lib/asiolink/tests/udp_endpoint_unittest.cc
index 18135ec..03de6b8 100644
--- a/src/lib/asiolink/tests/udp_endpoint_unittest.cc
+++ b/src/lib/asiolink/tests/udp_endpoint_unittest.cc
@@ -22,7 +22,7 @@
#include <asiolink/io_address.h>
#include <asiolink/udp_endpoint.h>
-using namespace asiolink;
+using namespace isc::asiolink;
using namespace std;
// This test checks that the endpoint can manage its own internal
diff --git a/src/lib/asiolink/tests/udp_socket_unittest.cc b/src/lib/asiolink/tests/udp_socket_unittest.cc
index 2170ab6..1ab1a09 100644
--- a/src/lib/asiolink/tests/udp_socket_unittest.cc
+++ b/src/lib/asiolink/tests/udp_socket_unittest.cc
@@ -45,8 +45,8 @@
#include <asiolink/udp_socket.h>
using namespace asio;
-using namespace asiolink;
using namespace isc::util;
+using namespace isc::asiolink;
using namespace std;
namespace {
diff --git a/src/lib/asiolink/udp_endpoint.h b/src/lib/asiolink/udp_endpoint.h
index 99dc27f..5c8a1fe 100644
--- a/src/lib/asiolink/udp_endpoint.h
+++ b/src/lib/asiolink/udp_endpoint.h
@@ -21,6 +21,7 @@
#include <asiolink/io_endpoint.h>
+namespace isc {
namespace asiolink {
/// \brief The \c UDPEndpoint class is a concrete derived class of
@@ -109,5 +110,6 @@ private:
asio::ip::udp::endpoint& asio_endpoint_;
};
-} // namespace asiolink
+} // namespace asiolink
+} // namespace isc
#endif // __UDP_ENDPOINT_H
diff --git a/src/lib/asiolink/udp_server.cc b/src/lib/asiolink/udp_server.cc
deleted file mode 100644
index 5e9fe1d..0000000
--- a/src/lib/asiolink/udp_server.cc
+++ /dev/null
@@ -1,322 +0,0 @@
-// Copyright (C) 2011 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 <netinet/in.h>
-#include <sys/socket.h>
-#include <unistd.h> // for some IPC/network system calls
-#include <errno.h>
-
-#include <boost/shared_array.hpp>
-
-#include <config.h>
-
-#include <log/dummylog.h>
-
-#include <asio.hpp>
-#include <asio/error.hpp>
-#include <asiolink/dummy_io_cb.h>
-#include <asiolink/udp_endpoint.h>
-#include <asiolink/udp_server.h>
-#include <asiolink/udp_socket.h>
-
-#include <dns/opcode.h>
-
-using namespace asio;
-using asio::ip::udp;
-using isc::log::dlog;
-
-using namespace std;
-using namespace isc::dns;
-using namespace isc::util;
-
-namespace asiolink {
-
-/*
- * Some of the member variables here are shared_ptrs and some are
- * auto_ptrs. There will be one instance of Data for the lifetime
- * of packet. The variables that are state only for a single packet
- * use auto_ptr, as it is more lightweight. In the case of shared
- * configuration (eg. the callbacks, socket), we use shared_ptrs.
- */
-struct UDPServer::Data {
- /*
- * Constructor from parameters passed to UDPServer constructor.
- * This instance will not be used to retrieve and answer the actual
- * query, it will only hold parameters until we wait for the
- * first packet. But we do initialize the socket in here.
- */
- Data(io_service& io_service, const ip::address& addr, const uint16_t port,
- SimpleCallback* checkin, DNSLookup* lookup, DNSAnswer* answer) :
- io_(io_service), done_(false),
- checkin_callback_(checkin),lookup_callback_(lookup),
- answer_callback_(answer)
- {
- // We must use different instantiations for v4 and v6;
- // otherwise ASIO will bind to both
- udp proto = addr.is_v4() ? udp::v4() : udp::v6();
- socket_.reset(new udp::socket(io_service, proto));
- socket_->set_option(socket_base::reuse_address(true));
- if (addr.is_v6()) {
- socket_->set_option(asio::ip::v6_only(true));
- }
- socket_->bind(udp::endpoint(addr, port));
- }
-
- /*
- * Copy constructor. Default one would probably do, but it is unnecessary
- * to copy many of the member variables every time we fork to handle
- * another packet.
- *
- * We also allocate data for receiving the packet here.
- */
- Data(const Data& other) :
- io_(other.io_), socket_(other.socket_), done_(false),
- checkin_callback_(other.checkin_callback_),
- lookup_callback_(other.lookup_callback_),
- answer_callback_(other.answer_callback_)
- {
- // Instantiate the data buffer and endpoint that will
- // be used by the asynchronous receive call.
- data_.reset(new char[MAX_LENGTH]);
- sender_.reset(new udp::endpoint());
- }
-
- // The ASIO service object
- asio::io_service& io_;
-
- // Class member variables which are dynamic, and changes to which
- // need to accessible from both sides of a coroutine fork or from
- // outside of the coroutine (i.e., from an asynchronous I/O call),
- // should be declared here as pointers and allocated in the
- // constructor or in the coroutine. This allows state information
- // to persist when an individual copy of the coroutine falls out
- // scope while waiting for an event, *so long as* there is another
- // object that is referencing the same data. As a side-benefit, using
- // pointers also reduces copy overhead for coroutine objects.
- //
- // Note: Currently these objects are allocated by "new" in the
- // constructor, or in the function operator while processing a query.
- // Repeated allocations from the heap for every incoming query is
- // clearly a performance issue; this must be optimized in the future.
- // The plan is to have a structure pre-allocate several "Data"
- // objects which can be pulled off a free list and placed on an in-use
- // list whenever a query comes in. This will serve the dual purpose
- // of improving performance and guaranteeing that state information
- // will *not* be destroyed when any one instance of the coroutine
- // falls out of scope while waiting for an event.
- //
- // Socket used to for listen for queries. Created in the
- // constructor and stored in a shared_ptr because socket objects
- // are not copyable.
- boost::shared_ptr<asio::ip::udp::socket> socket_;
-
- // The ASIO-internal endpoint object representing the client
- std::auto_ptr<asio::ip::udp::endpoint> sender_;
-
- // \c IOMessage and \c Message objects to be passed to the
- // DNS lookup and answer providers
- std::auto_ptr<asiolink::IOMessage> io_message_;
-
- // The original query as sent by the client
- isc::dns::MessagePtr query_message_;
-
- // The response message we are building
- isc::dns::MessagePtr answer_message_;
-
- // The buffer into which the response is written
- isc::util::OutputBufferPtr respbuf_;
-
- // The buffer into which the query packet is written
- boost::shared_array<char> data_;
-
- // State information that is entirely internal to a given instance
- // of the coroutine can be declared here.
- size_t bytes_;
- bool done_;
-
-
- // Callback functions provided by the caller
- const SimpleCallback* checkin_callback_;
- const DNSLookup* lookup_callback_;
- const DNSAnswer* answer_callback_;
-
- std::auto_ptr<IOEndpoint> peer_;
- std::auto_ptr<IOSocket> iosock_;
-};
-
-/// The following functions implement the \c UDPServer class.
-///
-/// The constructor. It just creates new internal state object
-/// and lets it handle the initialization.
-UDPServer::UDPServer(io_service& io_service, const ip::address& addr,
- const uint16_t port, SimpleCallback* checkin, DNSLookup* lookup,
- DNSAnswer* answer) :
- data_(new Data(io_service, addr, port, checkin, lookup, answer))
-{ }
-
-/// The function operator is implemented with the "stackless coroutine"
-/// pattern; see internal/coroutine.h for details.
-void
-UDPServer::operator()(error_code ec, size_t length) {
- /// Because the coroutine reentry block is implemented as
- /// a switch statement, inline variable declarations are not
- /// permitted. Certain variables used below can be declared here.
-
- CORO_REENTER (this) {
- do {
- /*
- * This is preparation for receiving a packet. We get a new
- * state object for the lifetime of the next packet to come.
- * It allocates the buffers to receive data into.
- */
- data_.reset(new Data(*data_));
-
- do {
- // Begin an asynchronous receive, then yield.
- // When the receive event is posted, the coroutine
- // will resume immediately after this point.
- CORO_YIELD data_->socket_->async_receive_from(
- buffer(data_->data_.get(), MAX_LENGTH), *data_->sender_,
- *this);
-
- // Abort on fatal errors
- // TODO: add log
- if (ec) {
- using namespace asio::error;
- if (ec.value() != would_block && ec.value() != try_again &&
- ec.value() != interrupted) {
- return;
- }
- }
-
- } while (ec || length == 0);
-
- data_->bytes_ = length;
-
- /*
- * We fork the coroutine now. One (the child) will keep
- * the current state and handle the packet, then die and
- * drop ownership of the state. The other (parent) will just
- * go into the loop again and replace the current state with
- * a new one for a new object.
- *
- * Actually, both of the coroutines will be a copy of this
- * one, but that's just internal implementation detail.
- */
- CORO_FORK data_->io_.post(UDPServer(*this));
- } while (is_parent());
-
- // Create an \c IOMessage object to store the query.
- //
- // (XXX: It would be good to write a factory function
- // that would quickly generate an IOMessage object without
- // all these calls to "new".)
- data_->peer_.reset(new UDPEndpoint(*data_->sender_));
-
- // 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.
- data_->iosock_.reset(
- new UDPSocket<DummyIOCallback>(*data_->socket_));
-
- data_->io_message_.reset(new IOMessage(data_->data_.get(),
- data_->bytes_, *data_->iosock_, *data_->peer_));
-
- // Perform any necessary operations prior to processing an incoming
- // query (e.g., checking for queued configuration messages).
- //
- // (XXX: it may be a performance issue to check in for every single
- // incoming query; we may wish to throttle this in the future.)
- if (data_->checkin_callback_ != NULL) {
- (*data_->checkin_callback_)(*data_->io_message_);
- }
-
- // If we don't have a DNS Lookup provider, there's no point in
- // continuing; we exit the coroutine permanently.
- if (data_->lookup_callback_ == NULL) {
- CORO_YIELD return;
- }
-
- // Instantiate objects that will be needed by the
- // asynchronous DNS lookup and/or by the send call.
- data_->respbuf_.reset(new OutputBuffer(0));
- data_->query_message_.reset(new Message(Message::PARSE));
- data_->answer_message_.reset(new Message(Message::RENDER));
-
- // Schedule a DNS lookup, and yield. When the lookup is
- // finished, the coroutine will resume immediately after
- // this point.
- CORO_YIELD data_->io_.post(AsyncLookup<UDPServer>(*this));
-
- // The 'done_' flag indicates whether we have an answer
- // to send back. If not, exit the coroutine permanently.
- if (!data_->done_) {
- CORO_YIELD return;
- }
-
- // Call the DNS answer provider to render the answer into
- // wire format
- (*data_->answer_callback_)(*data_->io_message_, data_->query_message_,
- data_->answer_message_, data_->respbuf_);
-
- // Begin an asynchronous send, and then yield. When the
- // send completes, we will resume immediately after this point
- // (though we have nothing further to do, so the coroutine
- // will simply exit at that time).
- CORO_YIELD data_->socket_->async_send_to(
- buffer(data_->respbuf_->getData(), data_->respbuf_->getLength()),
- *data_->sender_, *this);
- }
-}
-
-/// Call the DNS lookup provider. (Expected to be called by the
-/// AsyncLookup<UDPServer> handler.)
-void
-UDPServer::asyncLookup() {
- (*data_->lookup_callback_)(*data_->io_message_,
- data_->query_message_, data_->answer_message_, data_->respbuf_, this);
-}
-
-/// Stop the UDPServer
-void
-UDPServer::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
- data_->socket_->close();
-}
-
-/// 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
-UDPServer::resume(const bool done) {
- data_->done_ = done;
- data_->io_.post(*this);
-}
-
-bool
-UDPServer::hasAnswer() {
- return (data_->done_);
-}
-
-} // namespace asiolink
diff --git a/src/lib/asiolink/udp_server.h b/src/lib/asiolink/udp_server.h
deleted file mode 100644
index 1d37471..0000000
--- a/src/lib/asiolink/udp_server.h
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright (C) 2011 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 __UDP_SERVER_H
-#define __UDP_SERVER_H 1
-
-#ifndef ASIO_HPP
-#error "asio.hpp must be included before including this, see asiolink.h as to why"
-#endif
-
-#include <asiolink/dns_server.h>
-#include <asiolink/simple_callback.h>
-#include <asiolink/dns_lookup.h>
-#include <asiolink/dns_answer.h>
-
-#include <coroutine.h>
-
-namespace asiolink {
-
-//
-// Asynchronous UDP server coroutine
-//
-///
-/// \brief This class implements the coroutine to handle UDP
-/// DNS query event. As such, it is both a \c DNSServer and
-/// a \c coroutine
-///
-class UDPServer : public virtual DNSServer, public virtual coroutine {
-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 UDPServer(asio::io_service& io_service,
- const asio::ip::address& addr, const uint16_t port,
- SimpleCallback* checkin = NULL,
- DNSLookup* lookup = NULL,
- DNSAnswer* answer = NULL);
-
- /// \brief The function operator
- void operator()(asio::error_code ec = asio::error_code(),
- size_t length = 0);
-
- /// \brief Calls the lookup callback
- void asyncLookup();
-
- /// \brief Stop the running server
- /// \note once the server stopped, it can't restart
- void stop();
-
- /// \brief Resume operation
- ///
- /// \param done Set this to true if the lookup action is done and
- /// 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
- DNSServer* clone() {
- UDPServer* s = new UDPServer(*this);
- return (s);
- }
-
-private:
- enum { MAX_LENGTH = 4096 };
-
- /**
- * \brief Internal state and data.
- *
- * We use the pimple design pattern, but not because we need to hide
- * internal data. This class and whole header is for private use anyway.
- * It turned out that UDPServer is copied a lot, because it is a coroutine.
- * This way the overhead of copying is lower, we copy only one shared
- * pointer instead of about 10 of them.
- */
- class Data;
- boost::shared_ptr<Data> data_;
-};
-
-} // namespace asiolink
-#endif // __UDP_SERVER_H
diff --git a/src/lib/asiolink/udp_socket.h b/src/lib/asiolink/udp_socket.h
index a03d3d4..c061fba 100644
--- a/src/lib/asiolink/udp_socket.h
+++ b/src/lib/asiolink/udp_socket.h
@@ -33,6 +33,7 @@
#include <asiolink/io_service.h>
#include <asiolink/udp_endpoint.h>
+namespace isc {
namespace asiolink {
/// \brief The \c UDPSocket class is a concrete derived class of \c IOAsioSocket
@@ -318,5 +319,6 @@ UDPSocket<C>::close() {
}
} // namespace asiolink
+} // namespace isc
#endif // __UDP_SOCKET_H
diff --git a/src/lib/datasrc/tests/rbtree_unittest.cc b/src/lib/datasrc/tests/rbtree_unittest.cc
index dd1b7fe..b26a22b 100644
--- a/src/lib/datasrc/tests/rbtree_unittest.cc
+++ b/src/lib/datasrc/tests/rbtree_unittest.cc
@@ -398,7 +398,7 @@ TEST_F(RBTreeTest, getLastComparedNode) {
EXPECT_EQ(static_cast<void*>(NULL), chain.getLastComparedNode());
chain.clear();
- const RBNode<int>* expected_node;
+ const RBNode<int>* expected_node = NULL;
// Exact match case. The returned node should be last compared.
EXPECT_EQ(RBTree<int>::EXACTMATCH,
diff --git a/src/lib/dns/Makefile.am b/src/lib/dns/Makefile.am
index b7fb9b1..9b42e8c 100644
--- a/src/lib/dns/Makefile.am
+++ b/src/lib/dns/Makefile.am
@@ -1,6 +1,7 @@
SUBDIRS = . tests python
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
AM_CPPFLAGS += -I$(top_srcdir)/src/lib/util -I$(top_builddir)/src/lib/util
AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CXXFLAGS = $(B10_CXXFLAGS)
diff --git a/src/lib/dns/python/edns_python.cc b/src/lib/dns/python/edns_python.cc
index 07dcc14..d781e89 100644
--- a/src/lib/dns/python/edns_python.cc
+++ b/src/lib/dns/python/edns_python.cc
@@ -298,12 +298,15 @@ EDNS_getUDPSize(const s_EDNS* const self) {
PyObject*
EDNS_setUDPSize(s_EDNS* self, PyObject* args) {
- unsigned int size;
- if (!PyArg_ParseTuple(args, "I", &size)) {
+ long size;
+ if (!PyArg_ParseTuple(args, "l", &size)) {
+ PyErr_Clear();
+ PyErr_SetString(PyExc_TypeError,
+ "No valid type in set_udp_size argument");
return (NULL);
}
- if (size > 65535) {
- PyErr_SetString(PyExc_OverflowError,
+ if (size < 0 || size > 0xffff) {
+ PyErr_SetString(PyExc_ValueError,
"UDP size is not an unsigned 16-bit integer");
return (NULL);
}
diff --git a/src/lib/dns/python/message_python.cc b/src/lib/dns/python/message_python.cc
index 30100f4..058312e 100644
--- a/src/lib/dns/python/message_python.cc
+++ b/src/lib/dns/python/message_python.cc
@@ -227,9 +227,9 @@ static PyTypeObject message_type = {
static int
Message_init(s_Message* self, PyObject* args) {
- unsigned int i;
-
- if (PyArg_ParseTuple(args, "I", &i)) {
+ int i;
+
+ if (PyArg_ParseTuple(args, "i", &i)) {
PyErr_Clear();
if (i == Message::PARSE) {
self->message = new Message(Message::PARSE);
@@ -275,17 +275,17 @@ Message_getHeaderFlag(s_Message* self, PyObject* args) {
static PyObject*
Message_setHeaderFlag(s_Message* self, PyObject* args) {
- int messageflag;
+ long messageflag;
PyObject *on = Py_True;
- if (!PyArg_ParseTuple(args, "i|O!", &messageflag, &PyBool_Type, &on)) {
+ if (!PyArg_ParseTuple(args, "l|O!", &messageflag, &PyBool_Type, &on)) {
PyErr_Clear();
PyErr_SetString(PyExc_TypeError,
"no valid type in set_header_flag argument");
return (NULL);
}
- if (messageflag < 0) {
- PyErr_SetString(PyExc_TypeError, "invalid Message header flag");
+ if (messageflag < 0 || messageflag > 0xffff) {
+ PyErr_SetString(PyExc_ValueError, "Message header flag out of range");
return (NULL);
}
@@ -311,10 +311,19 @@ Message_getQid(s_Message* self) {
static PyObject*
Message_setQid(s_Message* self, PyObject* args) {
- uint16_t id;
- if (!PyArg_ParseTuple(args, "H", &id)) {
+ long id;
+ if (!PyArg_ParseTuple(args, "l", &id)) {
+ PyErr_Clear();
+ PyErr_SetString(PyExc_TypeError,
+ "no valid type in set_qid argument");
return (NULL);
}
+ if (id < 0 || id > 0xffff) {
+ PyErr_SetString(PyExc_ValueError,
+ "Message id out of range");
+ return (NULL);
+ }
+
try {
self->message->setQid(id);
Py_RETURN_NONE;
@@ -566,9 +575,9 @@ Message_addQuestion(s_Message* self, PyObject* args) {
static PyObject*
Message_addRRset(s_Message* self, PyObject* args) {
PyObject *sign = Py_False;
- unsigned int section;
+ int section;
s_RRset* rrset;
- if (!PyArg_ParseTuple(args, "IO!|O!", §ion, &rrset_type, &rrset,
+ if (!PyArg_ParseTuple(args, "iO!|O!", §ion, &rrset_type, &rrset,
&PyBool_Type, &sign)) {
return (NULL);
}
@@ -592,8 +601,8 @@ Message_addRRset(s_Message* self, PyObject* args) {
static PyObject*
Message_clear(s_Message* self, PyObject* args) {
- unsigned int i;
- if (PyArg_ParseTuple(args, "I", &i)) {
+ int i;
+ if (PyArg_ParseTuple(args, "i", &i)) {
PyErr_Clear();
if (i == Message::PARSE) {
self->message->clear(Message::PARSE);
diff --git a/src/lib/dns/python/messagerenderer_python.cc b/src/lib/dns/python/messagerenderer_python.cc
index 139475a..85a4f17 100644
--- a/src/lib/dns/python/messagerenderer_python.cc
+++ b/src/lib/dns/python/messagerenderer_python.cc
@@ -179,8 +179,16 @@ static PyObject*
MessageRenderer_setLengthLimit(s_MessageRenderer* self,
PyObject* args)
{
- unsigned int lengthlimit;
- if (!PyArg_ParseTuple(args, "I", &lengthlimit)) {
+ long lengthlimit;
+ if (!PyArg_ParseTuple(args, "l", &lengthlimit)) {
+ PyErr_Clear();
+ PyErr_SetString(PyExc_TypeError,
+ "No valid type in set_length_limit argument");
+ return (NULL);
+ }
+ if (lengthlimit < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "MessageRenderer length limit out of range");
return (NULL);
}
self->messagerenderer->setLengthLimit(lengthlimit);
@@ -191,8 +199,8 @@ static PyObject*
MessageRenderer_setCompressMode(s_MessageRenderer* self,
PyObject* args)
{
- unsigned int mode;
- if (!PyArg_ParseTuple(args, "I", &mode)) {
+ int mode;
+ if (!PyArg_ParseTuple(args, "i", &mode)) {
return (NULL);
}
diff --git a/src/lib/dns/python/name_python.cc b/src/lib/dns/python/name_python.cc
index b36e313..b030ba1 100644
--- a/src/lib/dns/python/name_python.cc
+++ b/src/lib/dns/python/name_python.cc
@@ -322,14 +322,20 @@ Name_init(s_Name* self, PyObject* args) {
PyObject* bytes_obj;
const char* bytes;
Py_ssize_t len;
- unsigned int position = 0;
+ long position = 0;
// It was not a string (see comment above), so try bytes, and
// create with buffer object
- if (PyArg_ParseTuple(args, "O|IO!", &bytes_obj, &position,
+ if (PyArg_ParseTuple(args, "O|lO!", &bytes_obj, &position,
&PyBool_Type, &downcase) &&
PyObject_AsCharBuffer(bytes_obj, &bytes, &len) != -1) {
try {
+ if (position < 0) {
+ // Throw IndexError here since name index should be unsigned
+ PyErr_SetString(PyExc_IndexError,
+ "Name index shouldn't be negative");
+ return (-1);
+ }
InputBuffer buffer(bytes, len);
buffer.setPosition(position);
@@ -364,10 +370,17 @@ Name_destroy(s_Name* self) {
static PyObject*
Name_at(s_Name* self, PyObject* args) {
- unsigned int pos;
- if (!PyArg_ParseTuple(args, "I", &pos)) {
+ int pos;
+ if (!PyArg_ParseTuple(args, "i", &pos)) {
+ return (NULL);
+ }
+ if (pos < 0) {
+ // Throw IndexError here since name index should be unsigned
+ PyErr_SetString(PyExc_IndexError,
+ "name index shouldn't be negative");
return (NULL);
}
+
try {
return (Py_BuildValue("I", self->name->at(pos)));
} catch (const isc::OutOfRange&) {
@@ -406,10 +419,10 @@ static PyObject*
Name_toWire(s_Name* self, PyObject* args) {
PyObject* bytes;
s_MessageRenderer* mr;
-
+
if (PyArg_ParseTuple(args, "O", &bytes) && PySequence_Check(bytes)) {
PyObject* bytes_o = bytes;
-
+
OutputBuffer buffer(Name::MAX_WIRE);
self->name->toWire(buffer);
PyObject* name_bytes = PyBytes_FromStringAndSize(static_cast<const char*>(buffer.getData()), buffer.getLength());
@@ -458,12 +471,18 @@ Name_equals(s_Name* self, PyObject* args) {
Py_RETURN_FALSE;
}
-static PyObject*
+static PyObject*
Name_split(s_Name* self, PyObject* args) {
- unsigned int first, n;
+ int first, n;
s_Name* ret = NULL;
-
- if (PyArg_ParseTuple(args, "II", &first, &n)) {
+
+ if (PyArg_ParseTuple(args, "ii", &first, &n)) {
+ if (first < 0 || n < 0) {
+ // Throw IndexError here since name index should be unsigned
+ PyErr_SetString(PyExc_IndexError,
+ "name index shouldn't be negative");
+ return (NULL);
+ }
ret = PyObject_New(s_Name, &name_type);
if (ret != NULL) {
ret->name = NULL;
@@ -478,7 +497,14 @@ Name_split(s_Name* self, PyObject* args) {
return (NULL);
}
}
- } else if (PyArg_ParseTuple(args, "I", &n)) {
+ } else if (PyArg_ParseTuple(args, "i", &n)) {
+ PyErr_Clear();
+ if (n < 0) {
+ // Throw IndexError here since name index should be unsigned
+ PyErr_SetString(PyExc_IndexError,
+ "name index shouldn't be negative");
+ return (NULL);
+ }
ret = PyObject_New(s_Name, &name_type);
if (ret != NULL) {
ret->name = NULL;
@@ -494,6 +520,10 @@ Name_split(s_Name* self, PyObject* args) {
}
}
}
+
+ PyErr_Clear();
+ PyErr_SetString(PyExc_TypeError,
+ "No valid type in split argument");
return (ret);
}
#include <iostream>
@@ -503,7 +533,7 @@ Name_split(s_Name* self, PyObject* args) {
// It is translated to a function that gets 3 arguments, an object,
// an object to compare to, and an operator.
//
-static PyObject*
+static PyObject*
Name_richcmp(s_Name* self, s_Name* other, int op) {
bool c;
diff --git a/src/lib/dns/python/question_python.cc b/src/lib/dns/python/question_python.cc
index a039284..2889350 100644
--- a/src/lib/dns/python/question_python.cc
+++ b/src/lib/dns/python/question_python.cc
@@ -169,7 +169,7 @@ Question_init(s_Question* self, PyObject* args) {
}
self->question = QuestionPtr();
-
+
PyErr_Clear();
PyErr_SetString(PyExc_TypeError,
"no valid type in constructor argument");
diff --git a/src/lib/dns/python/rcode_python.cc b/src/lib/dns/python/rcode_python.cc
index fce8eef..b80a93c 100644
--- a/src/lib/dns/python/rcode_python.cc
+++ b/src/lib/dns/python/rcode_python.cc
@@ -171,18 +171,18 @@ PyTypeObject rcode_type = {
int
Rcode_init(s_Rcode* const self, PyObject* args) {
- int code = 0;
+ long code = 0;
int ext_code = 0;
- if (PyArg_ParseTuple(args, "i", &code)) {
+ if (PyArg_ParseTuple(args, "l", &code)) {
if (code < 0 || code > 0xffff) {
- PyErr_SetString(PyExc_OverflowError, "Rcode out of range");
+ PyErr_SetString(PyExc_ValueError, "Rcode out of range");
return (-1);
}
ext_code = -1;
- } else if (PyArg_ParseTuple(args, "ii", &code, &ext_code)) {
+ } else if (PyArg_ParseTuple(args, "li", &code, &ext_code)) {
if (code < 0 || code > 0xff || ext_code < 0 || ext_code > 0xff) {
- PyErr_SetString(PyExc_OverflowError, "Rcode out of range");
+ PyErr_SetString(PyExc_ValueError, "Rcode out of range");
return (-1);
}
} else {
diff --git a/src/lib/dns/python/rrclass_python.cc b/src/lib/dns/python/rrclass_python.cc
index 8e8b60b..6d150c2 100644
--- a/src/lib/dns/python/rrclass_python.cc
+++ b/src/lib/dns/python/rrclass_python.cc
@@ -153,7 +153,7 @@ static PyTypeObject rrclass_type = {
static int
RRClass_init(s_RRClass* self, PyObject* args) {
const char* s;
- unsigned int i;
+ long i;
PyObject* bytes = NULL;
// The constructor argument can be a string ("IN"), an integer (1),
// or a sequence of numbers between 0 and 65535 (wire code)
@@ -166,10 +166,11 @@ RRClass_init(s_RRClass* self, PyObject* args) {
if (PyArg_ParseTuple(args, "s", &s)) {
self->rrclass = new RRClass(s);
return (0);
- } else if (PyArg_ParseTuple(args, "I", &i)) {
- PyErr_Clear();
- if (i > 65535) {
- PyErr_SetString(po_InvalidRRClass, "RR class number too high");
+ } else if (PyArg_ParseTuple(args, "l", &i)) {
+ if (i < 0 || i > 0xffff) {
+ PyErr_Clear();
+ PyErr_SetString(PyExc_ValueError,
+ "RR class number out of range");
return (-1);
}
self->rrclass = new RRClass(i);
diff --git a/src/lib/dns/python/rrttl_python.cc b/src/lib/dns/python/rrttl_python.cc
index db9d736..c4b25bf 100644
--- a/src/lib/dns/python/rrttl_python.cc
+++ b/src/lib/dns/python/rrttl_python.cc
@@ -146,7 +146,7 @@ static PyTypeObject rrttl_type = {
static int
RRTTL_init(s_RRTTL* self, PyObject* args) {
const char* s;
- unsigned long i;
+ long long i;
PyObject* bytes = NULL;
// The constructor argument can be a string ("1234"), an integer (1),
// or a sequence of numbers between 0 and 255 (wire code)
@@ -159,8 +159,12 @@ RRTTL_init(s_RRTTL* self, PyObject* args) {
if (PyArg_ParseTuple(args, "s", &s)) {
self->rrttl = new RRTTL(s);
return (0);
- } else if (PyArg_ParseTuple(args, "I", &i)) {
+ } else if (PyArg_ParseTuple(args, "L", &i)) {
PyErr_Clear();
+ if (i < 0 || i > 0xffffffff) {
+ PyErr_SetString(PyExc_ValueError, "RR TTL number out of range");
+ return (-1);
+ }
self->rrttl = new RRTTL(i);
return (0);
} else if (PyArg_ParseTuple(args, "O", &bytes) &&
diff --git a/src/lib/dns/python/rrtype_python.cc b/src/lib/dns/python/rrtype_python.cc
index 10895c6..00e0acd 100644
--- a/src/lib/dns/python/rrtype_python.cc
+++ b/src/lib/dns/python/rrtype_python.cc
@@ -183,7 +183,7 @@ static PyTypeObject rrtype_type = {
static int
RRType_init(s_RRType* self, PyObject* args) {
const char* s;
- unsigned int i;
+ long i;
PyObject* bytes = NULL;
// The constructor argument can be a string ("A"), an integer (1),
// or a sequence of numbers between 0 and 65535 (wire code)
@@ -196,10 +196,10 @@ RRType_init(s_RRType* self, PyObject* args) {
if (PyArg_ParseTuple(args, "s", &s)) {
self->rrtype = new RRType(s);
return (0);
- } else if (PyArg_ParseTuple(args, "I", &i)) {
+ } else if (PyArg_ParseTuple(args, "l", &i)) {
PyErr_Clear();
- if (i > 65535) {
- PyErr_SetString(po_InvalidRRType, "RR Type number too high");
+ if (i < 0 || i > 0xffff) {
+ PyErr_SetString(PyExc_ValueError, "RR Type number out of range");
return (-1);
}
self->rrtype = new RRType(i);
@@ -260,10 +260,10 @@ static PyObject*
RRType_toWire(s_RRType* self, PyObject* args) {
PyObject* bytes;
s_MessageRenderer* mr;
-
+
if (PyArg_ParseTuple(args, "O", &bytes) && PySequence_Check(bytes)) {
PyObject* bytes_o = bytes;
-
+
OutputBuffer buffer(2);
self->rrtype->toWire(buffer);
PyObject* n = PyBytes_FromStringAndSize(static_cast<const char*>(buffer.getData()), buffer.getLength());
diff --git a/src/lib/dns/python/tests/edns_python_test.py b/src/lib/dns/python/tests/edns_python_test.py
index 3f03c90..b249213 100644
--- a/src/lib/dns/python/tests/edns_python_test.py
+++ b/src/lib/dns/python/tests/edns_python_test.py
@@ -62,17 +62,16 @@ class EDNSTest(unittest.TestCase):
edns = EDNS()
edns.set_udp_size(511)
self.assertEqual(511, edns.get_udp_size())
- edns.set_udp_size(0)
- self.assertEqual(0, edns.get_udp_size())
- edns.set_udp_size(65535)
- self.assertEqual(65535, edns.get_udp_size())
-
self.assertRaises(TypeError, edns.set_udp_size, "wrong")
# Range check. We need to do this at the binding level, so we need
# explicit tests for it.
- self.assertRaises(OverflowError, edns.set_udp_size, 65536)
- self.assertRaises(OverflowError, edns.set_udp_size, -1)
+ edns.set_udp_size(0)
+ self.assertEqual(0, edns.get_udp_size())
+ edns.set_udp_size(65535)
+ self.assertEqual(65535, edns.get_udp_size())
+ self.assertRaises(ValueError, edns.set_udp_size, 0x10000)
+ self.assertRaises(ValueError, edns.set_udp_size, -1)
def test_get_version(self):
self.assertEqual(EDNS.SUPPORTED_VERSION, EDNS().get_version())
diff --git a/src/lib/dns/python/tests/message_python_test.py b/src/lib/dns/python/tests/message_python_test.py
index 6ef42d4..bccc596 100644
--- a/src/lib/dns/python/tests/message_python_test.py
+++ b/src/lib/dns/python/tests/message_python_test.py
@@ -80,8 +80,10 @@ class MessageTest(unittest.TestCase):
"2001:db8::134"))
self.bogus_section = Message.SECTION_ADDITIONAL + 1
+ self.bogus_below_section = Message.SECTION_QUESTION - 1
def test_init(self):
+ self.assertRaises(TypeError, Message, -1)
self.assertRaises(TypeError, Message, 3)
self.assertRaises(TypeError, Message, "wrong")
@@ -109,22 +111,28 @@ class MessageTest(unittest.TestCase):
self.assertRaises(InvalidParameter, self.r.set_header_flag, 0)
self.assertRaises(InvalidParameter, self.r.set_header_flag, 0x7000)
self.assertRaises(InvalidParameter, self.r.set_header_flag, 0x0800)
- self.assertRaises(InvalidParameter, self.r.set_header_flag, 0x10000)
- self.assertRaises(TypeError, self.r.set_header_flag, 0x80000000)
- # this would cause overflow and result in a "valid" flag
- self.assertRaises(TypeError, self.r.set_header_flag,
- Message.HEADERFLAG_AA | 0x100000000)
- self.assertRaises(TypeError, self.r.set_header_flag, -1)
-
self.assertRaises(InvalidMessageOperation,
self.p.set_header_flag, Message.HEADERFLAG_AA)
+ # Range check. We need to do this at the binding level, so we need
+ # explicit tests for it.
+ self.assertRaises(ValueError, self.r.set_header_flag, 0x10000)
+ self.assertRaises(ValueError, self.r.set_header_flag, -1)
+
def test_set_qid(self):
self.assertRaises(TypeError, self.r.set_qid, "wrong")
self.assertRaises(InvalidMessageOperation,
self.p.set_qid, 123)
self.r.set_qid(1234)
self.assertEqual(1234, self.r.get_qid())
+ # Range check. We need to do this at the binding level, so we need
+ # explicit tests for it.
+ self.r.set_qid(0)
+ self.assertEqual(0, self.r.get_qid())
+ self.r.set_qid(0xffff)
+ self.assertEqual(0xffff, self.r.get_qid())
+ self.assertRaises(ValueError, self.r.set_qid, -1)
+ self.assertRaises(ValueError, self.r.set_qid, 0x10000)
def test_set_rcode(self):
self.assertRaises(TypeError, self.r.set_rcode, "wrong")
@@ -135,7 +143,7 @@ class MessageTest(unittest.TestCase):
self.assertRaises(InvalidMessageOperation,
self.p.set_rcode, rcode)
-
+
self.assertRaises(InvalidMessageOperation, self.p.get_rcode)
def test_set_opcode(self):
@@ -197,7 +205,7 @@ class MessageTest(unittest.TestCase):
self.assertRaises(InvalidMessageOperation, self.p.add_rrset,
Message.SECTION_ANSWER, self.rrset_a)
-
+
self.assertFalse(compare_rrset_list(section_rrset, self.r.get_section(Message.SECTION_ANSWER)))
self.assertEqual(0, self.r.get_rr_count(Message.SECTION_ANSWER))
self.r.add_rrset(Message.SECTION_ANSWER, self.rrset_a)
@@ -239,6 +247,8 @@ class MessageTest(unittest.TestCase):
Message.SECTION_ANSWER, self.rrset_a)
self.assertRaises(OverflowError, self.r.add_rrset,
self.bogus_section, self.rrset_a)
+ self.assertRaises(OverflowError, self.r.add_rrset,
+ self.bogus_below_section, self.rrset_a)
def test_clear(self):
self.assertEqual(None, self.r.clear(Message.PARSE))
diff --git a/src/lib/dns/python/tests/messagerenderer_python_test.py b/src/lib/dns/python/tests/messagerenderer_python_test.py
index 544ad23..5362496 100644
--- a/src/lib/dns/python/tests/messagerenderer_python_test.py
+++ b/src/lib/dns/python/tests/messagerenderer_python_test.py
@@ -98,6 +98,11 @@ class MessageRendererTest(unittest.TestCase):
renderer.set_length_limit(1024)
self.assertEqual(1024, renderer.get_length_limit())
self.assertRaises(TypeError, renderer.set_length_limit, "wrong")
+ # Range check. We need to do this at the binding level, so we need
+ # explicit tests for it.
+ renderer.set_length_limit(0)
+ self.assertEqual(0, renderer.get_length_limit())
+ self.assertRaises(ValueError, renderer.set_length_limit, -1)
def test_messagerenderer_set_compress_mode(self):
renderer = MessageRenderer()
diff --git a/src/lib/dns/python/tests/name_python_test.py b/src/lib/dns/python/tests/name_python_test.py
index 81060e9..b8e625a 100644
--- a/src/lib/dns/python/tests/name_python_test.py
+++ b/src/lib/dns/python/tests/name_python_test.py
@@ -95,11 +95,14 @@ class NameTest(unittest.TestCase):
b = bytearray()
b += b'\x07example'*32 + b'\x03com\x00'
self.assertRaises(DNSMessageFORMERR, Name, b, 0)
+ self.assertRaises(IndexError, Name, b, -1)
def test_at(self):
self.assertEqual(7, self.name1.at(0))
self.assertEqual(101, self.name1.at(1))
self.assertRaises(IndexError, self.name1.at, 100)
+ self.assertRaises(IndexError, self.name1.at, 0x10000)
+ self.assertRaises(IndexError, self.name1.at, -1)
self.assertRaises(TypeError, self.name1.at, "wrong")
def test_get_length(self):
@@ -151,14 +154,25 @@ class NameTest(unittest.TestCase):
self.assertEqual("completely.different.", s.to_text())
self.assertRaises(TypeError, self.name1.split, "wrong", 1)
self.assertRaises(TypeError, self.name1.split, 1, "wrong")
- self.assertRaises(IndexError, self.name1.split, 123, 1)
- self.assertRaises(IndexError, self.name1.split, 1, 123)
s = self.name1.split(1)
self.assertEqual("com.", s.to_text())
+
+ # Range check. We need to do this at the binding level, so we need
+ # explicit tests for it.
+ self.assertRaises(IndexError, self.name1.split, 123, 1)
+ self.assertRaises(IndexError, self.name1.split, 1, 123)
+ self.assertRaises(IndexError, self.name1.split, 0x10000, 5)
+ self.assertRaises(IndexError, self.name1.split, -1, -1)
+ self.assertRaises(IndexError, self.name1.split, 0, -1)
+ self.assertRaises(IndexError, self.name1.split, -1, 0x10000)
+
s = self.name1.split(0)
self.assertEqual("example.com.", s.to_text())
self.assertRaises(IndexError, self.name1.split, 123)
+ self.assertRaises(IndexError, self.name1.split, 0x10000)
+ self.assertRaises(IndexError, self.name1.split, -123)
+ self.assertRaises(TypeError, self.name1.split, -1)
def test_reverse(self):
self.assertEqual("com.example.", self.name1.reverse().to_text())
@@ -169,7 +183,6 @@ class NameTest(unittest.TestCase):
self.assertEqual("example.com.example.com.", self.name1.concatenate(self.name1).to_text())
self.assertRaises(TypeError, self.name1.concatenate, "wrong")
self.assertRaises(TooLongName, self.name1.concatenate, Name("example."*31))
-
def test_downcase(self):
self.assertEqual("EXAMPLE.com.", self.name4.to_text())
diff --git a/src/lib/dns/python/tests/question_python_test.py b/src/lib/dns/python/tests/question_python_test.py
index 6c4db4b..69e3051 100644
--- a/src/lib/dns/python/tests/question_python_test.py
+++ b/src/lib/dns/python/tests/question_python_test.py
@@ -45,7 +45,7 @@ class QuestionTest(unittest.TestCase):
# tests below based on cpp unit tests
# also tests get_name, get_class and get_type
def test_from_wire(self):
-
+
q = question_from_wire("question_fromWire")
self.assertEqual(self.example_name1, q.get_name())
diff --git a/src/lib/dns/python/tests/rcode_python_test.py b/src/lib/dns/python/tests/rcode_python_test.py
index 3577f84..77fed3a 100644
--- a/src/lib/dns/python/tests/rcode_python_test.py
+++ b/src/lib/dns/python/tests/rcode_python_test.py
@@ -23,12 +23,8 @@ from pydnspp import *
class RcodeTest(unittest.TestCase):
def test_init(self):
self.assertRaises(TypeError, Rcode, "wrong")
- self.assertRaises(OverflowError, Rcode, 65536)
- self.assertEqual(Rcode(0).get_code(), 0)
-
- self.assertEqual(0, Rcode(0).get_code())
self.assertEqual(0xfff, Rcode(0xfff).get_code()) # possible max code
-
+
# should fail on attempt of construction with an out of range code
self.assertRaises(OverflowError, Rcode, 0x1000)
self.assertRaises(OverflowError, Rcode, 0xffff)
@@ -38,7 +34,18 @@ class RcodeTest(unittest.TestCase):
self.assertEqual(Rcode.BADVERS_CODE, Rcode(0, 1).get_code())
self.assertEqual(0xfff, Rcode(0xf, 0xff).get_code())
self.assertRaises(OverflowError, Rcode, 0x10, 0xff)
-
+
+ # Range check. We need to do this at the binding level, so we need
+ # explicit tests for it.
+ self.assertEqual(Rcode(0).get_code(), 0)
+ self.assertEqual(Rcode(4095).get_code(), 4095)
+ self.assertEqual(Rcode(0, 0).get_code(), 0)
+ self.assertEqual(Rcode(0, 0).get_extended_code(), 0)
+ self.assertEqual(Rcode(15, 255).get_code(), 4095)
+ self.assertRaises(ValueError, Rcode, 65536)
+ self.assertRaises(ValueError, Rcode, 0x10, 0x100)
+ self.assertRaises(ValueError, Rcode, 0x100, 0x10)
+
def test_constants(self):
self.assertEqual(Rcode.NOERROR_CODE, Rcode(0).get_code())
self.assertEqual(Rcode.FORMERR_CODE, Rcode(1).get_code())
diff --git a/src/lib/dns/python/tests/rrclass_python_test.py b/src/lib/dns/python/tests/rrclass_python_test.py
index b5e8b5e..38d8c8c 100644
--- a/src/lib/dns/python/tests/rrclass_python_test.py
+++ b/src/lib/dns/python/tests/rrclass_python_test.py
@@ -32,12 +32,17 @@ class RRClassTest(unittest.TestCase):
b = bytearray(1)
b[0] = 123
self.assertRaises(TypeError, RRClass, b)
- self.assertRaises(InvalidRRClass, RRClass, 65536)
self.assertEqual(self.c1, RRClass(1))
b = bytearray()
self.c1.to_wire(b)
self.assertEqual(self.c1, RRClass(b))
-
+ # Range check. We need to do this at the binding level, so we need
+ # explicit tests for it.
+ self.assertRaises(ValueError, RRClass, 65536)
+ self.assertRaises(TypeError, RRClass, -1)
+ self.assertEqual(RRClass(65535).get_code(), 65535)
+ self.assertEqual(RRClass(0).get_code(), 0)
+
def test_rrclass_to_text(self):
self.assertEqual("IN", self.c1.to_text())
self.assertEqual("IN", str(self.c1))
diff --git a/src/lib/dns/python/tests/rrttl_python_test.py b/src/lib/dns/python/tests/rrttl_python_test.py
index 095a0b1..aa4a34d 100644
--- a/src/lib/dns/python/tests/rrttl_python_test.py
+++ b/src/lib/dns/python/tests/rrttl_python_test.py
@@ -25,7 +25,7 @@ class RRTTLTest(unittest.TestCase):
def setUp(self):
self.t1 = RRTTL(1)
self.t2 = RRTTL(3600)
-
+
def test_init(self):
self.assertRaises(InvalidRRTTL, RRTTL, "wrong")
self.assertRaises(TypeError, RRTTL, Exception())
@@ -39,7 +39,13 @@ class RRTTLTest(unittest.TestCase):
b[2] = 0
b[3] = 15
self.assertEqual(15, RRTTL(b).get_value())
-
+ # Range check. We need to do this at the binding level, so we need
+ # explicit tests for it.
+ self.assertRaises(TypeError, RRTTL, -1)
+ self.assertRaises(ValueError, RRTTL, 4294967296)
+ self.assertEqual(0, RRTTL(0).get_value())
+ self.assertEqual(4294967295, RRTTL(4294967295).get_value())
+
def test_rrttl_to_text(self):
self.assertEqual("1", self.t1.to_text())
self.assertEqual("1", str(self.t1))
diff --git a/src/lib/dns/python/tests/rrtype_python_test.py b/src/lib/dns/python/tests/rrtype_python_test.py
index c35e1e7..7135426 100644
--- a/src/lib/dns/python/tests/rrtype_python_test.py
+++ b/src/lib/dns/python/tests/rrtype_python_test.py
@@ -22,7 +22,7 @@ import os
from pydnspp import *
class TestModuleSpec(unittest.TestCase):
-
+
rrtype_1 = RRType(1)
rrtype_0x80 = RRType(0x80);
rrtype_0x800 = RRType(0x800);
@@ -32,24 +32,28 @@ class TestModuleSpec(unittest.TestCase):
def test_init(self):
- self.assertRaises(InvalidRRType, RRType, 65537)
b = bytearray(b'\x00\x01')
self.assertEqual(RRType("A"), RRType(b))
b = bytearray(b'\x01')
self.assertRaises(IncompleteRRType, RRType, b)
self.assertRaises(TypeError, RRType, Exception)
-
+ # Range check. We need to do this at the binding level, so we need
+ # explicit tests for it.
+ self.assertRaises(ValueError, RRType, 65536)
+ self.assertRaises(TypeError, RRType, -1)
+ self.assertEqual("TYPE65535", RRType(65535).to_text());
+ self.assertEqual("TYPE0", RRType(0).to_text());
+
def test_init_from_text(self):
self.assertEqual("A", RRType("A").to_text())
self.assertEqual("NS", RRType("NS").to_text());
self.assertEqual("NS", str(RRType("NS")));
-
self.assertEqual("TYPE65535", RRType("TYPE65535").to_text());
-
+
self.assertEqual(53, RRType("TYPE00053").get_code());
self.assertRaises(InvalidRRType, RRType, "TYPE000053");
-
+
self.assertRaises(InvalidRRType, RRType, "TYPE");
self.assertRaises(InvalidRRType, RRType, "TYPE-1");
self.assertRaises(InvalidRRType, RRType, "TYPExxx");
diff --git a/src/lib/dns/rdata.cc b/src/lib/dns/rdata.cc
index e51991f..a1ba063 100644
--- a/src/lib/dns/rdata.cc
+++ b/src/lib/dns/rdata.cc
@@ -67,7 +67,8 @@ createRdata(const RRType& rrtype, const RRClass& rrclass,
len);
if (buffer.getPosition() - old_pos != len) {
- isc_throw(InvalidRdataLength, "RDLENGTH mismatch");
+ isc_throw(InvalidRdataLength, "RDLENGTH mismatch: " <<
+ buffer.getPosition() - old_pos << " != " << len);
}
return (rdata);
diff --git a/src/lib/dns/rdata.h b/src/lib/dns/rdata.h
index 1e57f27..c8064f9 100644
--- a/src/lib/dns/rdata.h
+++ b/src/lib/dns/rdata.h
@@ -163,6 +163,7 @@ public:
///
/// \return A string representation of \c Rdata.
virtual std::string toText() const = 0;
+
/// \brief Render the \c Rdata in the wire format into a buffer.
///
/// This is a pure virtual method without the definition; the actual
@@ -171,6 +172,7 @@ public:
///
/// \param buffer An output buffer to store the wire data.
virtual void toWire(isc::util::OutputBuffer& buffer) const = 0;
+
/// \brief Render the \c Rdata in the wire format into a
/// \c MessageRenderer object.
///
@@ -253,6 +255,7 @@ public:
/// \param rdata_string A string of textual representation of generic
/// RDATA.
explicit Generic(const std::string& rdata_string);
+
///
/// \brief Constructor from wire-format data.
///
@@ -275,6 +278,7 @@ public:
/// \c Rdata to parse.
/// \param rdata_len The length in buffer of the \c Rdata. In bytes.
Generic(isc::util::InputBuffer& buffer, size_t rdata_len);
+
///
/// \brief The destructor.
virtual ~Generic();
@@ -286,6 +290,7 @@ public:
///
/// \param source A reference to a \c generic::Generic object to copy from.
Generic(const Generic& source);
+
///
/// \brief The assignment operator.
///
@@ -295,6 +300,7 @@ public:
/// \param source A reference to a \c generic::Generic object to copy from.
Generic& operator=(const Generic& source);
//@}
+
///
/// \name Converter methods
///
@@ -309,6 +315,7 @@ public:
///
/// \return A string representation of \c generic::Generic.
virtual std::string toText() const;
+
///
/// \brief Render the \c generic::Generic in the wire format into a buffer.
///
@@ -319,6 +326,7 @@ public:
///
/// \param buffer An output buffer to store the wire data.
virtual void toWire(isc::util::OutputBuffer& buffer) const;
+
/// \brief Render the \c generic::Generic in the wire format into a
/// \c MessageRenderer object.
///
@@ -331,6 +339,7 @@ public:
/// output buffer in which the \c Generic object is to be stored.
virtual void toWire(MessageRenderer& renderer) const;
//@}
+
///
/// \name Comparison method
///
@@ -423,6 +432,7 @@ std::ostream& operator<<(std::ostream& os, const Generic& rdata);
/// object.
RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
const std::string& rdata_string);
+
/// \brief Create RDATA of a given pair of RR type and class from
/// wire-format data.
///
@@ -446,6 +456,7 @@ RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
/// object.
RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
isc::util::InputBuffer& buffer, size_t len);
+
/// \brief Create RDATA of a given pair of RR type and class, copying
/// of another RDATA of same kind.
///
diff --git a/src/lib/dns/rdata/generic/rp_17.cc b/src/lib/dns/rdata/generic/rp_17.cc
new file mode 100644
index 0000000..c1c91ef
--- /dev/null
+++ b/src/lib/dns/rdata/generic/rp_17.cc
@@ -0,0 +1,125 @@
+// Copyright (C) 2011 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 <string>
+#include <sstream>
+
+#include <util/buffer.h>
+
+#include <dns/messagerenderer.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdataclass.h>
+
+using namespace std;
+using namespace isc::dns;
+
+// BEGIN_ISC_NAMESPACE
+// BEGIN_RDATA_NAMESPACE
+
+/// \brief Constructor from string.
+///
+/// \c rp_str must be formatted as follows:
+/// \code <mailbox name> <text name>
+/// \endcode
+/// where both fields must represent a valid domain name.
+///
+/// \exception InvalidRdataText The number of RDATA fields (must be 2) is
+/// incorrect.
+/// \exception Other The constructor of the \c Name class will throw if the
+/// given name is invalid.
+/// \exception std::bad_alloc Memory allocation for names fails.
+RP::RP(const std::string& rp_str) :
+ // We cannot construct both names in the initialization list due to the
+ // necessary text processing, so we have to initialize them with a dummy
+ // name and replace them later.
+ mailbox_(Name::ROOT_NAME()), text_(Name::ROOT_NAME())
+{
+ istringstream iss(rp_str);
+ string mailbox_str, text_str;
+ iss >> mailbox_str >> text_str;
+
+ // Validation: A valid RP RR must have exactly two fields.
+ if (iss.bad() || iss.fail()) {
+ isc_throw(InvalidRdataText, "Invalid RP text: " << rp_str);
+ }
+ if (!iss.eof()) {
+ isc_throw(InvalidRdataText, "Invalid RP text (redundant field): "
+ << rp_str);
+ }
+
+ mailbox_ = Name(mailbox_str);
+ text_ = Name(text_str);
+}
+
+/// \brief Constructor from wire-format data.
+///
+/// This constructor doesn't check the validity of the second parameter (rdata
+/// length) for parsing.
+/// If necessary, the caller will check consistency.
+///
+/// \exception std::bad_alloc Memory allocation for names fails.
+/// \exception Other The constructor of the \c Name class will throw if the
+/// names in the wire is invalid.
+RP::RP(InputBuffer& buffer, size_t) : mailbox_(buffer), text_(buffer) {
+}
+
+/// \brief Copy constructor.
+///
+/// \exception std::bad_alloc Memory allocation fails in copying internal
+/// member variables (this should be very rare).
+RP::RP(const RP& other) :
+ Rdata(), mailbox_(other.mailbox_), text_(other.text_)
+{}
+
+/// \brief Convert the \c RP to a string.
+///
+/// The output of this method is formatted as described in the "from string"
+/// constructor (\c RP(const std::string&))).
+///
+/// \exception std::bad_alloc Internal resource allocation fails.
+///
+/// \return A \c string object that represents the \c RP object.
+std::string
+RP::toText() const {
+ return (mailbox_.toText() + " " + text_.toText());
+}
+
+void
+RP::toWire(OutputBuffer& buffer) const {
+ mailbox_.toWire(buffer);
+ text_.toWire(buffer);
+}
+
+void
+RP::toWire(MessageRenderer& renderer) const {
+ // Type RP is not "well-known", and name compression must be disabled
+ // per RFC3597.
+ renderer.writeName(mailbox_, false);
+ renderer.writeName(text_, false);
+}
+
+int
+RP::compare(const Rdata& other) const {
+ const RP& other_rp = dynamic_cast<const RP&>(other);
+
+ const int cmp = compareNames(mailbox_, other_rp.mailbox_);
+ if (cmp != 0) {
+ return (cmp);
+ }
+ return (compareNames(text_, other_rp.text_));
+}
+
+// END_RDATA_NAMESPACE
+// END_ISC_NAMESPACE
diff --git a/src/lib/dns/rdata/generic/rp_17.h b/src/lib/dns/rdata/generic/rp_17.h
new file mode 100644
index 0000000..a90a530
--- /dev/null
+++ b/src/lib/dns/rdata/generic/rp_17.h
@@ -0,0 +1,88 @@
+// Copyright (C) 2011 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.
+
+// BEGIN_HEADER_GUARD
+
+#include <string>
+
+#include <dns/name.h>
+#include <dns/rdata.h>
+
+// BEGIN_ISC_NAMESPACE
+
+// BEGIN_COMMON_DECLARATIONS
+// END_COMMON_DECLARATIONS
+
+// BEGIN_RDATA_NAMESPACE
+
+/// \brief \c rdata::generic::RP class represents the RP RDATA as defined in
+/// RFC1183.
+///
+/// This class implements the basic interfaces inherited from the abstract
+/// \c rdata::Rdata class, and provides trivial accessors specific to the
+/// RP RDATA.
+class RP : public Rdata {
+public:
+ // BEGIN_COMMON_MEMBERS
+ // END_COMMON_MEMBERS
+
+ /// We use the default copy constructor and assignment operator.
+
+ /// \brief Constructor from RDATA field parameters.
+ ///
+ /// The parameters are a straightforward mapping of %RP RDATA
+ /// fields as defined in RFC1183.
+ RP(const Name& mailbox, const Name& text) :
+ mailbox_(mailbox), text_(text)
+ {}
+
+ /// \brief Return the value of the mailbox field.
+ ///
+ /// This method normally does not throw an exception, but if resource
+ /// allocation for the returned \c Name object fails, a corresponding
+ /// standard exception will be thrown.
+ ///
+ /// \note
+ /// Unlike the case of some other RDATA classes (such as
+ /// \c NS::getNSName()), this method constructs a new \c Name object
+ /// and returns it, instead of returning a reference to a \c Name object
+ /// internally maintained in the class (which is a private member).
+ /// This is based on the observation that this method will be rarely used
+ /// and even when it's used it will not be in a performance context
+ /// (for example, a recursive resolver won't need this field in its
+ /// resolution process). By returning a new object we have flexibility of
+ /// changing the internal representation without the risk of changing
+ /// the interface or method property.
+ /// The same note applies to the \c getText() method.
+ Name getMailbox() const { return (mailbox_); }
+
+ /// \brief Return the value of the text field.
+ ///
+ /// This method normally does not throw an exception, but if resource
+ /// allocation for the returned \c Name object fails, a corresponding
+ /// standard exception will be thrown.
+ Name getText() const { return (text_); }
+
+private:
+ Name mailbox_;
+ Name text_;
+};
+
+// END_RDATA_NAMESPACE
+// END_ISC_NAMESPACE
+// END_HEADER_GUARD
+
+// Local Variables:
+// mode: c++
+// End:
diff --git a/src/lib/dns/rdata/template.cc b/src/lib/dns/rdata/template.cc
index b1dc571..157ea90 100644
--- a/src/lib/dns/rdata/template.cc
+++ b/src/lib/dns/rdata/template.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011 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
diff --git a/src/lib/dns/rdata/template.h b/src/lib/dns/rdata/template.h
index e85a839..9e84cc3 100644
--- a/src/lib/dns/rdata/template.h
+++ b/src/lib/dns/rdata/template.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011 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
diff --git a/src/lib/dns/tests/Makefile.am b/src/lib/dns/tests/Makefile.am
index 8882e18..b345411 100644
--- a/src/lib/dns/tests/Makefile.am
+++ b/src/lib/dns/tests/Makefile.am
@@ -38,6 +38,7 @@ run_unittests_SOURCES += rdata_nsec3_unittest.cc
run_unittests_SOURCES += rdata_nsecbitmap_unittest.cc
run_unittests_SOURCES += rdata_nsec3param_unittest.cc
run_unittests_SOURCES += rdata_rrsig_unittest.cc
+run_unittests_SOURCES += rdata_rp_unittest.cc
run_unittests_SOURCES += rdata_tsig_unittest.cc
run_unittests_SOURCES += rrset_unittest.cc rrsetlist_unittest.cc
run_unittests_SOURCES += question_unittest.cc
@@ -50,8 +51,8 @@ run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
run_unittests_LDADD = $(GTEST_LDADD)
run_unittests_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
-run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
run_unittests_LDADD += $(top_builddir)/src/lib/util/libutil.la
+run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
endif
noinst_PROGRAMS = $(TESTS)
diff --git a/src/lib/dns/tests/rdata_rp_unittest.cc b/src/lib/dns/tests/rdata_rp_unittest.cc
new file mode 100644
index 0000000..07f5a93
--- /dev/null
+++ b/src/lib/dns/tests/rdata_rp_unittest.cc
@@ -0,0 +1,163 @@
+// Copyright (C) 2011 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 <string>
+
+#include <util/buffer.h>
+#include <dns/exceptions.h>
+#include <dns/rdataclass.h>
+
+#include <gtest/gtest.h>
+
+#include <dns/tests/unittest_util.h>
+#include <dns/tests/rdata_unittest.h>
+
+using isc::UnitTestUtil;
+using namespace std;
+using namespace isc::util;
+using namespace isc::dns;
+using namespace isc::dns::rdata;
+
+namespace {
+class Rdata_RP_Test : public RdataTest {
+protected:
+ Rdata_RP_Test() :
+ mailbox_name("root.example.com."),
+ text_name("rp-text.example.com."),
+ // 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)
+ {}
+
+ const Name mailbox_name, text_name;
+ const generic::RP rdata_rp; // commonly used test RDATA
+ OutputBuffer obuffer;
+ MessageRenderer renderer;
+ vector<uint8_t> expected_wire;
+};
+
+TEST_F(Rdata_RP_Test, createFromText) {
+ EXPECT_EQ(mailbox_name, rdata_rp.getMailbox());
+ EXPECT_EQ(text_name, rdata_rp.getText());
+
+ // Invalid textual input cases follow:
+ // names are invalid
+ EXPECT_THROW(generic::RP("bad..name. rp-text.example.com"), EmptyLabel);
+ EXPECT_THROW(generic::RP("mailbox.example.com. bad..name"), EmptyLabel);
+
+ // missing field
+ EXPECT_THROW(generic::RP("mailbox.example.com."), InvalidRdataText);
+
+ // redundant field
+ EXPECT_THROW(generic::RP("mailbox.example.com. rp-text.example.com. "
+ "redundant.example."), InvalidRdataText);
+}
+
+TEST_F(Rdata_RP_Test, createFromWire) {
+ RdataPtr rdata(rdataFactoryFromFile(RRType::RP(), RRClass::IN(),
+ "rdata_rp_fromWire1.wire"));
+ EXPECT_EQ(mailbox_name, dynamic_cast<generic::RP&>(*rdata).getMailbox());
+ EXPECT_EQ(text_name, dynamic_cast<generic::RP&>(*rdata).getText());
+
+ // a similar test with names being compressed
+ rdata = rdataFactoryFromFile(RRType::RP(), RRClass::IN(),
+ "rdata_rp_fromWire2.wire", 30);
+ EXPECT_EQ(mailbox_name, dynamic_cast<generic::RP&>(*rdata).getMailbox());
+ EXPECT_EQ(Name("rp-text.example.net"),
+ dynamic_cast<generic::RP&>(*rdata).getText());
+}
+
+TEST_F(Rdata_RP_Test, badFromWire) {
+ // RDLEN is too short
+ EXPECT_THROW(rdataFactoryFromFile(RRType::RP(), RRClass::IN(),
+ "rdata_rp_fromWire3.wire"),
+ InvalidRdataLength);
+
+ // RDLEN is too long
+ EXPECT_THROW(rdataFactoryFromFile(RRType::RP(), RRClass::IN(),
+ "rdata_rp_fromWire4.wire"),
+ InvalidRdataLength);
+
+ // bogus mailbox name
+ EXPECT_THROW(rdataFactoryFromFile(RRType::RP(), RRClass::IN(),
+ "rdata_rp_fromWire5.wire"),
+ DNSMessageFORMERR);
+
+ // bogus text name
+ EXPECT_THROW(rdataFactoryFromFile(RRType::RP(), RRClass::IN(),
+ "rdata_rp_fromWire6.wire"),
+ DNSMessageFORMERR);
+}
+
+TEST_F(Rdata_RP_Test, createFromParams) {
+ EXPECT_EQ(mailbox_name, generic::RP(mailbox_name, text_name).getMailbox());
+ EXPECT_EQ(text_name, generic::RP(mailbox_name, text_name).getText());
+}
+
+TEST_F(Rdata_RP_Test, toWireBuffer) {
+ // construct expected data
+ UnitTestUtil::readWireData("rdata_rp_toWire1.wire", expected_wire);
+
+ // construct actual data
+ rdata_rp.toWire(obuffer);
+
+ // then compare them
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
+ obuffer.getData(), obuffer.getLength(),
+ &expected_wire[0], expected_wire.size());
+}
+
+TEST_F(Rdata_RP_Test, toWireRenderer) {
+ // similar to toWireBuffer, but names in RDATA could be compressed due to
+ // preceding names. Actually they must not be compressed according to
+ // RFC3597, and this test checks that.
+
+ UnitTestUtil::readWireData("rdata_rp_toWire2.wire", expected_wire);
+
+ renderer.writeName(Name("a.example.com"));
+ renderer.writeName(Name("b.example.net"));
+ generic::RP(mailbox_name, Name("rp-text.example.net")).toWire(renderer);
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
+ renderer.getData(), renderer.getLength(),
+ &expected_wire[0], expected_wire.size());
+}
+
+TEST_F(Rdata_RP_Test, toText) {
+ // there's not much to test for this method. Only checking a simple case.
+ EXPECT_EQ("root.example.com. rp-text.example.com.", rdata_rp.toText());
+}
+
+TEST_F(Rdata_RP_Test, compare) {
+ // check reflexivity
+ EXPECT_EQ(0, rdata_rp.compare(rdata_rp));
+
+ // names must be compared in case-insensitive manner
+ EXPECT_EQ(0, rdata_rp.compare(generic::RP("ROOT.example.com. "
+ "rp-text.EXAMPLE.com.")));
+
+ // another RP whose mailbox name is larger than that of rdata_rp.
+ const generic::RP large1_rp("zzzz.example.com. rp-text.example.com.");
+ EXPECT_GT(0, rdata_rp.compare(large1_rp));
+ EXPECT_LT(0, large1_rp.compare(rdata_rp));
+
+ // yet another RP whose text name is larger than that of rdata_rp.
+ const generic::RP large2_rp("root.example.com. zzzzzzz.example.com.");
+ EXPECT_GT(0, rdata_rp.compare(large2_rp));
+ EXPECT_LT(0, large2_rp.compare(rdata_rp));
+
+ // comparison attempt between incompatible RR types should be rejected
+ EXPECT_THROW(rdata_rp.compare(*RdataTest::rdata_nomatch), bad_cast);
+}
+}
diff --git a/src/lib/dns/tests/testdata/Makefile.am b/src/lib/dns/tests/testdata/Makefile.am
index 1aaddb6..1dc1c00 100644
--- a/src/lib/dns/tests/testdata/Makefile.am
+++ b/src/lib/dns/tests/testdata/Makefile.am
@@ -16,6 +16,10 @@ BUILT_SOURCES += rdata_nsec3_fromWire10.wire rdata_nsec3_fromWire11.wire
BUILT_SOURCES += rdata_nsec3_fromWire12.wire rdata_nsec3_fromWire13.wire
BUILT_SOURCES += rdata_nsec3_fromWire14.wire rdata_nsec3_fromWire15.wire
BUILT_SOURCES += rdata_rrsig_fromWire2.wire
+BUILT_SOURCES += rdata_rp_fromWire1.wire rdata_rp_fromWire2.wire
+BUILT_SOURCES += rdata_rp_fromWire3.wire rdata_rp_fromWire4.wire
+BUILT_SOURCES += rdata_rp_fromWire5.wire rdata_rp_fromWire6.wire
+BUILT_SOURCES += rdata_rp_toWire1.wire rdata_rp_toWire2.wire
BUILT_SOURCES += rdata_soa_toWireUncompressed.wire
BUILT_SOURCES += rdata_txt_fromWire2.wire rdata_txt_fromWire3.wire
BUILT_SOURCES += rdata_txt_fromWire4.wire rdata_txt_fromWire5.wire
@@ -67,6 +71,10 @@ EXTRA_DIST += rdata_nsec3_fromWire12.spec rdata_nsec3_fromWire13.spec
EXTRA_DIST += rdata_nsec3_fromWire14.spec rdata_nsec3_fromWire15.spec
EXTRA_DIST += rdata_opt_fromWire rdata_rrsig_fromWire1
EXTRA_DIST += rdata_rrsig_fromWire2.spec
+EXTRA_DIST += rdata_rp_fromWire1.spec rdata_rp_fromWire2.spec
+EXTRA_DIST += rdata_rp_fromWire3.spec rdata_rp_fromWire4.spec
+EXTRA_DIST += rdata_rp_fromWire5.spec rdata_rp_fromWire6.spec
+EXTRA_DIST += rdata_rp_toWire1.spec rdata_rp_toWire2.spec
EXTRA_DIST += rdata_soa_fromWire rdata_soa_toWireUncompressed.spec
EXTRA_DIST += rdata_txt_fromWire1 rdata_txt_fromWire2.spec
EXTRA_DIST += rdata_txt_fromWire3.spec rdata_txt_fromWire4.spec
diff --git a/src/lib/dns/tests/testdata/gen-wiredata.py.in b/src/lib/dns/tests/testdata/gen-wiredata.py.in
index 645430c..72cbdaa 100755
--- a/src/lib/dns/tests/testdata/gen-wiredata.py.in
+++ b/src/lib/dns/tests/testdata/gen-wiredata.py.in
@@ -90,7 +90,7 @@ def encode_name(name, absolute=True):
for l in labels:
if len(l) > 4 and l[0:4] == 'ptr=':
# special meta-syntax for compression pointer
- wire += ' %04x' % (0xc000 | int(l[4:]))
+ wire += '%04x' % (0xc000 | int(l[4:]))
break
if absolute or len(l) > 0:
wire += '%02x' % len(l)
@@ -277,6 +277,34 @@ class TXT:
' ' if len(wirestring_list[i]) > 0 else '',
wirestring_list[i]))
+class RP:
+ '''Implements rendering RP RDATA in the wire format.
+ Configurable parameters are as follows:
+ - rdlen: 16-bit RDATA length. If omitted, the accurate value is auto
+ calculated and used; if negative, the RDLEN field will be omitted from
+ the output data.
+ - mailbox: The mailbox field.
+ - text: The text field.
+ All of these parameters have the default values and can be omitted.
+ '''
+ rdlen = None # auto-calculate
+ mailbox = 'root.example.com'
+ text = 'rp-text.example.com'
+ def dump(self, f):
+ mailbox_wire = encode_name(self.mailbox)
+ text_wire = encode_name(self.text)
+ if self.rdlen is None:
+ self.rdlen = (len(mailbox_wire) + len(text_wire)) / 2
+ else:
+ self.rdlen = int(self.rdlen)
+ if self.rdlen >= 0:
+ f.write('\n# RP RDATA (RDLEN=%d)\n' % self.rdlen)
+ f.write('%04x\n' % self.rdlen)
+ else:
+ f.write('\n# RP RDATA (RDLEN omitted)\n')
+ f.write('# MAILBOX=%s TEXT=%s\n' % (self.mailbox, self.text))
+ f.write('%s %s\n' % (mailbox_wire, text_wire))
+
class NSECBASE:
'''Implements rendering NSEC/NSEC3 type bitmaps commonly used for
these RRs. The NSEC and NSEC3 classes will be inherited from this
@@ -461,8 +489,9 @@ def get_config_param(section):
'header' : (DNSHeader, header_xtables),
'question' : (DNSQuestion, question_xtables),
'edns' : (EDNS, {}), 'soa' : (SOA, {}), 'txt' : (TXT, {}),
- 'rrsig' : (RRSIG, {}), 'nsec' : (NSEC, {}),
- 'nsec3' : (NSEC3, {}), 'tsig' : (TSIG, {}) }
+ 'rp' : (RP, {}), 'rrsig' : (RRSIG, {}),
+ 'nsec' : (NSEC, {}), 'nsec3' : (NSEC3, {}),
+ 'tsig' : (TSIG, {}) }
s = section
m = re.match('^([^:]+)/\d+$', section)
if m:
diff --git a/src/lib/dns/tests/testdata/rdata_rp_fromWire1.spec b/src/lib/dns/tests/testdata/rdata_rp_fromWire1.spec
new file mode 100644
index 0000000..edb9f34
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_rp_fromWire1.spec
@@ -0,0 +1,6 @@
+#
+# A simplest form of RP: all default parameters
+#
+[custom]
+sections: rp
+[rp]
diff --git a/src/lib/dns/tests/testdata/rdata_rp_fromWire2.spec b/src/lib/dns/tests/testdata/rdata_rp_fromWire2.spec
new file mode 100644
index 0000000..57adb5a
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_rp_fromWire2.spec
@@ -0,0 +1,12 @@
+#
+# A simplest form of RP: names are compressed.
+#
+[custom]
+sections: name/1:name/2:rp
+[name/1]
+name: a.example.com
+[name/2]
+name: b.example.net
+[rp]
+mailbox: root.ptr=2
+text: rp-text.ptr=17
diff --git a/src/lib/dns/tests/testdata/rdata_rp_fromWire3.spec b/src/lib/dns/tests/testdata/rdata_rp_fromWire3.spec
new file mode 100644
index 0000000..a238b7e
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_rp_fromWire3.spec
@@ -0,0 +1,7 @@
+#
+# RP-like RDATA but RDLEN is too short.
+#
+[custom]
+sections: rp
+[rp]
+rdlen: 38
diff --git a/src/lib/dns/tests/testdata/rdata_rp_fromWire4.spec b/src/lib/dns/tests/testdata/rdata_rp_fromWire4.spec
new file mode 100644
index 0000000..6f3abd1
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_rp_fromWire4.spec
@@ -0,0 +1,7 @@
+#
+# RP-like RDATA but RDLEN is too long.
+#
+[custom]
+sections: rp
+[rp]
+rdlen: 40
diff --git a/src/lib/dns/tests/testdata/rdata_rp_fromWire5.spec b/src/lib/dns/tests/testdata/rdata_rp_fromWire5.spec
new file mode 100644
index 0000000..b8d5e29
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_rp_fromWire5.spec
@@ -0,0 +1,7 @@
+#
+# RP-like RDATA but mailbox name is broken.
+#
+[custom]
+sections: rp
+[rp]
+mailbox: "01234567890123456789012345678901234567890123456789012345678901234"
diff --git a/src/lib/dns/tests/testdata/rdata_rp_fromWire6.spec b/src/lib/dns/tests/testdata/rdata_rp_fromWire6.spec
new file mode 100644
index 0000000..e9e79f3
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_rp_fromWire6.spec
@@ -0,0 +1,7 @@
+#
+# RP-like RDATA but text name is broken.
+#
+[custom]
+sections: rp
+[rp]
+text: "01234567890123456789012345678901234567890123456789012345678901234"
diff --git a/src/lib/dns/tests/testdata/rdata_rp_toWire1.spec b/src/lib/dns/tests/testdata/rdata_rp_toWire1.spec
new file mode 100644
index 0000000..948bd1a
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_rp_toWire1.spec
@@ -0,0 +1,8 @@
+#
+# A simplest form of RP for toWire test: all default parameters except rdlen,
+# which is to be omitted.
+#
+[custom]
+sections: rp
+[rp]
+rdlen: -1
diff --git a/src/lib/dns/tests/testdata/rdata_rp_toWire2.spec b/src/lib/dns/tests/testdata/rdata_rp_toWire2.spec
new file mode 100644
index 0000000..09a7ddc
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_rp_toWire2.spec
@@ -0,0 +1,14 @@
+#
+# A simple form of RP: names could be compressed (but MUST NOT).
+# rdlen is omitted for the "to wire" test.
+#
+[custom]
+sections: name/1:name/2:rp
+[name/1]
+name: a.example.com
+[name/2]
+name: b.example.net
+[rp]
+rdlen: -1
+mailbox: root.example.com
+text: rp-text.example.net
diff --git a/src/lib/nsas/glue_hints.cc b/src/lib/nsas/glue_hints.cc
index d4c653a..02c27ee 100644
--- a/src/lib/nsas/glue_hints.cc
+++ b/src/lib/nsas/glue_hints.cc
@@ -58,7 +58,7 @@ namespace {
const std::string ns_name = rrset->getName().toText();
RdataIteratorPtr rdi = rrset->getRdataIterator();
while (!rdi->isLast()) {
- AddressEntry entry(asiolink::IOAddress(rdi->getCurrent().toText()));
+ AddressEntry entry(isc::asiolink::IOAddress(rdi->getCurrent().toText()));
boost::shared_ptr<NameserverEntry> ns_entry(new NameserverEntry(ns_name, rrset->getClass()));
NameserverAddress ns_address(ns_entry, entry, V4_ONLY);
addresses.push_back(ns_address);
diff --git a/src/lib/nsas/nameserver_entry.cc b/src/lib/nsas/nameserver_entry.cc
index d991bcb..4035f79 100644
--- a/src/lib/nsas/nameserver_entry.cc
+++ b/src/lib/nsas/nameserver_entry.cc
@@ -41,7 +41,7 @@
#include "nameserver_address.h"
#include "nameserver_entry.h"
-using namespace asiolink;
+using namespace isc::asiolink;
using namespace isc::nsas;
using namespace isc::dns;
using namespace std;
diff --git a/src/lib/nsas/tests/address_entry_unittest.cc b/src/lib/nsas/tests/address_entry_unittest.cc
index 02fef51..60aa3cc 100644
--- a/src/lib/nsas/tests/address_entry_unittest.cc
+++ b/src/lib/nsas/tests/address_entry_unittest.cc
@@ -32,7 +32,7 @@ static std::string V4B_TEXT("5.6.7.8");
static std::string V6A_TEXT("2001:dead:beef::");
static std::string V6B_TEXT("1984:1985::1986:1987");
-using namespace asiolink;
+using namespace isc::asiolink;
using namespace std;
using namespace isc::nsas;
diff --git a/src/lib/nsas/tests/nameserver_address_unittest.cc b/src/lib/nsas/tests/nameserver_address_unittest.cc
index 457e61c..e3bc5de 100644
--- a/src/lib/nsas/tests/nameserver_address_unittest.cc
+++ b/src/lib/nsas/tests/nameserver_address_unittest.cc
@@ -58,7 +58,7 @@ public:
boost::shared_ptr<NameserverEntry>& getNameserverEntry() { return ns_; }
// Return the IOAddress corresponding to the index in rrv4_
- asiolink::IOAddress getAddressAtIndex(uint32_t index) {
+ isc::asiolink::IOAddress getAddressAtIndex(uint32_t index) {
return ns_.get()->getAddressAtIndex(index, V4_ONLY);
}
@@ -107,7 +107,7 @@ TEST_F(NameserverAddressTest, Address) {
boost::shared_ptr<NameserverEntry> empty_ne((NameserverEntry*)NULL);
// It will throw an NullNameserverEntryPointer exception with the empty NameserverEntry shared pointer
ASSERT_THROW({NameserverAddress empty_ns_address(empty_ne,
- asiolink::IOAddress("127.0.0.1"), V4_ONLY);},
+ isc::asiolink::IOAddress("127.0.0.1"), V4_ONLY);},
NullNameserverEntryPointer);
}
diff --git a/src/lib/nsas/tests/nameserver_entry_unittest.cc b/src/lib/nsas/tests/nameserver_entry_unittest.cc
index 4225e87..d489cbc 100644
--- a/src/lib/nsas/tests/nameserver_entry_unittest.cc
+++ b/src/lib/nsas/tests/nameserver_entry_unittest.cc
@@ -39,7 +39,7 @@
#include "nsas_test.h"
using namespace isc::nsas;
-using namespace asiolink;
+using namespace isc::asiolink;
using namespace std;
using namespace isc::dns;
using namespace rdata;
diff --git a/src/lib/nsas/tests/zone_entry_unittest.cc b/src/lib/nsas/tests/zone_entry_unittest.cc
index c2110d1..1982299 100644
--- a/src/lib/nsas/tests/zone_entry_unittest.cc
+++ b/src/lib/nsas/tests/zone_entry_unittest.cc
@@ -33,7 +33,7 @@
#include "nsas_test.h"
using namespace isc::nsas;
-using namespace asiolink;
+using namespace isc::asiolink;
using namespace std;
using namespace isc::dns;
using namespace isc::util;
diff --git a/src/lib/python/isc/config/ccsession.py b/src/lib/python/isc/config/ccsession.py
index 942bf79..226c6ba 100644
--- a/src/lib/python/isc/config/ccsession.py
+++ b/src/lib/python/isc/config/ccsession.py
@@ -151,6 +151,9 @@ class ModuleCCSession(ConfigData):
self._remote_module_configs = {}
def __del__(self):
+ # If the CC Session obejct has been closed, it returns
+ # immediately.
+ if self._session._closed: return
self._session.group_unsubscribe(self._module_name, "*")
for module_name in self._remote_module_configs:
self._session.group_unsubscribe(module_name)
diff --git a/src/lib/python/isc/config/config_data.py b/src/lib/python/isc/config/config_data.py
index 582c11c..cee1d34 100644
--- a/src/lib/python/isc/config/config_data.py
+++ b/src/lib/python/isc/config/config_data.py
@@ -461,8 +461,8 @@ class MultiConfigData:
spec_part_list = spec_part['list_item_spec']
list_value, status = self.get_value(identifier)
if list_value is None:
- print("Error: identifier '%s' not found" % identifier)
- return
+ raise isc.cc.data.DataNotFoundError(identifier)
+
if type(list_value) != list:
# the identifier specified a single element
self._append_value_item(result, spec_part_list, identifier, all)
diff --git a/src/lib/python/isc/config/tests/ccsession_test.py b/src/lib/python/isc/config/tests/ccsession_test.py
index 2ae37f5..4edc559 100644
--- a/src/lib/python/isc/config/tests/ccsession_test.py
+++ b/src/lib/python/isc/config/tests/ccsession_test.py
@@ -234,7 +234,18 @@ class TestModuleCCSession(unittest.TestCase):
fake_session = FakeModuleCCSession()
mccs = self.create_session("spec1.spec", None, None, fake_session)
mccs.close()
- self.assertEqual("closed", fake_session._socket)
+ self.assertEqual(None, fake_session._socket)
+
+ def test_del_opened(self):
+ fake_session = FakeModuleCCSession()
+ mccs = self.create_session("spec1.spec", None, None, fake_session)
+ mccs.__del__() # with opened fake_session
+
+ def test_del_closed(self):
+ fake_session = FakeModuleCCSession()
+ mccs = self.create_session("spec1.spec", None, None, fake_session)
+ fake_session.close()
+ mccs.__del__() # with closed fake_session
def my_config_handler_ok(self, new_config):
return isc.config.ccsession.create_answer(0)
diff --git a/src/lib/python/isc/config/tests/config_data_test.py b/src/lib/python/isc/config/tests/config_data_test.py
index 1aded94..923e0b6 100644
--- a/src/lib/python/isc/config/tests/config_data_test.py
+++ b/src/lib/python/isc/config/tests/config_data_test.py
@@ -465,8 +465,8 @@ class TestMultiConfigData(unittest.TestCase):
module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec24.spec")
self.mcd.set_specification(module_spec)
- maps = self.mcd.get_value_maps("/Spec24/item")
- self.assertEqual([], maps)
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self.mcd.get_value_maps, "/Spec24/item", 4)
self.mcd._set_current_config({ "Spec24": { "item": [] } })
maps = self.mcd.get_value_maps("/Spec24/item")
self.assertEqual([{'default': False, 'modified': False, 'name': 'Spec24/item', 'type': 'list', 'value': []}], maps)
diff --git a/src/lib/python/isc/config/tests/unittest_fakesession.py b/src/lib/python/isc/config/tests/unittest_fakesession.py
index e31b436..1641ec0 100644
--- a/src/lib/python/isc/config/tests/unittest_fakesession.py
+++ b/src/lib/python/isc/config/tests/unittest_fakesession.py
@@ -35,6 +35,7 @@ class FakeModuleCCSession:
# the message_queue is empty when receive is called, throw
# a SessionTimeout
self._timeout = 0
+ self._closed = False
def group_subscribe(self, group_name, instance_name = None):
if not group_name in self.subscriptions:
@@ -43,6 +44,11 @@ class FakeModuleCCSession:
self.subscriptions[group_name].append(instance_name)
def group_unsubscribe(self, group_name, instance_name = None):
+
+ # raises SessionError if the session has been already closed.
+ if self._closed:
+ raise isc.cc.SessionError("Session has been closed.")
+
if group_name in self.subscriptions:
if instance_name:
if len(self.subscriptions[group_name]) > 1:
@@ -94,7 +100,8 @@ class FakeModuleCCSession:
def close(self):
# need to pass along somehow that this function has been called,
- self._socket = "closed"
+ self._socket = None
+ self._closed = True
def set_timeout(self, timeout):
self._timeout = timeout
diff --git a/src/lib/resolve/recursive_query.cc b/src/lib/resolve/recursive_query.cc
index 2acede8..c0d5ee6 100644
--- a/src/lib/resolve/recursive_query.cc
+++ b/src/lib/resolve/recursive_query.cc
@@ -35,16 +35,18 @@
#include <nsas/nameserver_address.h>
#include <asio.hpp>
-#include <asiolink/dns_service.h>
-#include <asiolink/io_fetch.h>
+#include <asiodns/dns_service.h>
+#include <asiodns/io_fetch.h>
#include <asiolink/io_service.h>
#include <resolve/recursive_query.h>
using isc::log::dlog;
using namespace isc::dns;
using namespace isc::util;
+using namespace isc::asiolink;
-namespace asiolink {
+namespace isc {
+namespace asiodns {
typedef std::vector<std::pair<std::string, uint16_t> > AddressVector;
@@ -58,19 +60,19 @@ RecursiveQuery::RecursiveQuery(DNSService& dns_service,
const std::vector<std::pair<std::string, uint16_t> >& upstream,
const std::vector<std::pair<std::string, uint16_t> >& upstream_root,
int query_timeout, int client_timeout, int lookup_timeout,
- unsigned retries) :
+ unsigned retries)
+ :
dns_service_(dns_service),
nsas_(nsas), cache_(cache),
upstream_(new AddressVector(upstream)),
upstream_root_(new AddressVector(upstream_root)),
test_server_("", 0),
query_timeout_(query_timeout), client_timeout_(client_timeout),
- lookup_timeout_(lookup_timeout), retries_(retries)
+ lookup_timeout_(lookup_timeout), retries_(retries), rtt_recorder_()
{
}
// Set the test server - only used for unit testing.
-
void
RecursiveQuery::setTestServer(const std::string& address, uint16_t port) {
dlog("Setting test server to " + address + "(" +
@@ -79,6 +81,11 @@ RecursiveQuery::setTestServer(const std::string& address, uint16_t port) {
test_server_.second = port;
}
+// Set the RTT recorder - only used for testing
+void
+RecursiveQuery::setRttRecorder(boost::shared_ptr<RttRecorder>& recorder) {
+ rtt_recorder_ = recorder;
+}
namespace {
@@ -224,6 +231,10 @@ private:
// event; we can cancel the NSAS callback safely.
size_t outstanding_events_;
+ // RTT Recorder. Used for testing, the RTTs of queries are
+ // sent to this object as well as being used to update the NSAS.
+ boost::shared_ptr<RttRecorder> rtt_recorder_;
+
// perform a single lookup; first we check the cache to see
// if we have a response for our query stored already. if
// so, call handlerecursiveresponse(), if not, we call send()
@@ -482,7 +493,9 @@ public:
int query_timeout, int client_timeout, int lookup_timeout,
unsigned retries,
isc::nsas::NameserverAddressStore& nsas,
- isc::cache::ResolverCache& cache) :
+ isc::cache::ResolverCache& cache,
+ boost::shared_ptr<RttRecorder>& recorder)
+ :
io_(io),
question_(question),
answer_message_(answer_message),
@@ -503,7 +516,8 @@ public:
cur_zone_("."),
nsas_callback_(new ResolverNSASCallback(this)),
nsas_callback_out_(false),
- outstanding_events_(0)
+ outstanding_events_(0),
+ rtt_recorder_(recorder)
{
// Setup the timer to stop trying (lookup_timeout)
if (lookup_timeout >= 0) {
@@ -620,9 +634,11 @@ public:
rtt = 1000 * (cur_time.tv_sec - current_ns_qsent_time.tv_sec);
rtt += (cur_time.tv_usec - current_ns_qsent_time.tv_usec) / 1000;
}
-
dlog("RTT: " + boost::lexical_cast<std::string>(rtt));
current_ns_address.updateRTT(rtt);
+ if (rtt_recorder_) {
+ rtt_recorder_->addRtt(rtt);
+ }
try {
Message incoming(Message::PARSE);
@@ -740,7 +756,8 @@ RecursiveQuery::resolve(const QuestionPtr& question,
new RunningQuery(io, *question, answer_message, upstream_,
test_server_, buffer, callback,
query_timeout_, client_timeout_,
- lookup_timeout_, retries_, nsas_, cache_);
+ lookup_timeout_, retries_, nsas_,
+ cache_, rtt_recorder_);
}
}
}
@@ -793,11 +810,10 @@ RecursiveQuery::resolve(const Question& question,
new RunningQuery(io, question, answer_message, upstream_,
test_server_, buffer, crs, query_timeout_,
client_timeout_, lookup_timeout_, retries_,
- nsas_, cache_);
+ nsas_, cache_, rtt_recorder_);
}
}
}
-
-
-} // namespace asiolink
+} // namespace asiodns
+} // namespace isc
diff --git a/src/lib/resolve/recursive_query.h b/src/lib/resolve/recursive_query.h
index ebdab95..c082426 100644
--- a/src/lib/resolve/recursive_query.h
+++ b/src/lib/resolve/recursive_query.h
@@ -15,18 +15,49 @@
#ifndef __RECURSIVE_QUERY_H
#define __RECURSIVE_QUERY_H 1
-#include <asiolink/dns_service.h>
-#include <asiolink/dns_server.h>
#include <util/buffer.h>
+#include <asiodns/dns_service.h>
+#include <asiodns/dns_server.h>
#include <nsas/nameserver_address_store.h>
#include <cache/resolver_cache.h>
-namespace asiolink {
-/// \brief The \c RecursiveQuery class provides a layer of abstraction around
-/// the ASIO code that carries out an upstream query.
+namespace isc {
+namespace asiodns {
+
+/// \brief RTT Recorder
+///
+/// Used for testing, this class will hold the set of round-trip times to
+/// nameservers for the current recursive query.
+///
+/// A pointer to an object of this class is passed to RecursiveQuery which in
+/// turn passes it to the created RunningQuery class. When a running query
+/// completes, its RTT is passed to the RTT Recorder object.
+class RttRecorder {
+public:
+ /// \brief Record Time
+ ///
+ /// Adds a round-trip time to the internal vector of times.
+ ///
+ /// \param RTT to record.
+ void addRtt(uint32_t rtt) {
+ rtt_.push_back(rtt);
+ }
+
+ /// \brief Return RTT Vector
+ std::vector<uint32_t> getRtt() const {
+ return rtt_;
+ }
+
+private:
+ std::vector<uint32_t> rtt_; ///< Stored round-trip times
+};
+
+
+/// \brief Recursive Query
///
-/// This design is very preliminary; currently it is only capable of
-/// handling simple forward requests to a single resolver.
+/// The \c RecursiveQuery class provides a layer of abstraction around
+/// the ASIO code that carries out an upstream query.
+
class RecursiveQuery {
///
/// \name Constructors
@@ -56,17 +87,25 @@ public:
isc::nsas::NameserverAddressStore& nsas,
isc::cache::ResolverCache& cache,
const std::vector<std::pair<std::string, uint16_t> >&
- upstream,
+ upstream,
const std::vector<std::pair<std::string, uint16_t> >&
- upstream_root,
+ upstream_root,
int query_timeout = 2000,
int client_timeout = 4000,
int lookup_timeout = 30000,
unsigned retries = 3);
//@}
+ /// \brief Set Round-Trip Time Recorder
+ ///
+ /// Sets the RTT recorder object. This is not accessed directly, instead
+ /// it is passed to created RunningQuery objects.
+ ///
+ /// \param recorder Pointer to the RTT recorder object used to hold RTTs.
+ void setRttRecorder(boost::shared_ptr<RttRecorder>& recorder);
+
/// \brief Initiate resolving
- ///
+ ///
/// When sendQuery() is called, a (set of) message(s) is sent
/// asynchronously. If upstream servers are set, one is chosen
/// and the response (if any) from that server will be returned.
@@ -113,7 +152,7 @@ public:
/// \param address IP address of the test server.
/// \param port Port number of the test server
void setTestServer(const std::string& address, uint16_t port);
-
+
private:
DNSService& dns_service_;
isc::nsas::NameserverAddressStore& nsas_;
@@ -127,7 +166,9 @@ private:
int client_timeout_;
int lookup_timeout_;
unsigned retries_;
+ boost::shared_ptr<RttRecorder> rtt_recorder_; ///< Round-trip time recorder
};
-} // namespace asiolink
+} // namespace asiodns
+} // namespace isc
#endif // __RECURSIVE_QUERY_H
diff --git a/src/lib/resolve/resolver_callback.h b/src/lib/resolve/resolver_callback.h
index f69d8a7..79138e8 100644
--- a/src/lib/resolve/resolver_callback.h
+++ b/src/lib/resolve/resolver_callback.h
@@ -15,9 +15,11 @@
#ifndef _ISC_RESOLVER_CALLBACK_H
#define _ISC_RESOLVER_CALLBACK_H 1
-#include <asiolink/asiolink.h>
+#include <asiodns/dns_server.h>
#include <dns/message.h>
+#include <resolve/resolver_interface.h>
+
namespace isc {
namespace resolve {
@@ -31,7 +33,7 @@ namespace resolve {
/// as the server itself should also have a reference.
class ResolverCallbackServer : public ResolverInterface::Callback {
public:
- ResolverCallbackServer(asiolink::DNSServer* server) :
+ ResolverCallbackServer(asiodns::DNSServer* server) :
server_(server->clone()) {}
~ResolverCallbackServer() { delete server_; };
@@ -39,7 +41,7 @@ public:
void failure();
private:
- asiolink::DNSServer* server_;
+ asiodns::DNSServer* server_;
};
} //namespace resolve
diff --git a/src/lib/resolve/tests/Makefile.am b/src/lib/resolve/tests/Makefile.am
index a403272..edea7cd 100644
--- a/src/lib/resolve/tests/Makefile.am
+++ b/src/lib/resolve/tests/Makefile.am
@@ -27,6 +27,7 @@ run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
run_unittests_LDADD += $(top_builddir)/src/lib/nsas/libnsas.la
run_unittests_LDADD += $(top_builddir)/src/lib/cache/libcache.la
run_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
+run_unittests_LDADD += $(top_builddir)/src/lib/asiodns/libasiodns.la
run_unittests_LDADD += $(top_builddir)/src/lib/resolve/libresolve.la
run_unittests_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
run_unittests_LDADD += $(top_builddir)/src/lib/log/liblog.la
diff --git a/src/lib/resolve/tests/recursive_query_unittest.cc b/src/lib/resolve/tests/recursive_query_unittest.cc
index 4f340c7..3338893 100644
--- a/src/lib/resolve/tests/recursive_query_unittest.cc
+++ b/src/lib/resolve/tests/recursive_query_unittest.cc
@@ -45,16 +45,17 @@
// If we need to test something at the level of underlying ASIO and need
// their definition, that test should go to asiolink/internal/tests.
#include <resolve/recursive_query.h>
+#include <asiodns/dns_lookup.h>
#include <asiolink/io_socket.h>
#include <asiolink/io_service.h>
#include <asiolink/io_message.h>
#include <asiolink/io_error.h>
-#include <asiolink/dns_lookup.h>
#include <asiolink/simple_callback.h>
using isc::UnitTestUtil;
using namespace std;
-using namespace asiolink;
+using namespace isc::asiodns;
+using namespace isc::asiolink;
using namespace isc::dns;
using namespace isc::util;
@@ -317,7 +318,7 @@ protected:
private:
// Currently unused; these will be used for testing
// asynchronous lookup calls via the asyncLookup() method
- boost::shared_ptr<asiolink::IOMessage> io_message_;
+ boost::shared_ptr<isc::asiolink::IOMessage> io_message_;
isc::dns::MessagePtr message_;
isc::dns::MessagePtr answer_message_;
isc::util::OutputBufferPtr respbuf_;
diff --git a/src/lib/resolve/tests/recursive_query_unittest_2.cc b/src/lib/resolve/tests/recursive_query_unittest_2.cc
index 75f026c..3e62336 100644
--- a/src/lib/resolve/tests/recursive_query_unittest_2.cc
+++ b/src/lib/resolve/tests/recursive_query_unittest_2.cc
@@ -17,6 +17,7 @@
#include <iomanip>
#include <iostream>
#include <string>
+#include <vector>
#include <gtest/gtest.h>
#include <boost/bind.hpp>
@@ -37,16 +38,18 @@
#include <dns/rrttl.h>
#include <dns/rdata.h>
-#include <asiolink/dns_service.h>
+#include <util/io_utilities.h>
+#include <asiodns/dns_service.h>
+#include <asiodns/io_fetch.h>
#include <asiolink/io_address.h>
#include <asiolink/io_endpoint.h>
-#include <asiolink/io_fetch.h>
#include <asiolink/io_service.h>
#include <resolve/recursive_query.h>
#include <resolve/resolver_interface.h>
using namespace asio;
using namespace asio::ip;
+using namespace isc::asiolink;
using namespace isc::dns;
using namespace isc::dns::rdata;
using namespace isc::util;
@@ -73,7 +76,8 @@ using namespace std;
/// directed to one or other of the "servers" in the RecursiveQueryTest2 class,
/// regardless of the glue returned in referrals.
-namespace asiolink {
+namespace isc {
+namespace asiodns {
const std::string TEST_ADDRESS = "127.0.0.1"; ///< Servers are on this address
const uint16_t TEST_PORT = 5301; ///< ... and this port
@@ -651,13 +655,17 @@ TEST_F(RecursiveQueryTest2, Resolve) {
boost::bind(&RecursiveQueryTest2::tcpAcceptHandler,
this, _1, 0));
- // Set up the RecursiveQuery object.
+ // Set up the RecursiveQuery object. We will also test that it correctly records
+ // RTT times by setting up a RTT recorder object as well.
std::vector<std::pair<std::string, uint16_t> > upstream; // Empty
std::vector<std::pair<std::string, uint16_t> > upstream_root; // Empty
RecursiveQuery query(dns_service_, *nsas_, cache_,
upstream, upstream_root);
query.setTestServer(TEST_ADDRESS, TEST_PORT);
+ boost::shared_ptr<RttRecorder> recorder(new RttRecorder());
+ query.setRttRecorder(recorder);
+
// Set up callback to receive notification that the query has completed.
isc::resolve::ResolverInterface::CallbackPtr
resolver_callback(new ResolverCallback(service_));
@@ -674,6 +682,17 @@ TEST_F(RecursiveQueryTest2, Resolve) {
ResolverCallback* rc = static_cast<ResolverCallback*>(resolver_callback.get());
EXPECT_TRUE(rc->getRun());
EXPECT_TRUE(rc->getStatus());
+
+ // Finally, check that all the RTTs were "reasonable" (defined here as
+ // being below 2 seconds). This is an explicit check to test that the
+ // variables in the RTT calculation are at least being initialized; if they
+ // weren't, we would expect some absurdly high answers.
+ vector<uint32_t> rtt = recorder->getRtt();
+ EXPECT_GT(rtt.size(), 0);
+ for (int i = 0; i < rtt.size(); ++i) {
+ EXPECT_LT(rtt[i], 2000);
+ }
}
-} // namespace asiolink
+} // namespace asiodns
+} // namespace isc
diff --git a/src/lib/resolve/tests/resolver_callback_unittest.cc b/src/lib/resolve/tests/resolver_callback_unittest.cc
index 6370e22..e94f13d 100644
--- a/src/lib/resolve/tests/resolver_callback_unittest.cc
+++ b/src/lib/resolve/tests/resolver_callback_unittest.cc
@@ -13,8 +13,8 @@
// PERFORMANCE OF THIS SOFTWARE.
#include <gtest/gtest.h>
+#include <asiodns/dns_server.h>
#include <resolve/resolver_callback.h>
-#include <asiolink/asiolink.h>
using namespace isc::resolve;
@@ -22,7 +22,7 @@ using namespace isc::resolve;
// We want to check if resume is called
// Since the server will get cloned(), we want the clones to share
// our bools for whether resume got called and with what value
-class DummyServer : public asiolink::DNSServer {
+class DummyServer : public isc::asiodns::DNSServer {
public:
DummyServer(DummyServer* orig) {
resume_called_ = orig->getResumeCalled();
@@ -31,10 +31,10 @@ public:
DummyServer(bool* resume_called, bool* resume_value) :
resume_called_(resume_called), resume_value_(resume_value)
{}
-
+
bool* getResumeCalled() { return resume_called_; }
bool* getResumeValue() { return resume_value_; }
-
+
DNSServer* clone() {
DummyServer* n = new DummyServer(this);
return n;
diff --git a/src/lib/server_common/portconfig.cc b/src/lib/server_common/portconfig.cc
index 3765f52..941644e 100644
--- a/src/lib/server_common/portconfig.cc
+++ b/src/lib/server_common/portconfig.cc
@@ -15,7 +15,7 @@
#include <server_common/portconfig.h>
#include <asiolink/io_address.h>
-#include <asiolink/dns_service.h>
+#include <asiodns/dns_service.h>
#include <log/dummylog.h>
#include <boost/foreach.hpp>
@@ -23,7 +23,8 @@
using namespace std;
using namespace isc::data;
-using namespace asiolink;
+using namespace isc::asiolink;
+using namespace isc::asiodns;
using isc::log::dlog;
namespace isc {
@@ -82,7 +83,7 @@ setAddresses(DNSService& service, const AddressList& addresses) {
void
installListenAddresses(const AddressList& newAddresses,
AddressList& addressStore,
- asiolink::DNSService& service)
+ isc::asiodns::DNSService& service)
{
try {
dlog("Setting listen addresses:");
diff --git a/src/lib/server_common/portconfig.h b/src/lib/server_common/portconfig.h
index bcb8528..e4e7bf6 100644
--- a/src/lib/server_common/portconfig.h
+++ b/src/lib/server_common/portconfig.h
@@ -25,9 +25,11 @@
/*
* Some forward declarations.
*/
-namespace asiolink {
+namespace isc {
+namespace asiodns {
class DNSService;
}
+}
namespace isc {
namespace server_common {
@@ -112,7 +114,7 @@ parseAddresses(isc::data::ConstElementPtr addresses,
void
installListenAddresses(const AddressList& newAddresses,
AddressList& addressStore,
- asiolink::DNSService& dnsService);
+ asiodns::DNSService& dnsService);
}
}
diff --git a/src/lib/server_common/tests/Makefile.am b/src/lib/server_common/tests/Makefile.am
index 55ccc85..a04a884 100644
--- a/src/lib/server_common/tests/Makefile.am
+++ b/src/lib/server_common/tests/Makefile.am
@@ -12,7 +12,7 @@ endif
# Some versions of GCC warn about some versions of Boost regarding
# missing initializer for members in its posix_time.
# https://svn.boost.org/trac/boost/ticket/3477
-# But older GCC compilers don't have the flag.
+# But older GCC compilers don't have the flag.
AM_CXXFLAGS += $(WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG)
if USE_CLANGPP
@@ -35,6 +35,7 @@ run_unittests_LDADD = $(GTEST_LDADD)
run_unittests_LDADD += $(top_builddir)/src/lib/server_common/libserver_common.la
run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
run_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
+run_unittests_LDADD += $(top_builddir)/src/lib/asiodns/libasiodns.la
run_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.la
run_unittests_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
endif
diff --git a/src/lib/server_common/tests/portconfig_unittest.cc b/src/lib/server_common/tests/portconfig_unittest.cc
index fabdfa2..5262565 100644
--- a/src/lib/server_common/tests/portconfig_unittest.cc
+++ b/src/lib/server_common/tests/portconfig_unittest.cc
@@ -17,6 +17,7 @@
#include <cc/data.h>
#include <exceptions/exceptions.h>
#include <asiolink/asiolink.h>
+#include <asiodns/asiodns.h>
#include <gtest/gtest.h>
#include <string>
@@ -25,7 +26,8 @@ using namespace isc::server_common::portconfig;
using namespace isc::data;
using namespace isc;
using namespace std;
-using namespace asiolink;
+using namespace isc::asiolink;
+using namespace isc::asiodns;
namespace {
diff --git a/src/lib/testutils/mockups.h b/src/lib/testutils/mockups.h
index 4bec83d..2441ad7 100644
--- a/src/lib/testutils/mockups.h
+++ b/src/lib/testutils/mockups.h
@@ -19,7 +19,7 @@
#include <xfr/xfrout_client.h>
-#include <asiolink/asiolink.h>
+#include <asiodns/asiodns.h>
// A minimal mock configuration session. Most the methods are
// stubbed out, except for a very basic group_sendmsg() and
@@ -94,7 +94,7 @@ private:
};
// A nonoperative DNSServer object to be used in calls to processMessage().
-class MockServer : public asiolink::DNSServer {
+class MockServer : public isc::asiodns::DNSServer {
public:
MockServer() : done_(false) {}
void operator()(asio::error_code, size_t) {}
diff --git a/src/lib/testutils/srv_test.cc b/src/lib/testutils/srv_test.cc
index 783aae7..1d79d71 100644
--- a/src/lib/testutils/srv_test.cc
+++ b/src/lib/testutils/srv_test.cc
@@ -12,6 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+#include <config.h>
+
#include <netinet/in.h>
#include <dns/message.h>
@@ -25,8 +27,8 @@
#include <testutils/srv_test.h>
using namespace isc::dns;
-using namespace asiolink;
using namespace isc::util;
+using namespace isc::asiolink;
namespace isc {
namespace testutils {
diff --git a/src/lib/util/Makefile.am b/src/lib/util/Makefile.am
index 39028b6..77a3e4a 100644
--- a/src/lib/util/Makefile.am
+++ b/src/lib/util/Makefile.am
@@ -1,4 +1,6 @@
-SUBDIRS = . tests
+SUBDIRS = . tests unittests io
+# The io/tests is hack, because otherwise we can not order these directories
+# properly. Unittests use io and io/tests use unittest.
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_srcdir)/src/lib/util -I$(top_builddir)/src/lib/util
diff --git a/src/lib/util/buffer.h b/src/lib/util/buffer.h
index 58c75f5..b7a8e28 100644
--- a/src/lib/util/buffer.h
+++ b/src/lib/util/buffer.h
@@ -15,6 +15,8 @@
#ifndef __BUFFER_H
#define __BUFFER_H 1
+#include <stdlib.h>
+#include <cstring>
#include <vector>
#include <string.h>
@@ -286,15 +288,58 @@ public:
/// \brief Constructor from the initial size of the buffer.
///
/// \param len The initial length of the buffer in bytes.
- OutputBuffer(size_t len) { data_.reserve(len); }
+ OutputBuffer(size_t len) :
+ buffer_(NULL),
+ size_(0),
+ allocated_(len)
+ {
+ // We use malloc and free instead of C++ new[] and delete[].
+ // This way we can use realloc, which may in fact do it without a copy.
+ buffer_ = static_cast<uint8_t*>(malloc(allocated_));
+ if (buffer_ == NULL && len != 0) {
+ throw std::bad_alloc();
+ }
+ }
+
+ /// \brief Copy constructor
+ OutputBuffer(const OutputBuffer& other) :
+ buffer_(NULL),
+ size_(other.size_),
+ allocated_(other.allocated_)
+ {
+ buffer_ = static_cast<uint8_t*>(malloc(allocated_));
+ if (buffer_ == NULL && allocated_ != 0) {
+ throw std::bad_alloc();
+ }
+ memcpy(buffer_, other.buffer_, size_);
+ }
+
+ /// \brief Destructor
+ ~ OutputBuffer() {
+ free(buffer_);
+ }
//@}
+ /// \brief Assignment operator
+ OutputBuffer& operator =(const OutputBuffer& other) {
+ uint8_t* newbuff(static_cast<uint8_t*>(malloc(other.allocated_)));
+ if (newbuff == NULL && other.allocated_ != 0) {
+ throw std::bad_alloc();
+ }
+ free(buffer_);
+ buffer_ = newbuff;
+ size_ = other.size_;
+ allocated_ = other.allocated_;
+ memcpy(buffer_, other.buffer_, size_);
+ return (*this);
+ }
+
///
/// \name Getter Methods
///
//@{
/// \brief Return the current capacity of the buffer.
- size_t getCapacity() const { return (data_.capacity()); }
+ size_t getCapacity() const { return (allocated_); }
/// \brief Return a pointer to the head of the data stored in the buffer.
///
/// The caller can assume that the subsequent \c getLength() bytes are
@@ -302,21 +347,21 @@ public:
///
/// Note: The pointer returned by this method may be invalidated after a
/// subsequent write operation.
- const void* getData() const { return (&data_[0]); }
+ const void* getData() const { return (buffer_); }
/// \brief Return the length of data written in the buffer.
- size_t getLength() const { return (data_.size()); }
+ size_t getLength() const { return (size_); }
/// \brief Return the value of the buffer at the specified position.
///
/// \c pos must specify the valid position of the buffer; otherwise an
/// exception class of \c InvalidBufferPosition will be thrown.
///
/// \param pos The position in the buffer to be returned.
- const uint8_t& operator[](size_t pos) const
+ uint8_t operator[](size_t pos) const
{
- if (pos >= data_.size()) {
+ if (pos >= size_) {
isc_throw(InvalidBufferPosition, "read at invalid position");
}
- return (data_[pos]);
+ return (buffer_[pos]);
}
//@}
@@ -330,7 +375,10 @@ public:
/// This method is provided as a shortcut to make a hole in the buffer
/// that is to be filled in later, e.g, by \ref writeUint16At().
/// \param len The length of the gap to be inserted in bytes.
- void skip(size_t len) { data_.insert(data_.end(), len, 0); }
+ void skip(size_t len) {
+ ensureAllocated(size_ + len);
+ size_ += len;
+ }
/// \brief Trim the specified length of data from the end of the buffer.
///
@@ -341,20 +389,23 @@ public:
/// \param len The length of data that should be trimmed.
void trim(size_t len)
{
- if (len > data_.size()) {
+ if (len > size_) {
isc_throw(OutOfRange, "trimming too large from output buffer");
}
- data_.resize(data_.size() - len);
+ size_ -= len;
}
/// \brief Clear buffer content.
///
/// This method can be used to re-initialize and reuse the buffer without
/// constructing a new one.
- void clear() { data_.clear(); }
+ void clear() { size_ = 0; }
/// \brief Write an unsigned 8-bit integer into the buffer.
///
/// \param data The 8-bit integer to be written into the buffer.
- void writeUint8(uint8_t data) { data_.push_back(data); }
+ void writeUint8(uint8_t data) {
+ ensureAllocated(size_ + 1);
+ buffer_[size_ ++] = data;
+ }
/// \brief Write an unsigned 8-bit integer into the buffer.
///
@@ -365,10 +416,10 @@ public:
/// \param data The 8-bit integer to be written into the buffer.
/// \param pos The position in the buffer to write the data.
void writeUint8At(uint8_t data, size_t pos) {
- if (pos + sizeof(data) > data_.size()) {
+ if (pos + sizeof(data) > size_) {
isc_throw(InvalidBufferPosition, "write at invalid position");
}
- data_[pos] = data;
+ buffer_[pos] = data;
}
/// \brief Write an unsigned 16-bit integer in host byte order into the
@@ -377,8 +428,9 @@ public:
/// \param data The 16-bit integer to be written into the buffer.
void writeUint16(uint16_t data)
{
- data_.push_back(static_cast<uint8_t>((data & 0xff00U) >> 8));
- data_.push_back(static_cast<uint8_t>(data & 0x00ffU));
+ ensureAllocated(size_ + sizeof(data));
+ buffer_[size_ ++] = static_cast<uint8_t>((data & 0xff00U) >> 8);
+ buffer_[size_ ++] = static_cast<uint8_t>(data & 0x00ffU);
}
/// \brief Write an unsigned 16-bit integer in host byte order at the
/// specified position of the buffer in network byte order.
@@ -393,12 +445,12 @@ public:
/// \param pos The beginning position in the buffer to write the data.
void writeUint16At(uint16_t data, size_t pos)
{
- if (pos + sizeof(data) > data_.size()) {
+ if (pos + sizeof(data) > size_) {
isc_throw(InvalidBufferPosition, "write at invalid position");
}
- data_[pos] = static_cast<uint8_t>((data & 0xff00U) >> 8);
- data_[pos + 1] = static_cast<uint8_t>(data & 0x00ffU);
+ buffer_[pos] = static_cast<uint8_t>((data & 0xff00U) >> 8);
+ buffer_[pos + 1] = static_cast<uint8_t>(data & 0x00ffU);
}
/// \brief Write an unsigned 32-bit integer in host byte order
/// into the buffer in network byte order.
@@ -406,10 +458,11 @@ public:
/// \param data The 32-bit integer to be written into the buffer.
void writeUint32(uint32_t data)
{
- data_.push_back(static_cast<uint8_t>((data & 0xff000000) >> 24));
- data_.push_back(static_cast<uint8_t>((data & 0x00ff0000) >> 16));
- data_.push_back(static_cast<uint8_t>((data & 0x0000ff00) >> 8));
- data_.push_back(static_cast<uint8_t>(data & 0x000000ff));
+ ensureAllocated(size_ + sizeof(data));
+ buffer_[size_ ++] = static_cast<uint8_t>((data & 0xff000000) >> 24);
+ buffer_[size_ ++] = static_cast<uint8_t>((data & 0x00ff0000) >> 16);
+ buffer_[size_ ++] = static_cast<uint8_t>((data & 0x0000ff00) >> 8);
+ buffer_[size_ ++] = static_cast<uint8_t>(data & 0x000000ff);
}
/// \brief Copy an arbitrary length of data into the buffer.
///
@@ -419,13 +472,38 @@ public:
/// \param len The length of the data in bytes.
void writeData(const void *data, size_t len)
{
- const uint8_t* cp = static_cast<const uint8_t*>(data);
- data_.insert(data_.end(), cp, cp + len);
+ ensureAllocated(size_ + len);
+ memcpy(buffer_ + size_, data, len);
+ size_ += len;
}
//@}
-
+
private:
- std::vector<uint8_t> data_;
+ // The actual data
+ uint8_t* buffer_;
+ // How many bytes are used
+ size_t size_;
+ // How many bytes do we have preallocated (eg. the capacity)
+ size_t allocated_;
+ // Make sure at last needed_size bytes are allocated in the buffer
+ void ensureAllocated(size_t needed_size) {
+ if (allocated_ < needed_size) {
+ // Guess some bigger size
+ size_t new_size = (allocated_ == 0) ? 1024 : allocated_;
+ while (new_size < needed_size) {
+ new_size *= 2;
+ }
+ // Allocate bigger space
+ uint8_t* new_buffer_(static_cast<uint8_t*>(realloc(buffer_,
+ new_size)));
+ if (new_buffer_ == NULL) {
+ // If it fails, the original block is left intact by it
+ throw std::bad_alloc();
+ }
+ buffer_ = new_buffer_;
+ allocated_ = new_size;
+ }
+ }
};
/// \brief Pointer-like types pointing to \c InputBuffer or \c OutputBuffer
diff --git a/src/lib/util/io/Makefile.am b/src/lib/util/io/Makefile.am
new file mode 100644
index 0000000..9f06ef9
--- /dev/null
+++ b/src/lib/util/io/Makefile.am
@@ -0,0 +1,18 @@
+SUBDIRS = . tests
+
+AM_CXXFLAGS = $(B10_CXXFLAGS)
+
+lib_LTLIBRARIES = libutil_io.la
+libutil_io_la_SOURCES = fd.h fd.cc fd_share.h fd_share.cc
+libutil_io_la_CXXFLAGS = $(AM_CXXFLAGS) -fno-strict-aliasing
+
+CLEANFILES = *.gcno *.gcda
+
+pyexec_LTLIBRARIES = libutil_io_python.la
+# Python prefers .so, while some OSes (specifically MacOS) use a different
+# suffix for dynamic objects. -module is necessary to work this around.
+libutil_io_python_la_LDFLAGS = -module
+libutil_io_python_la_SOURCES = fdshare_python.cc
+libutil_io_python_la_LIBADD = libutil_io.la
+libutil_io_python_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
+libutil_io_python_la_CXXFLAGS = $(AM_CXXFLAGS)
diff --git a/src/lib/util/io/fd.cc b/src/lib/util/io/fd.cc
new file mode 100644
index 0000000..04e64dc
--- /dev/null
+++ b/src/lib/util/io/fd.cc
@@ -0,0 +1,70 @@
+// Copyright (C) 2011 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 "fd.h"
+
+#include <unistd.h>
+#include <cerrno>
+
+namespace isc {
+namespace util {
+namespace io {
+
+bool
+write_data(const int fd, const void *buffer_v, const size_t length) {
+ const unsigned char *buffer(static_cast<const unsigned char *>(buffer_v));
+ size_t rest(length);
+ // Just keep writing until all is written
+ while (rest) {
+ ssize_t written(write(fd, buffer, rest));
+ if (rest == -1) {
+ if (errno == EINTR) { // Just keep going
+ continue;
+ } else {
+ return false;
+ }
+ } else { // Wrote something
+ rest -= written;
+ buffer += written;
+ }
+ }
+ return true;
+}
+
+ssize_t
+read_data(const int fd, void *buffer_v, const size_t length) {
+ unsigned char *buffer(static_cast<unsigned char *>(buffer_v));
+ size_t rest(length), already(0);
+ while (rest) { // Stil something to read
+ ssize_t amount(read(fd, buffer, rest));
+ if (rest == -1) {
+ if (errno == EINTR) { // Continue on interrupted call
+ continue;
+ } else {
+ return -1;
+ }
+ } else if (amount) {
+ already += amount;
+ rest -= amount;
+ buffer += amount;
+ } else { // EOF
+ return already;
+ }
+ }
+ return already;
+}
+
+}
+}
+}
diff --git a/src/lib/util/io/fd.h b/src/lib/util/io/fd.h
new file mode 100644
index 0000000..bdd2d41
--- /dev/null
+++ b/src/lib/util/io/fd.h
@@ -0,0 +1,61 @@
+// Copyright (C) 2011 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 __UTIL_IO_FD_H
+#define __UTIL_IO_FD_H 1
+
+#include <unistd.h>
+
+/**
+ * @file fd.h
+ * @short Wrappers around common unix fd manipulation functions.
+ */
+
+namespace isc {
+namespace util {
+namespace io {
+
+/*
+ * \short write() that writes everything.
+ * Wrapper around write(). The difference is, it never writes less data
+ * and looks successfull (eg. it blocks until all data are written).
+ * Retries on signals.
+ *
+ * \return True if sucessfull, false otherwise. The errno variable is left
+ * intact.
+ * \param fd Where to write.
+ * \param data The buffer to write.
+ * \param length How much data is there to write.
+ */
+bool
+write_data(const int fd, const void *data, const size_t length);
+
+/*
+ * \short read() that reads everything.
+ * Wrapper around read(). It does not do short reads, if it returns less,
+ * it means there was EOF. It retries on signals.
+ *
+ * \return Number of bytes read or -1 on error.
+ * \param fd Where to read data from.
+ * \param data Where to put the data.
+ * \param length How many of them.
+ */
+ssize_t
+read_data(const int fd, void *buffer, const size_t length);
+
+}
+}
+}
+
+#endif // __UTIL_IO_FD_H
diff --git a/src/lib/util/io/fd_share.cc b/src/lib/util/io/fd_share.cc
new file mode 100644
index 0000000..92576e0
--- /dev/null
+++ b/src/lib/util/io/fd_share.cc
@@ -0,0 +1,139 @@
+// Copyright (C) 2010 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 <cstring>
+#include <cstdlib>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <stdlib.h> // for malloc and free
+#include "fd_share.h"
+
+namespace isc {
+namespace util {
+namespace io {
+
+namespace {
+// Not all OSes support advanced CMSG macros: CMSG_LEN and CMSG_SPACE.
+// In order to ensure as much portability as possible, we provide wrapper
+// functions of these macros.
+// Note that cmsg_space() could run slow on OSes that do not have
+// CMSG_SPACE.
+inline socklen_t
+cmsg_len(const socklen_t len) {
+#ifdef CMSG_LEN
+ return (CMSG_LEN(len));
+#else
+ // Cast NULL so that any pointer arithmetic performed by CMSG_DATA
+ // is correct.
+ const uintptr_t hdrlen = (uintptr_t)CMSG_DATA(((struct cmsghdr*)NULL));
+ return (hdrlen + len);
+#endif
+}
+
+inline socklen_t
+cmsg_space(const socklen_t len) {
+#ifdef CMSG_SPACE
+ return (CMSG_SPACE(len));
+#else
+ struct msghdr msg;
+ struct cmsghdr* cmsgp;
+ // XXX: The buffer length is an ad hoc value, but should be enough
+ // in a practical sense.
+ char dummybuf[sizeof(struct cmsghdr) + 1024];
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_control = dummybuf;
+ msg.msg_controllen = sizeof(dummybuf);
+
+ cmsgp = (struct cmsghdr*)dummybuf;
+ cmsgp->cmsg_len = cmsg_len(len);
+
+ cmsgp = CMSG_NXTHDR(&msg, cmsgp);
+ if (cmsgp != NULL) {
+ return ((char*)cmsgp - (char*)msg.msg_control);
+ } else {
+ return (0);
+ }
+#endif // CMSG_SPACE
+}
+}
+
+int
+recv_fd(const int sock) {
+ struct msghdr msghdr;
+ struct iovec iov_dummy;
+ unsigned char dummy_data;
+
+ iov_dummy.iov_base = &dummy_data;
+ iov_dummy.iov_len = sizeof(dummy_data);
+ msghdr.msg_name = NULL;
+ msghdr.msg_namelen = 0;
+ msghdr.msg_iov = &iov_dummy;
+ msghdr.msg_iovlen = 1;
+ msghdr.msg_flags = 0;
+ msghdr.msg_controllen = cmsg_space(sizeof(int));
+ msghdr.msg_control = malloc(msghdr.msg_controllen);
+ if (msghdr.msg_control == NULL) {
+ return (FD_OTHER_ERROR);
+ }
+
+ if (recvmsg(sock, &msghdr, 0) < 0) {
+ free(msghdr.msg_control);
+ return (FD_COMM_ERROR);
+ }
+ const struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msghdr);
+ int fd = FD_OTHER_ERROR;
+ if (cmsg != NULL && cmsg->cmsg_len == cmsg_len(sizeof(int)) &&
+ cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
+ fd = *(const int*)CMSG_DATA(cmsg);
+ }
+ free(msghdr.msg_control);
+ return (fd);
+}
+
+int
+send_fd(const int sock, const int fd) {
+ struct msghdr msghdr;
+ struct iovec iov_dummy;
+ unsigned char dummy_data = 0;
+
+ iov_dummy.iov_base = &dummy_data;
+ iov_dummy.iov_len = sizeof(dummy_data);
+ msghdr.msg_name = NULL;
+ msghdr.msg_namelen = 0;
+ msghdr.msg_iov = &iov_dummy;
+ msghdr.msg_iovlen = 1;
+ msghdr.msg_flags = 0;
+ msghdr.msg_controllen = cmsg_space(sizeof(int));
+ msghdr.msg_control = malloc(msghdr.msg_controllen);
+ if (msghdr.msg_control == NULL) {
+ return (FD_OTHER_ERROR);
+ }
+
+ struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msghdr);
+ cmsg->cmsg_len = cmsg_len(sizeof(int));
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ *(int*)CMSG_DATA(cmsg) = fd;
+
+ const int ret = sendmsg(sock, &msghdr, 0);
+ free(msghdr.msg_control);
+ return (ret >= 0 ? 0 : FD_COMM_ERROR);
+}
+
+} // End for namespace io
+} // End for namespace util
+} // End for namespace isc
diff --git a/src/lib/util/io/fd_share.h b/src/lib/util/io/fd_share.h
new file mode 100644
index 0000000..b74d4ef
--- /dev/null
+++ b/src/lib/util/io/fd_share.h
@@ -0,0 +1,65 @@
+// Copyright (C) 2011 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 FD_SHARE_H_
+#define FD_SHARE_H_
+
+/**
+ * \file fd_share.h
+ * \short Support to transfer file descriptors between processes.
+ * \todo This interface is very C-ish. Should we have some kind of exceptions?
+ */
+
+namespace isc {
+namespace util {
+namespace io {
+
+const int FD_COMM_ERROR = -2;
+const int FD_OTHER_ERROR = -1;
+
+/**
+ * \short Receives a file descriptor.
+ * This receives a file descriptor sent over an unix domain socket. This
+ * is the counterpart of send_fd().
+ *
+ * \return FD_COMM_ERROR when there's error receiving the socket, FD_OTHER_ERROR
+ * when there's a different error.
+ * \param sock The unix domain socket to read from. Tested and it does
+ * not work with a pipe.
+ */
+int recv_fd(const int sock);
+
+/**
+ * \short Sends a file descriptor.
+ * This sends a file descriptor over an unix domain socket. This is the
+ * counterpart of recv_fd().
+ *
+ * \return FD_COMM_ERROR when there's error sending the socket, FD_OTHER_ERROR
+ * for all other possible errors.
+ * \param sock The unix domain socket to send to. Tested and it does not
+ * work with a pipe.
+ * \param fd The file descriptor to send. It should work with any valid
+ * file descriptor.
+ */
+int send_fd(const int sock, const int fd);
+
+} // End for namespace io
+} // End for namespace util
+} // End for namespace isc
+
+#endif
+
+// Local Variables:
+// mode: c++
+// End:
diff --git a/src/lib/util/io/fdshare_python.cc b/src/lib/util/io/fdshare_python.cc
new file mode 100644
index 0000000..0a41107
--- /dev/null
+++ b/src/lib/util/io/fdshare_python.cc
@@ -0,0 +1,97 @@
+// Copyright (C) 2010 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.
+
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+#include <structmember.h>
+
+#include <config.h>
+
+#include "fd_share.h"
+
+
+static PyObject*
+fdshare_recv_fd(PyObject*, PyObject* args) {
+ int sock, fd;
+ if (!PyArg_ParseTuple(args, "i", &sock)) {
+ return (NULL);
+ }
+ fd = isc::util::io::recv_fd(sock);
+ return (Py_BuildValue("i", fd));
+}
+
+static PyObject*
+fdshare_send_fd(PyObject*, PyObject* args) {
+ int sock, fd, result;
+ if (!PyArg_ParseTuple(args, "ii", &sock, &fd)) {
+ return (NULL);
+ }
+ result = isc::util::io::send_fd(sock, fd);
+ return (Py_BuildValue("i", result));
+}
+
+static PyMethodDef fdshare_Methods[] = {
+ {"send_fd", fdshare_send_fd, METH_VARARGS, ""},
+ {"recv_fd", fdshare_recv_fd, METH_VARARGS, ""},
+ {NULL, NULL, 0, NULL} /* Sentinel */
+};
+
+
+static PyModuleDef bind10_fdshare_python = {
+ { PyObject_HEAD_INIT(NULL) NULL, 0, NULL},
+ "bind10_fdshare",
+ "Python bindings for fdshare",
+ -1,
+ fdshare_Methods,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+PyMODINIT_FUNC
+PyInit_libutil_io_python(void) {
+ PyObject *mod = PyModule_Create(&bind10_fdshare_python);
+ if (mod == NULL) {
+ return (NULL);
+ }
+
+ PyObject* FD_COMM_ERROR = Py_BuildValue("i", isc::util::io::FD_COMM_ERROR);
+ if (FD_COMM_ERROR == NULL) {
+ Py_XDECREF(mod);
+ return (NULL);
+ }
+ int ret = PyModule_AddObject(mod, "FD_COMM_ERROR", FD_COMM_ERROR);
+ if (-1 == ret) {
+ Py_XDECREF(FD_COMM_ERROR);
+ Py_XDECREF(mod);
+ return (NULL);
+ }
+
+ PyObject* FD_OTHER_ERROR = Py_BuildValue("i",
+ isc::util::io::FD_OTHER_ERROR);
+ if (FD_OTHER_ERROR == NULL) {
+ Py_XDECREF(mod);
+ return (NULL);
+ }
+ ret = PyModule_AddObject(mod, "FD_OTHER_ERROR", FD_OTHER_ERROR);
+ if (-1 == ret) {
+ Py_XDECREF(FD_OTHER_ERROR);
+ Py_XDECREF(mod);
+ return (NULL);
+ }
+
+ return (mod);
+}
+
diff --git a/src/lib/util/io/tests/Makefile.am b/src/lib/util/io/tests/Makefile.am
new file mode 100644
index 0000000..56d50cf
--- /dev/null
+++ b/src/lib/util/io/tests/Makefile.am
@@ -0,0 +1,25 @@
+CLEANFILES = *.gcno *.gcda
+
+AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CXXFLAGS = $(B10_CXXFLAGS)
+
+if USE_STATIC_LINK
+AM_LDFLAGS = -static
+endif
+
+TESTS =
+if HAVE_GTEST
+TESTS += run_unittests
+run_unittests_SOURCES = run_unittests.cc
+run_unittests_SOURCES += fd_tests.cc
+run_unittests_SOURCES += fd_share_tests.cc
+
+run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
+run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
+run_unittests_LDADD = $(GTEST_LDADD)
+run_unittests_LDADD += $(top_builddir)/src/lib/util/io/libutil_io.la
+run_unittests_LDADD += \
+ $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
+endif
+
+noinst_PROGRAMS = $(TESTS)
diff --git a/src/lib/util/io/tests/fd_share_tests.cc b/src/lib/util/io/tests/fd_share_tests.cc
new file mode 100644
index 0000000..0902ce0
--- /dev/null
+++ b/src/lib/util/io/tests/fd_share_tests.cc
@@ -0,0 +1,74 @@
+// Copyright (C) 2011 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 "../fd.h"
+#include "../fd_share.h"
+
+#include <util/unittests/fork.h>
+
+#include <gtest/gtest.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <cstdio>
+
+using namespace isc::util::io;
+using namespace isc::util::unittests;
+
+namespace {
+
+// We test that we can transfer a pipe over other pipe
+TEST(FDShare, transfer) {
+ // Get a pipe and fork
+ int pipes[2];
+ ASSERT_NE(-1, socketpair(AF_UNIX, SOCK_STREAM, 0, pipes));
+ pid_t sender(fork());
+ ASSERT_NE(-1, sender);
+ if(sender) { // We are in parent
+ // Close the other side of pipe, we want only writible one
+ EXPECT_NE(-1, close(pipes[0]));
+ // Get a process to check data
+ int fd(0);
+ pid_t checker(check_output(&fd, "data", 4));
+ ASSERT_NE(-1, checker);
+ // Now, send the file descriptor, close it and close the pipe
+ EXPECT_NE(-1, send_fd(pipes[1], fd));
+ EXPECT_NE(-1, close(pipes[1]));
+ EXPECT_NE(-1, close(fd));
+ // Check both subprocesses ended well
+ EXPECT_TRUE(process_ok(sender));
+ EXPECT_TRUE(process_ok(checker));
+ } else { // We are in child. We do not use ASSERT here
+ // Close the write end, we only read
+ if(close(pipes[1])) {
+ exit(1);
+ }
+ // Get the file descriptor
+ int fd(recv_fd(pipes[0]));
+ if(fd == -1) {
+ exit(1);
+ }
+ // This pipe is not needed
+ if(close(pipes[0])) {
+ exit(1);
+ }
+ // Send "data" trough the received fd, close it and be done
+ if(!write_data(fd, "data", 4) || close(fd) == -1) {
+ exit(1);
+ }
+ exit(0);
+ }
+}
+
+}
diff --git a/src/lib/util/io/tests/fd_tests.cc b/src/lib/util/io/tests/fd_tests.cc
new file mode 100644
index 0000000..12b70d8
--- /dev/null
+++ b/src/lib/util/io/tests/fd_tests.cc
@@ -0,0 +1,66 @@
+// Copyright (C) 2011 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 "../fd.h"
+
+#include <util/unittests/fork.h>
+
+#include <gtest/gtest.h>
+
+using namespace isc::util::io;
+using namespace isc::util::unittests;
+
+namespace {
+
+// Make sure the test is large enough and does not fit into one
+// read or write request
+const size_t TEST_DATA_SIZE = 8 * 1024 * 1024;
+
+class FDTest : public ::testing::Test {
+ public:
+ unsigned char *data, *buffer;
+ FDTest() :
+ // We do not care what is inside, we just need it to be the same
+ data(new unsigned char[TEST_DATA_SIZE]),
+ buffer(NULL)
+ { }
+ ~ FDTest() {
+ delete[] data;
+ delete[] buffer;
+ }
+};
+
+// Test we read what was sent
+TEST_F(FDTest, read) {
+ int read_pipe(0);
+ buffer = new unsigned char[TEST_DATA_SIZE];
+ pid_t feeder(provide_input(&read_pipe, data, TEST_DATA_SIZE));
+ ASSERT_GE(feeder, 0);
+ ssize_t received(read_data(read_pipe, buffer, TEST_DATA_SIZE));
+ EXPECT_TRUE(process_ok(feeder));
+ EXPECT_EQ(TEST_DATA_SIZE, received);
+ EXPECT_EQ(0, memcmp(data, buffer, received));
+}
+
+// Test we write the correct thing
+TEST_F(FDTest, write) {
+ int write_pipe(0);
+ pid_t checker(check_output(&write_pipe, data, TEST_DATA_SIZE));
+ ASSERT_GE(checker, 0);
+ EXPECT_TRUE(write_data(write_pipe, data, TEST_DATA_SIZE));
+ EXPECT_EQ(0, close(write_pipe));
+ EXPECT_TRUE(process_ok(checker));
+}
+
+}
diff --git a/src/lib/util/io/tests/run_unittests.cc b/src/lib/util/io/tests/run_unittests.cc
new file mode 100644
index 0000000..e787ab1
--- /dev/null
+++ b/src/lib/util/io/tests/run_unittests.cc
@@ -0,0 +1,22 @@
+// Copyright (C) 2011 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 <gtest/gtest.h>
+
+int
+main(int argc, char *argv[]) {
+ ::testing::InitGoogleTest(&argc, argv);
+
+ return RUN_ALL_TESTS();
+}
diff --git a/src/lib/util/locks.h b/src/lib/util/locks.h
index c9fc82d..971c413 100644
--- a/src/lib/util/locks.h
+++ b/src/lib/util/locks.h
@@ -26,11 +26,6 @@
/// Note that we need to include <config.h> in our .cc files for that
/// to be set. we might want to enfore this at compile time with a check
/// (TODO)
-/// Note that this also contains a workaround for Sunstudio; which
-/// probably won't completely work right now (that is, if the TODO
-/// above is completed), since that would also require some changes
-/// in most (at first glance unrelated) Makefiles
-/// (TODO2)
#ifndef __LOCKS_
#define __LOCKS_
diff --git a/src/lib/util/tests/buffer_unittest.cc b/src/lib/util/tests/buffer_unittest.cc
index 7578370..0cd1823 100644
--- a/src/lib/util/tests/buffer_unittest.cc
+++ b/src/lib/util/tests/buffer_unittest.cc
@@ -190,4 +190,53 @@ TEST_F(BufferTest, outputBufferClear) {
obuffer.clear();
EXPECT_EQ(0, obuffer.getLength());
}
+
+TEST_F(BufferTest, outputBufferCopy) {
+ obuffer.writeData(testdata, sizeof(testdata));
+
+ EXPECT_NO_THROW({
+ OutputBuffer copy(obuffer);
+ ASSERT_EQ(sizeof(testdata), copy.getLength());
+ for (int i = 0; i < sizeof(testdata); i ++) {
+ EXPECT_EQ(testdata[i], copy[i]);
+ if (i + 1 < sizeof(testdata)) {
+ obuffer.writeUint16At(0, i);
+ }
+ EXPECT_EQ(testdata[i], copy[i]);
+ }
+ obuffer.clear();
+ ASSERT_EQ(sizeof(testdata), copy.getLength());
+ });
+}
+
+TEST_F(BufferTest, outputBufferAssign) {
+ OutputBuffer another(0);
+ another.clear();
+ obuffer.writeData(testdata, sizeof(testdata));
+
+ EXPECT_NO_THROW({
+ another = obuffer;
+ ASSERT_EQ(sizeof(testdata), another.getLength());
+ for (int i = 0; i < sizeof(testdata); i ++) {
+ EXPECT_EQ(testdata[i], another[i]);
+ if (i + 1 < sizeof(testdata)) {
+ obuffer.writeUint16At(0, i);
+ }
+ EXPECT_EQ(testdata[i], another[i]);
+ }
+ obuffer.clear();
+ ASSERT_EQ(sizeof(testdata), another.getLength());
+ });
+}
+
+TEST_F(BufferTest, outputBufferZeroSize) {
+ // Some OSes might return NULL on malloc for 0 size, so check it works
+ EXPECT_NO_THROW({
+ OutputBuffer first(0);
+ OutputBuffer copy(first);
+ OutputBuffer second(0);
+ second = first;
+ });
+}
+
}
diff --git a/src/lib/util/unittests/Makefile.am b/src/lib/util/unittests/Makefile.am
new file mode 100644
index 0000000..0ea8653
--- /dev/null
+++ b/src/lib/util/unittests/Makefile.am
@@ -0,0 +1,9 @@
+AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CXXFLAGS = $(B10_CXXFLAGS)
+
+lib_LTLIBRARIES = libutil_unittests.la
+libutil_unittests_la_SOURCES = fork.h fork.cc
+libutil_unittests_la_LIBADD = \
+ $(top_builddir)/src/lib/util/io/libutil_io.la
+
+CLEANFILES = *.gcno *.gcda
diff --git a/src/lib/util/unittests/README b/src/lib/util/unittests/README
new file mode 100644
index 0000000..0ed888f
--- /dev/null
+++ b/src/lib/util/unittests/README
@@ -0,0 +1,5 @@
+This directory contains some code that is useful while writing various
+unittest code. It doesn't contain any code that would actually run in
+bind10.
+
+Because this is a test code, we do not test it explicitly.
diff --git a/src/lib/util/unittests/fork.cc b/src/lib/util/unittests/fork.cc
new file mode 100644
index 0000000..3414a3c
--- /dev/null
+++ b/src/lib/util/unittests/fork.cc
@@ -0,0 +1,145 @@
+// Copyright (C) 2011 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 "fork.h"
+
+#include <util/io/fd.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <cerrno>
+#include <stdlib.h>
+#include <stdio.h>
+
+using namespace isc::util::io;
+
+namespace {
+
+// Just a NOP function to ignore a signal but let it interrupt function.
+void no_handler(int) { }
+
+};
+
+namespace isc {
+namespace util {
+namespace unittests {
+
+bool
+process_ok(pid_t process) {
+ // Create a timeout
+ struct sigaction ignored, original;
+ memset(&ignored, 0, sizeof ignored);
+ ignored.sa_handler = no_handler;
+ if (sigaction(SIGALRM, &ignored, &original)) {
+ return false;
+ }
+ // It is long, but if everything is OK, it'll not happen
+ alarm(10);
+ int status;
+ int result(waitpid(process, &status, 0) == -1);
+ // Cancel the alarm and return the original handler
+ alarm(0);
+ if (sigaction(SIGALRM, &original, NULL)) {
+ return false;
+ }
+ // Check what we found out
+ if (result) {
+ if (errno == EINTR)
+ kill(process, SIGTERM);
+ return false;
+ }
+ return WIFEXITED(status) && WEXITSTATUS(status) == 0;
+}
+
+/*
+ * This creates a pipe, forks and feeds the pipe with given data.
+ * Used to provide the input in non-blocking/asynchronous way.
+ */
+pid_t
+provide_input(int *read_pipe, const void *input, const size_t length)
+{
+ int pipes[2];
+ if (pipe(pipes)) {
+ return -1;
+ }
+ *read_pipe = pipes[0];
+ pid_t pid(fork());
+ if (pid) { // We are in the parent
+ return pid;
+ } else { // This is in the child, just puth the data there
+ close(pipes[0]);
+ if (!write_data(pipes[1], input, length)) {
+ exit(1);
+ } else {
+ close(pipes[1]);
+ exit(0);
+ }
+ }
+}
+
+/*
+ * This creates a pipe, forks and reads the pipe and compares it
+ * with given data. Used to check output of run in asynchronous way.
+ */
+pid_t
+check_output(int *write_pipe, const void *output, const size_t length)
+{
+ int pipes[2];
+ if (pipe(pipes)) {
+ return -1;
+ }
+ *write_pipe = pipes[1];
+ pid_t pid(fork());
+ if (pid) { // We are in parent
+ close(pipes[0]);
+ return pid;
+ } else {
+ close(pipes[1]);
+ // We don't return the memory, but we're in tests and end this process
+ // right away.
+ unsigned char *buffer = new unsigned char[length + 1];
+ // Try to read one byte more to see if the output ends here
+ size_t got_length(read_data(pipes[0], buffer, length + 1));
+ bool ok(true);
+ if (got_length != length) {
+ fprintf(stderr, "Different length (expected %u, got %u)\n",
+ static_cast<unsigned>(length),
+ static_cast<unsigned>(got_length));
+ ok = false;
+ }
+ if(!ok || memcmp(buffer, output, length)) {
+ const unsigned char *output_c(static_cast<const unsigned char *>(
+ output));
+ // If they differ, print what we have
+ for(size_t i(0); i != got_length; ++ i) {
+ fprintf(stderr, "%02hhx", buffer[i]);
+ }
+ fprintf(stderr, "\n");
+ for(size_t i(0); i != length; ++ i) {
+ fprintf(stderr, "%02hhx", output_c[i]);
+ }
+ fprintf(stderr, "\n");
+ exit(1);
+ } else {
+ exit(0);
+ }
+ }
+}
+
+}
+}
+}
diff --git a/src/lib/util/unittests/fork.h b/src/lib/util/unittests/fork.h
new file mode 100644
index 0000000..3331cfa
--- /dev/null
+++ b/src/lib/util/unittests/fork.h
@@ -0,0 +1,52 @@
+// Copyright (C) 2011 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 __UTIL_UNITTESTS_FORK_H
+#define __UTIL_UNITTESTS_FORK_H 1
+
+#include <unistd.h>
+
+/**
+ * @file fork.h
+ * @short Help functions to fork the test case process.
+ * Various functions to fork a process and feed some data to pipe, check
+ * its output and such lives here.
+ */
+
+namespace isc {
+namespace util {
+namespace unittests {
+
+/**
+ * @short Checks that a process terminates correctly.
+ * Waits for a process to terminate (with a short timeout, this should be
+ * used whan the process is about tu terminate) and checks its exit code.
+ *
+ * @return True if the process terminates with 0, false otherwise.
+ * @param process The ID of process to wait for.
+ */
+bool
+process_ok(pid_t process);
+
+pid_t
+provide_input(int *read_pipe, const void *input, const size_t length);
+
+pid_t
+check_output(int *write_pipe, const void *output, const size_t length);
+
+} // End of the namespace
+}
+}
+
+#endif // __UTIL_UNITTESTS_FORK_H
diff --git a/src/lib/xfr/Makefile.am b/src/lib/xfr/Makefile.am
index 79cee73..d714990 100644
--- a/src/lib/xfr/Makefile.am
+++ b/src/lib/xfr/Makefile.am
@@ -2,7 +2,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
AM_CPPFLAGS += $(BOOST_INCLUDES)
-AM_CXXFLAGS = $(B10_CXXFLAGS) -Wno-strict-aliasing
+AM_CXXFLAGS = $(B10_CXXFLAGS)
AM_CXXFLAGS += -Wno-unused-parameter # see src/lib/cc/Makefile.am
if USE_CLANGPP
AM_CXXFLAGS += -Wno-error
@@ -11,13 +11,5 @@ endif
CLEANFILES = *.gcno *.gcda
lib_LTLIBRARIES = libxfr.la
-libxfr_la_SOURCES = xfrout_client.h xfrout_client.cc
-libxfr_la_SOURCES += fd_share.h fd_share.cc
-
-pyexec_LTLIBRARIES = libxfr_python.la
-# Python prefers .so, while some OSes (specifically MacOS) use a different
-# suffix for dynamic objects. -module is necessary to work this around.
-libxfr_python_la_LDFLAGS = -module
-libxfr_python_la_SOURCES = fdshare_python.cc fd_share.cc fd_share.h
-libxfr_python_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
-libxfr_python_la_CXXFLAGS = $(AM_CXXFLAGS)
+libxfr_la_SOURCES = xfrout_client.h xfrout_client.cc
+libxfr_la_LIBADD = $(top_builddir)/src/lib/util/io/libutil_io.la
diff --git a/src/lib/xfr/fd_share.cc b/src/lib/xfr/fd_share.cc
deleted file mode 100644
index 4e1f093..0000000
--- a/src/lib/xfr/fd_share.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (C) 2010 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 <cstring>
-#include <cstdlib>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <stdlib.h> // for malloc and free
-#include <xfr/fd_share.h>
-
-namespace isc {
-namespace xfr {
-
-namespace {
-// Not all OSes support advanced CMSG macros: CMSG_LEN and CMSG_SPACE.
-// In order to ensure as much portability as possible, we provide wrapper
-// functions of these macros.
-// Note that cmsg_space() could run slow on OSes that do not have
-// CMSG_SPACE.
-inline socklen_t
-cmsg_len(const socklen_t len) {
-#ifdef CMSG_LEN
- return (CMSG_LEN(len));
-#else
- // Cast NULL so that any pointer arithmetic performed by CMSG_DATA
- // is correct.
- const uintptr_t hdrlen = (uintptr_t)CMSG_DATA(((struct cmsghdr*)NULL));
- return (hdrlen + len);
-#endif
-}
-
-inline socklen_t
-cmsg_space(const socklen_t len) {
-#ifdef CMSG_SPACE
- return (CMSG_SPACE(len));
-#else
- struct msghdr msg;
- struct cmsghdr* cmsgp;
- // XXX: The buffer length is an ad hoc value, but should be enough
- // in a practical sense.
- char dummybuf[sizeof(struct cmsghdr) + 1024];
-
- memset(&msg, 0, sizeof(msg));
- msg.msg_control = dummybuf;
- msg.msg_controllen = sizeof(dummybuf);
-
- cmsgp = (struct cmsghdr*)dummybuf;
- cmsgp->cmsg_len = cmsg_len(len);
-
- cmsgp = CMSG_NXTHDR(&msg, cmsgp);
- if (cmsgp != NULL) {
- return ((char*)cmsgp - (char*)msg.msg_control);
- } else {
- return (0);
- }
-#endif // CMSG_SPACE
-}
-}
-
-int
-recv_fd(const int sock) {
- struct msghdr msghdr;
- struct iovec iov_dummy;
- unsigned char dummy_data;
-
- iov_dummy.iov_base = &dummy_data;
- iov_dummy.iov_len = sizeof(dummy_data);
- msghdr.msg_name = NULL;
- msghdr.msg_namelen = 0;
- msghdr.msg_iov = &iov_dummy;
- msghdr.msg_iovlen = 1;
- msghdr.msg_flags = 0;
- msghdr.msg_controllen = cmsg_space(sizeof(int));
- msghdr.msg_control = malloc(msghdr.msg_controllen);
- if (msghdr.msg_control == NULL) {
- return (-1);
- }
-
- if (recvmsg(sock, &msghdr, 0) < 0) {
- free(msghdr.msg_control);
- return (XFR_FD_RECEIVE_FAIL);
- }
- const struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msghdr);
- int fd = -1;
- if (cmsg != NULL && cmsg->cmsg_len == cmsg_len(sizeof(int)) &&
- cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
- fd = *(const int*)CMSG_DATA(cmsg);
- }
- free(msghdr.msg_control);
- return (fd);
-}
-
-int
-send_fd(const int sock, const int fd) {
- struct msghdr msghdr;
- struct iovec iov_dummy;
- unsigned char dummy_data = 0;
-
- iov_dummy.iov_base = &dummy_data;
- iov_dummy.iov_len = sizeof(dummy_data);
- msghdr.msg_name = NULL;
- msghdr.msg_namelen = 0;
- msghdr.msg_iov = &iov_dummy;
- msghdr.msg_iovlen = 1;
- msghdr.msg_flags = 0;
- msghdr.msg_controllen = cmsg_space(sizeof(int));
- msghdr.msg_control = malloc(msghdr.msg_controllen);
- if (msghdr.msg_control == NULL) {
- return (-1);
- }
-
- struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msghdr);
- cmsg->cmsg_len = cmsg_len(sizeof(int));
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- *(int*)CMSG_DATA(cmsg) = fd;
-
- const int ret = sendmsg(sock, &msghdr, 0);
- free(msghdr.msg_control);
- return (ret >= 0 ? 0 : -1);
-}
-
-} // End for namespace xfr
-} // End for namespace isc
diff --git a/src/lib/xfr/fd_share.h b/src/lib/xfr/fd_share.h
deleted file mode 100644
index 4ee5fd5..0000000
--- a/src/lib/xfr/fd_share.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (C) 2010 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 FD_SHARE_H_
-#define FD_SHARE_H_
-
-namespace isc {
-namespace xfr {
-
-/// Failed to receive xfr socket descriptor "fd" on unix domain socket 'sock'
-const int XFR_FD_RECEIVE_FAIL = -2;
-
-// Receive socket descriptor on unix domain socket 'sock'.
-// Returned value is the socket descriptor received.
-// Returned XFR_FD_RECEIVE_FAIL if failed to receive xfr socket descriptor
-// Errors are indicated by a return value of -1.
-int recv_fd(const int sock);
-
-// Send socket descriptor "fd" to server over unix domain socket 'sock',
-// the connection from socket 'sock' to unix domain server should be established first.
-// Errors are indicated by a return value of -1.
-int send_fd(const int sock, const int fd);
-
-} // End for namespace xfr
-} // End for namespace isc
-
-#endif
-
-// Local Variables:
-// mode: c++
-// End:
diff --git a/src/lib/xfr/fdshare_python.cc b/src/lib/xfr/fdshare_python.cc
deleted file mode 100644
index 82b1b6e..0000000
--- a/src/lib/xfr/fdshare_python.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (C) 2010 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.
-
-#define PY_SSIZE_T_CLEAN
-#include <Python.h>
-#include <structmember.h>
-
-#include <config.h>
-
-#include <xfr/fd_share.h>
-
-
-static PyObject*
-fdshare_recv_fd(PyObject*, PyObject* args) {
- int sock, fd;
- if (!PyArg_ParseTuple(args, "i", &sock)) {
- return (NULL);
- }
- fd = isc::xfr::recv_fd(sock);
- return (Py_BuildValue("i", fd));
-}
-
-static PyObject*
-fdshare_send_fd(PyObject*, PyObject* args) {
- int sock, fd, result;
- if (!PyArg_ParseTuple(args, "ii", &sock, &fd)) {
- return (NULL);
- }
- result = isc::xfr::send_fd(sock, fd);
- return (Py_BuildValue("i", result));
-}
-
-static PyMethodDef fdshare_Methods[] = {
- {"send_fd", fdshare_send_fd, METH_VARARGS, ""},
- {"recv_fd", fdshare_recv_fd, METH_VARARGS, ""},
- {NULL, NULL, 0, NULL} /* Sentinel */
-};
-
-
-static PyModuleDef bind10_fdshare_python = {
- { PyObject_HEAD_INIT(NULL) NULL, 0, NULL},
- "bind10_fdshare",
- "Python bindings for fdshare",
- -1,
- fdshare_Methods,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-PyMODINIT_FUNC
-PyInit_libxfr_python(void) {
- PyObject* mod = PyModule_Create(&bind10_fdshare_python);
- if (mod == NULL) {
- return (NULL);
- }
-
- PyObject* XFR_FD_RECEIVE_FAIL = Py_BuildValue("i", isc::xfr::XFR_FD_RECEIVE_FAIL);
- if (XFR_FD_RECEIVE_FAIL == NULL) {
- Py_XDECREF(mod);
- return (NULL);
- }
- int ret = PyModule_AddObject(mod, "XFR_FD_RECEIVE_FAIL", XFR_FD_RECEIVE_FAIL);
- if (-1 == ret) {
- Py_XDECREF(XFR_FD_RECEIVE_FAIL);
- Py_XDECREF(mod);
- return (NULL);
- }
-
- return (mod);
-}
-
diff --git a/src/lib/xfr/python_xfr.cc b/src/lib/xfr/python_xfr.cc
deleted file mode 100644
index 52848ad..0000000
--- a/src/lib/xfr/python_xfr.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (C) 2010 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 <boost/python.hpp>
-#include <boost/python/class.hpp>
-#include <boost/python/module.hpp>
-#include <boost/python/def.hpp>
-#include <boost/python/exception_translator.hpp>
-#include <boost/python/return_internal_reference.hpp>
-#include <boost/python/copy_const_reference.hpp>
-#include <boost/shared_ptr.hpp>
-
-#include <xfr/fd_share.h>
-
-using namespace isc::xfr;
-using namespace boost::python;
-
-BOOST_PYTHON_MODULE(bind10_xfr) {
- def("recv_fd", &recv_fd);
- def("send_fd", &send_fd);
-}
diff --git a/src/lib/xfr/xfrout_client.cc b/src/lib/xfr/xfrout_client.cc
index e9e736b..6ab905b 100644
--- a/src/lib/xfr/xfrout_client.cc
+++ b/src/lib/xfr/xfrout_client.cc
@@ -20,10 +20,11 @@
#include <unistd.h>
#include <asio.hpp>
-#include <xfr/fd_share.h>
+#include <util/io/fd_share.h>
#include <xfr/xfrout_client.h>
using namespace std;
+using namespace isc::util::io;
using asio::local::stream_protocol;
namespace isc {
@@ -72,7 +73,7 @@ XfroutClient::sendXfroutRequestInfo(const int tcp_sock,
const void* const msg_data,
const uint16_t msg_len)
{
- if (-1 == send_fd(impl_->socket_.native(), tcp_sock)) {
+ if (send_fd(impl_->socket_.native(), tcp_sock) < 0) {
isc_throw(XfroutError,
"Failed to send the socket file descriptor "
"to xfrout module");
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d4008c0..570c0e2 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1 +1 @@
-SUBDIRS = system
+SUBDIRS = system tools
diff --git a/tests/tools/Makefile.am b/tests/tools/Makefile.am
new file mode 100644
index 0000000..2f07494
--- /dev/null
+++ b/tests/tools/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = badpacket
diff --git a/tests/tools/badpacket/Makefile.am b/tests/tools/badpacket/Makefile.am
new file mode 100644
index 0000000..b249f0e
--- /dev/null
+++ b/tests/tools/badpacket/Makefile.am
@@ -0,0 +1,28 @@
+SUBDIRS = . tests
+
+AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CPPFLAGS += -I$(top_srcdir)/src/lib/log -I$(top_builddir)/src/lib/log
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+
+AM_CXXFLAGS = $(B10_CXXFLAGS)
+
+if USE_STATIC_LINK
+AM_LDFLAGS = -static
+endif
+
+CLEANFILES = *.gcno *.gcda
+
+noinst_PROGRAMS = badpacket
+badpacket_SOURCES = badpacket.cc
+badpacket_SOURCES += command_options.cc command_options.h
+badpacket_SOURCES += header_flags.h
+badpacket_SOURCES += option_info.cc option_info.h
+badpacket_SOURCES += scan.cc scan.h
+badpacket_SOURCES += version.h
+
+badpacket_LDADD = $(top_builddir)/src/lib/asiodns/libasiodns.la
+badpacket_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
+badpacket_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
+badpacket_LDADD += $(top_builddir)/src/lib/log/liblog.la
+badpacket_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
+
diff --git a/tests/tools/badpacket/README b/tests/tools/badpacket/README
new file mode 100644
index 0000000..3f5e801
--- /dev/null
+++ b/tests/tools/badpacket/README
@@ -0,0 +1,53 @@
+"badpacket" is a tool intended to test that a nameserver can cope with
+incorrectly-formatted DNS messages.
+
+This particular incarnation of the tool allows various fields in the DNS
+message to be set to any value (including to values that invalidate the query).
+As well as setting individual values, it is possible to specify ranges; when
+this is done, the tool will send a set of packets so that each combination
+of values is checked.
+
+To illustrate this, consider the following command:
+
+badpacket --address 192.0.2.21 --port 5301 --aa 0-1 --cd 1
+ --rc 0-2 ftp.example.com
+
+(The command has been split across two lines for clarity.)
+
+The address and port flags are self-evident. The other flags specify
+settings for the AA bit (0 and 1), CD bit (always 1) and the RCODE field
+(0, 1, 2). (The remaining fields in the flags word are not specified, so
+will always be zero.) There are six combinations of these values, so six
+packets will sent to the remote server with the following settings:
+
+AA RCODE CD Rest
+0 0 1 0
+0 1 1 0
+0 2 1 0
+1 0 1 0
+1 1 1 0
+1 2 1 0
+
+Each packet will cause a line to be output to stdout, which will have the
+following form:
+
+SUCCESS: (QR:0 OP:0 AA:0 TC:0 RD:0 RA:0 ...
+ (qr:1 op:0 aa:0 tc:0 rd:0 ra:1 ...
+
+(Again the text has been split across two lines for clarity. Also, the full
+list of fields has been truncated.)
+
+Each lines contains a status (SUCCESS indicates that a response was received,
+regardless of the contents of the response), the state of the fields in the
+flags word of the packet sent (in upper-case letters) and the state of the
+fields in the flags word of the response (in lower-case letters).
+
+TODO: At the moment the tool is limited to:
+* Setting values in the flags field.
+* Setting section counts to arbitrary values.
+* Extending or truncating the DNS message size.
+
+Additional options needed are:
+* Add data to sections that should be empty.
+* Deliberately mangle the names placed in the message sections (e.g. by altering
+ the label count fields).
diff --git a/tests/tools/badpacket/badpacket.cc b/tests/tools/badpacket/badpacket.cc
new file mode 100644
index 0000000..86bbc47
--- /dev/null
+++ b/tests/tools/badpacket/badpacket.cc
@@ -0,0 +1,62 @@
+// Copyright (C) 2011 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 <unistd.h>
+#include <iostream>
+
+#include <config.h>
+
+#include <exceptions/exceptions.h>
+#include "command_options.h"
+#include "scan.h"
+
+/// \brief Perform Bad Packet Scan
+///
+/// Scans the server by sending a sequence of (potentially) bad packets and
+/// printing the packet settings and the response received. The principle
+/// raison d'etre for this is to check if a bad packet will cause a crash.
+///
+/// This particular version of the code allows a set of ranges to be set for:
+/// - The flags fields in the message.
+/// - The section count fields, regardless of what is in the section.
+/// - The message size: the message can be truncated or extended.
+///
+/// The program then sends a set of packets corresponding to all combinations
+/// of values in the ranges selected.
+
+// TODO: Extend to cover:
+// - Mangling the QNAME
+// - Adding names to the message sections
+// - Adding EDNS0 RR and magling the fields there
+
+using namespace isc::badpacket;
+
+/// \brief Main Program
+int main(int argc, char* argv[]) {
+
+ try {
+ // Parse command
+ CommandOptions options;
+ options.parse(argc, argv);
+
+ // Send the sequence of messages
+ Scan scanner;
+ scanner.scan(options);
+ } catch (isc::Exception& e) {
+ std::cout << "ERROR: " << e.what() << "\n";
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/tests/tools/badpacket/command_options.cc b/tests/tools/badpacket/command_options.cc
new file mode 100644
index 0000000..eea5ff0
--- /dev/null
+++ b/tests/tools/badpacket/command_options.cc
@@ -0,0 +1,333 @@
+// Copyright (C) 2011 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 <algorithm>
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include <boost/lexical_cast.hpp>
+#include <getopt.h>
+
+#include "exceptions/exceptions.h"
+#include "util/strutil.h"
+
+#include "command_options.h"
+#include "option_info.h"
+#include "version.h"
+
+using namespace std;
+using namespace isc;
+
+namespace isc {
+namespace badpacket {
+
+// Reset stored values to the defaults.
+void
+CommandOptions::reset() {
+ address_ = "127.0.0.1";
+ port_ = 53;
+ timeout_ = 500;
+ qname_ = "www.example.com";
+
+ for (int i = 0; i < OptionInfo::SIZE; ++i) {
+ options_[i].minimum = OptionInfo::defval(i);
+ options_[i].maximum = OptionInfo::defval(i);
+ options_[i].present = false;
+ }
+}
+
+/// Parses the command-line options and records the results.
+void
+CommandOptions::parse(int argc, char* const argv[]) {
+
+ // Set up options for processing. The declaration of the string constants
+ // as mutable arrays and putting the string variable into the "longopts"
+ // structure (as opposed to just putting a string literal there) is
+ // occasioned by a version of solaris which declares the first field as
+ // "char*" (instead of the correct "const char*").
+
+ // General options.
+ char HELP[] = {"help"};
+ char VERSION[] = {"version"};
+ char ADDRESS[] = {"address"};
+ char PORT[] = {"port"};
+ char TIMEOUT[] = {"timeout"};
+
+ // Settings for options in the flags field.
+ char QR[] = {"qr"};
+ char OP[] = {"op"};
+ char AA[] = {"aa"};
+ char TC[] = {"tc"};
+ char RD[] = {"rd"};
+ char RA[] = {"ra"};
+ char Z[] = {"z"};
+ char AD[] = {"ad"};
+ char CD[] = {"cd"};
+ char RC[] = {"rc"};
+
+ // Settings for the count fields
+ char QC[] = {"qc"};
+ char AC[] = {"ac"};
+ char UC[] = {"uc"};
+ char DC[] = {"dc"};
+
+ // Message size
+ char MS[] = {"ms"};
+
+ const struct option longopts[] = {
+ {HELP, 0, NULL, 'h'}, // Print usage message and exit
+ {VERSION, 0, NULL, 'v'}, // Print program version and exit
+ {ADDRESS, 1, NULL, 'a'}, // Specify target server address
+ {PORT, 1, NULL, 'p'}, // Specify target port
+ {TIMEOUT, 1, NULL, 't'}, // Time to wait before timing out (ms)
+ {QR, 1, NULL, 'Q'}, // Query/response flag
+ {OP, 1, NULL, 'O'}, // Opcode
+ {AA, 1, NULL, 'A'}, // Authoritative answer
+ {TC, 1, NULL, 'T'}, // Truncated
+ {RD, 1, NULL, 'D'}, // recursion Desired
+ {RA, 1, NULL, 'R'}, // Recursion available
+ {Z, 1, NULL, 'Z'}, // must be Zero (reserved bit)
+ {AD, 1, NULL, 'U'}, // aUthenticated data
+ {CD, 1, NULL, 'C'}, // Checking disabled
+ {RC, 1, NULL, 'E'}, // rEsult code
+ {QC, 1, NULL, 'Y'}, // querY section count
+ {AC, 1, NULL, 'W'}, // ansWer section count
+ {UC, 1, NULL, 'H'}, // autHority section count
+ {DC, 1, NULL, 'I'}, // addItional section count
+ {MS, 1, NULL, 'M'}, // Message size
+ {NULL, 0, NULL, 0 }
+ };
+ const char* shortopts = "hva:p:t:Q:O:A:T:D:R:Z:U:C:E:Y:W:H:I:M:";
+
+
+ // Set record of options to defaults before parsing
+ reset();
+
+ // Process command line
+ int c; // Option being processed
+ optind = 0; // Reset parsing
+ while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) {
+ switch (c) {
+ case 'h': // --help
+ usage();
+ exit(0);
+
+ case 'v': // --version
+ version();
+ exit(0);
+
+ case 'a': // --address
+ address_ = optarg;
+ break;
+
+ case 'p': // --port
+ port_ = boost::lexical_cast<uint16_t>(string(optarg));
+ break;
+
+ case 't': // --timeout
+ timeout_ = boost::lexical_cast<int>(string(optarg));
+ break;
+
+ case 'Q': // --qr (query/response)
+ case 'O': // --op (operation code)
+ case 'A': // --aa (authoritative answer)
+ case 'T': // --tc (truncated)
+ case 'D': // --rd (recursion desired)
+ case 'R': // --ra (recursion available)
+ case 'Z': // --z (zero: reserved bit)
+ case 'U': // --ad (authenticated data)
+ case 'C': // --cd (checking disabled)
+ case 'E': // --rc (result code)
+ case 'Y': // --qc (query count)
+ case 'W': // --ac (answer count)
+ case 'H': // --uc (authority count)
+ case 'I': // --dc (additional count)
+ case 'M': // --ms (message size)
+ processOptionValue(c, optarg);
+ break;
+
+ default:
+ isc_throw(isc::InvalidParameter,
+ "unknown option given on the command line");
+ }
+ }
+
+ // Pick up a parameter if there is one (and report excess).
+ if (optind < argc) {
+ qname_ = argv[optind++];
+ }
+
+ if (optind < argc) {
+ isc_throw(isc::InvalidParameter,
+ "only a single (optional) parameter may be specified on the command line");
+ }
+}
+
+// Print usage information.
+void
+CommandOptions::usage() {
+ cout << "Usage: badpacket [options] query\n"
+ "\n"
+ "Sends a sequence of DNS messages to the specified nameserver and prints the\n"
+ " results. The packets are valid query packets but certain aspects of the\n"
+ " packets (such as the flags fields, section count fields and message size) can\n"
+ "be set to arbitrary values using the command-line switches.\n"
+ "\n"
+ "In the following list of command-line switches, '<range>' indicates a range of\n"
+ "values specified as either <integer> or <integer1>-<integer2> (e.g. both '42'\n"
+ "and '0-1' would be valid values for range). The program sends a sequence of\n"
+ "messages that contain all combinations of the flag values. For example,\n"
+ "specifying:\n"
+ "\n"
+ "--tc 0-1 --op 1-4 --aa 1 --rd 0-1\n"
+ "\n"
+ "... would send a total of 16 packets which would have all combinations of the\n"
+ "the tc bit set to 0 and 1, the rd bit set to 0 and 1, and the opcode set to all\n"
+ "values between 1 and 4. All other flags fields would be zero except for the aa\n"
+ "bit which would always be 1.\n"
+ "\n"
+ "The long form of the option is given. It can also be specified as a single-\n"
+ "character short-form, which is listed in sqare brackets in the description.\n"
+ "\n"
+ "General options are:\n"
+ "\n"
+ "--help [-h] Prints this message and exits.\n"
+ "--version [-v] Prints the program version number.\n"
+ "--address <address> [-a] Address of nameserver, which defaults to 127.0.0.1\n"
+ "--port <port> [-p] Port to which to send query. Defaults to 53.\n"
+ "--timeout <value> [-t] Timeout value for the query. Specified in ms, it\n"
+ " defaults to 500ms.\n"
+ "\n"
+ "The following options set fields in the outgoing DNS message flags word:\n"
+ "\n"
+ "--qr <range> [-Q] Set query/response bit. Valid <range> is 0-1.\n"
+ "--op <range> [-O] Set opcode. Valid <range> is 0-15.\n"
+ "--aa <range> [-A] Set authoritative answer bit. Valid <range> is 0-1.\n"
+ "--tc <range> [-T] Set truncated bit. Valid <range> is 0-1.\n"
+ "--rd <range> [-D] Set recursion desired bit. Valid <range> is 0-1.\n"
+ "--ra <range> [-D] Set recursion available bit. Valid <range> is 0-1.\n"
+ "--z <range> [-Z] Set zero (reserved) bit. Valid <range> is 0-1.\n"
+ "--ad <range> [-U] Set authenticated data bit. Valid <range> is 0-1.\n"
+ "--cd <range> [-C] Set checking disabled bit. Valid <range> is 0-1.\n"
+ "--rc <range> [-E] Set rcode value. Valid <range> is 0-15\n"
+ "\n"
+ "The following options set the various section counts (independent of what is\n"
+ "actually in the section):\n"
+ "\n"
+ "--qc <range> [-Y] Set the query count. Valid range is 0-65535.\n"
+ "--ac <range> [-W] Set the answer count. Valid range is 0-65535.\n"
+ "--uc <range> [-H] Set the authority count. Valid range is 0-65535.\n"
+ "--dc <range> [-I] Set the additional count. Valid range is 0-65535.\n"
+ "\n"
+ "Other options are:\n"
+ "\n"
+ "--ms <range> [-M] Set the size of the message. If the specified size\n"
+ " smaller than the natural message size, it is truncated.\n"
+ " If longer, the packet is extended with random values.\n"
+ " Valid range is 2 to 65536\n"
+ "\n"
+ "query Name to query for. The query is for an 'IN' A record. If\n"
+ " not given, the name 'www.example.com' is used.\n"
+ "\n"
+ "The output is a single (very long) line containing the settings of the various\n"
+ "fields. The settings for the outgoing packet are reported in uppercase letters\n"
+ "and that of the returned packet in lowercase.\n"
+ ;
+}
+
+// Print version information,
+void
+CommandOptions::version() {
+ cout << BADPACKET_VERSION << "\n";
+}
+
+// Process single flag that can be stored in the options_ member.
+void
+CommandOptions::processOptionValue(int c, const char* value) {
+
+ // Get values for this option.
+ int index = OptionInfo::getIndex(c);
+ const char* name = OptionInfo::name(index);
+ uint32_t minval = OptionInfo::minval(index);
+ uint32_t maxval = OptionInfo::maxval(index);
+
+ // Split the string up into one or two tokens.
+ vector<string> tokens = isc::util::str::tokens(string(value), "-");
+ if ((tokens.size() < 1) || (tokens.size() > 2)) {
+ isc_throw(isc::BadValue, "value given for " << name << " is '" << value <<
+ "': it must be in the form 'int' or 'int1-int2'");
+ }
+
+ // Convert to uint32.
+ try {
+ options_[index].minimum = boost::lexical_cast<uint32_t>(tokens[0]);
+ if (tokens.size() == 2) {
+ options_[index].maximum = boost::lexical_cast<uint32_t>(tokens[1]);
+ } else {
+ options_[index].maximum = options_[index].minimum;
+ }
+ } catch (boost::bad_lexical_cast) {
+ isc_throw(isc::BadValue, "value given for " << name << " is '" << value <<
+ "': it must be in the form 'int' or 'int1-int2'");
+ }
+
+ // Set the limits in the correct order.
+ if (options_[index].minimum > options_[index].maximum) {
+ swap(options_[index].minimum, options_[index].maximum);
+ }
+
+ // Check that tokens lie inside the allowed ranges.
+ if ((tokens.size() == 1) &&
+ ((options_[index].minimum < OptionInfo::minval(index)) || (options_[index].maximum > maxval))) {
+ isc_throw(isc::BadValue, "the value of " << options_[index].minimum <<
+ " given for " << name << " is outside the range of " <<
+ minval << " to " << maxval);
+ } else if (options_[index].minimum < minval) {
+ isc_throw(isc::BadValue, "the lower limit of " << options_[index].minimum <<
+ " given for " << name << " is below the minimum permitted"
+ " value of " << minval);
+ } else if (options_[index].maximum > maxval) {
+ isc_throw(isc::BadValue, "the upper limit of " << options_[index].maximum <<
+ " given for " << name << " is above the maximum permitted"
+ " value of " << maxval);
+ }
+
+ // And finally note that the option was specified on the command line
+ options_[index].present = true;
+}
+
+// Return information about the option - minimum and maximum values and whether
+// it was actually specified. (Note that if it wasn't, the maximum and minimum
+// values will have been set to the default recorded in the OptionInfo class.)
+uint32_t
+CommandOptions::minimum(int index) const {
+ OptionInfo::checkIndex(index);
+ return (options_[index].minimum);
+}
+
+uint32_t
+CommandOptions::maximum(int index) const {
+ OptionInfo::checkIndex(index);
+ return (options_[index].maximum);
+}
+
+bool
+CommandOptions::present(int index) const {
+ OptionInfo::checkIndex(index);
+ return (options_[index].present);
+}
+
+} // namespace badpacket
+} // namespace isc
diff --git a/tests/tools/badpacket/command_options.h b/tests/tools/badpacket/command_options.h
new file mode 100644
index 0000000..fc819e9
--- /dev/null
+++ b/tests/tools/badpacket/command_options.h
@@ -0,0 +1,162 @@
+// Copyright (C) 2011 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 __COMMAND_OPTIONS_H
+#define __COMMAND_OPTIONS_H
+
+#include <cstdlib>
+#include <stdint.h>
+#include <utility>
+
+#include "option_info.h"
+
+namespace isc {
+namespace badpacket {
+
+/// \brief Command Options
+///
+/// This class is responsible for parsing the command-line and storing the
+/// specified options.
+///
+/// Some of the options perform general control (like setting the address of the
+/// nameserver under test, while the rest set values in the DNS message being
+/// sent. Each of the latter options can be specified as either:
+///
+/// - \c --option value
+/// - \c --option value1-value2
+///
+/// Either way, two values are extracted the low value and the high value (in
+/// the former case, both are the same). The values are stored and can be
+/// returned on request.
+///
+/// For simplicity, the class takes care of the --help and --version flags,
+/// each of which will cause a message to be printed to stdout and the program
+/// to terminate.
+
+class CommandOptions {
+public:
+
+ /// \brief Default Constructor
+ ///
+ /// Set values to defaults.
+ CommandOptions() {
+ reset();
+ }
+
+ /// \brief Return minimum value for option
+ ///
+ /// Applicable only to an option affecting a field in the message, this
+ /// method returns the minimum value that was given on the command line.
+ /// (If only a single value was given, it will be that value returned.)
+ /// If the option was not specified on the command line, the default value
+ /// set in the OptionsInfo class will be returned.
+ ///
+ /// \param index Index of the command-line option.
+ ///
+ /// \return uint32_t holding the minimum value given (or the default if
+ /// the option was not specified on the command line).
+ uint32_t minimum(int index) const;
+
+ /// \brief Return maximum value for option
+ ///
+ /// Applicable only to an option affecting a field in the message, this
+ /// method returns the maximum value that was given on the command line.
+ /// (If only a single value was given, it will be that value returned.)
+ /// If the option was not specified on the command line, the default value
+ /// set in the OptionsInfo class will be returned.
+ ///
+ /// \param index Index of the command-line option.
+ ///
+ /// \return uint32_t holding the maximum value given (or the default if
+ /// the option was not specified on the command line).
+ uint32_t maximum(int index) const;
+
+ /// \brief Reports if option was given on command line
+ ///
+ /// \param index Index of the command-line option.
+ ///
+ /// \return true if the option was present, false if not.
+ bool present(int index) const;
+
+
+ /// \brief Return target address
+ std::string getAddress() const {
+ return address_;
+ }
+
+ /// \brief Return target port
+ uint16_t getPort() const {
+ return port_;
+ }
+
+ /// \brief Return timeout
+ int getTimeout() const {
+ return timeout_;
+ }
+
+ /// \brief Return qname
+ std::string getQname() const {
+ return qname_;
+ }
+
+ /// \brief Reset to defaults
+ ///
+ /// Resets the CommandOptions object to default values.
+ void reset();
+
+ /// \brief Parse command line
+ ///
+ /// Parses the command line and stores the selected options. The parsing
+ /// also handles the --help and --version commands: both of these will cause
+ /// some text to be printed to stdout, after which exit() is called to
+ /// terminate the program.
+ ///
+ /// \param argc Argument count passed to main().
+ /// \param argv Argument value array passed to main().
+ void parse(int argc, char* const argv[]);
+
+ /// \brief Print usage information and exit program
+ void usage();
+
+ /// \brief Print version information and exit program
+ void version();
+
+private:
+ /// \brief Process Option Value
+ ///
+ /// Processes a specific command-line option, interpreting the value and
+ /// placing it in the appropriate location. On error a BadValue exception
+ /// is thrown.
+ ///
+ /// \param c Short form option character from the command line
+ /// \param value Value of the option read from the command line
+ void processOptionValue(int c, const char* value);
+
+ // Member variables
+
+ struct {
+ uint32_t minimum; ///< Minimum value specified
+ uint32_t maximum; ///< Maximum value specified
+ bool present; ///< true if specified on command line
+ } options_[OptionInfo::SIZE]; ///< Information about command options
+ std::string address_; ///< Address to where query is sent
+ uint16_t port_; ///< Target port
+ int timeout_; ///< Timeout for query
+ std::string qname_; ///< Query to make
+};
+
+} // namespace badpacket
+} // namespace isc
+
+#endif // __COMMAND_OPTIONS_H
diff --git a/tests/tools/badpacket/header_flags.h b/tests/tools/badpacket/header_flags.h
new file mode 100644
index 0000000..5d74e75
--- /dev/null
+++ b/tests/tools/badpacket/header_flags.h
@@ -0,0 +1,102 @@
+// Copyright (C) 2011 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 __HEADER_FLAGS_H
+#define __HEADER_FLAGS_H
+
+#include <exceptions/exceptions.h>
+#include "option_info.h"
+
+namespace isc {
+namespace badpacket {
+
+/// \brief Header Flags
+///
+/// Simple class providing easy conversion between the header flags in a DNS
+/// message and a 16-bit value.
+
+class HeaderFlags {
+public:
+
+ /// \brief Constructor
+ HeaderFlags() {
+ reset();
+ }
+
+ /// \brief Reset values to zero
+ ///
+ /// Clears all flags.
+ void reset() {
+ setValue(0);
+ }
+
+ /// \brief Get header flags as 16-bit value
+ uint16_t getValue() const {
+ return (flags_);
+ }
+
+ /// \brief Set header flags as 16-bit value
+ ///
+ /// \param value 16-bit value to put into object as representing the
+ /// header flags.
+ void setValue(uint16_t value) {
+ flags_ = value;
+ }
+
+ /// \brief Get field
+ ///
+ /// Return the value of a bit field in the flags word.
+ ///
+ /// \param int Index of the bit field in the OptionInfo data structure
+ ///
+ /// \return Value of the field.
+ uint16_t get(int index) const {
+ OptionInfo::checkIndex(index);
+ return ((flags_ & OptionInfo::mask(index)) >> OptionInfo::offset(index));
+ }
+
+ /// \brief Set field
+ ///
+ /// Sets the value of a bit field.
+ ///
+ /// \param int Index of the bit field in the OptionInfo data structure
+ /// \param value Value to set. If the value is more than the field can
+ /// hold, a BadValue exception is thrown.
+ void set(int index, uint16_t value) {
+
+ // Declare an OptionInfo object for brevity and check the index is
+ // valid.
+ OptionInfo o;
+ o.checkIndex(index);
+
+ // Ensure the value is within limits and throw an exception if not. (This
+ // should not really be needed, as the command line parsing should have
+ // checked the limits. But be safe.)
+ if ((value < o.minval(index)) || (value > o.maxval(index))) {
+ isc_throw(isc::BadValue, "value of index " << index << " is out of range");
+ }
+
+ // Clear the field then set it with the value.
+ flags_ &= ~o.mask(index);
+ flags_ |= (value << o.offset(index));
+ }
+
+private:
+ uint16_t flags_; ///< Variable holding field values
+};
+
+} // namespace badpacket
+} // namespace isc
+
+#endif // __HEADER_FLAGS_H
diff --git a/tests/tools/badpacket/option_info.cc b/tests/tools/badpacket/option_info.cc
new file mode 100644
index 0000000..e1c1f78
--- /dev/null
+++ b/tests/tools/badpacket/option_info.cc
@@ -0,0 +1,114 @@
+// Copyright (C) 2011 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 "option_info.h"
+
+namespace {
+
+// Define the various options for the command switches. This includes both the
+// long form and short form of the switch. Unfortunately this means that the
+// information is duplicated here and where the long options are specified for
+// getopt_long, but this inconvenience is outweighed by the simplified command
+// processing.
+//
+// Fields are:
+// * Short option name
+// * Long option name
+// * Offset of 16-bit word holding datum in DNS message (if applicable)
+// * Bit mask for the data (if applicable)
+// * Offset of the bit field in the word (if applicable)
+// * Default value (this can be ignored if applicable)
+// * Minimum value specified on command line
+// * Maximum value specified on command line
+
+isc::badpacket::OptionInfo::Parameter option_information[] = {
+ {'Q', "qr", 2, 0x8000, 15, 0, 0, 1},
+ {'O', "op", 2, 0x7800, 11, 0, 0, 15},
+ {'A', "aa", 2, 0x0400, 10, 0, 0, 1},
+ {'T', "tc", 2, 0x0200, 9, 0, 0, 1},
+ {'D', "rd", 2, 0x0100, 8, 0, 0, 1},
+ {'R', "ra", 2, 0x0080, 7, 0, 0, 1},
+ {'Z', "z", 2, 0x0040, 6, 0, 0, 1},
+ {'U', "ad", 2, 0x0020, 5, 0, 0, 1},
+ {'C', "cd", 2, 0x0010, 4, 0, 0, 1},
+ {'E', "rc", 2, 0x000F, 0, 0, 0, 15},
+ {'Y', "qc", 4, 0, 0, 1, 0, 0xFFFF},
+ {'W', "ac", 6, 0, 0, 0, 0, 0xFFFF},
+ {'H', "uc", 8, 0, 0, 0, 0, 0xFFFF},
+ {'I', "dc", 10, 0, 0, 0, 0, 0xFFFF},
+ {'M', "ms", 0, 0, 0, 0, 1, 65536}
+};
+
+} // Anonymous namespace
+
+namespace isc {
+namespace badpacket {
+
+// Locate the index of the information in the array from the short switch.
+int
+OptionInfo::getIndex(int c) {
+ for (int i = 0; i < SIZE; ++i) {
+ if (option_information[i].short_form == c) {
+ return (i);
+ }
+ }
+ isc_throw(isc::BadValue, "unknown option: " << c);
+}
+
+// Methods to return values from the array
+
+const char*
+OptionInfo::name(int i) {
+ checkIndex(i);
+ return (option_information[i].long_form);
+}
+
+uint16_t
+OptionInfo::mask(int i) {
+ checkIndex(i);
+ return (option_information[i].mask);
+}
+
+int
+OptionInfo::word(int i) {
+ checkIndex(i);
+ return (option_information[i].word);
+}
+
+int
+OptionInfo::offset(int i) {
+ checkIndex(i);
+ return (option_information[i].offset);
+}
+
+uint32_t
+OptionInfo::minval(int i) {
+ checkIndex(i);
+ return (option_information[i].minval);
+}
+
+uint32_t
+OptionInfo::defval(int i) {
+ checkIndex(i);
+ return (option_information[i].defval);
+}
+
+uint32_t
+OptionInfo::maxval(int i) {
+ checkIndex(i);
+ return (option_information[i].maxval);
+}
+
+} // namespace badpacket
+} // namespace isc
diff --git a/tests/tools/badpacket/option_info.h b/tests/tools/badpacket/option_info.h
new file mode 100644
index 0000000..a340c1d
--- /dev/null
+++ b/tests/tools/badpacket/option_info.h
@@ -0,0 +1,174 @@
+// Copyright (C) 2011 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 __OPTION_INFO_H
+#define __OPTION_INFO_H
+
+#include <stdint.h>
+#include "exceptions/exceptions.h"
+
+namespace isc {
+namespace badpacket {
+
+/// \brief Option Information
+///
+/// Holds details about the options that can be specified on the command line
+/// that require values and which control data put in the DNS message sent to
+/// the remote system.
+///
+/// Some of the fields are no applicable to all options. For example, some of
+/// the options correspond to fields in the flags word of the DNS message
+/// header, so the information includes details about the position of the fields
+/// and an appropriate bit mask.
+///
+/// Note that the class does not hold values specified on the command line - it
+/// only holds information about the available options.
+
+class OptionInfo {
+public:
+
+ /// \brief Array Indexes
+ ///
+ /// The data for the flags options are held in an array. Although declared
+ /// as an enum, only the numeric values are used as they are the indexes
+ /// into the array.
+ enum Index {
+ FLAGS_START = 0, // Start of flags field codes
+ QR = 0, // Query/response
+ OP = 1, // Opcode
+ AA = 2, // Authoritative answer
+ TC = 3, // Truncated
+ RD = 4, // Recursion desired
+ RA = 5, // Recursion available
+ Z = 6, // Zero (reserved)
+ AD = 7, // Authenticated data
+ CD = 8, // Checking disabled
+ RC = 9, // Response code
+ FLAGS_END = 9, // End of flags field codes
+ COUNT_START = 10, // Start of count fields
+ QC = 10, // Query count
+ AC = 11, // Answer count
+ UC = 12, // Authority count
+ DC = 13, // Additional count
+ COUNT_END = 13, // End of count fields
+ OTHER_START = 14, // Start of other fields
+ MS = 14, // Message size
+ OTHER_END = 14, // End of other fields
+ SIZE = 15 // Number of index values
+ };
+
+ /// \brief Option parameters
+ ///
+ /// Defines a structure that holds information associated with each of the
+ /// flags field command options. Not all members of the structure are
+ /// relevant to all options.
+ struct Parameter {
+ const char short_form; // Short form of the command switch
+ const char* long_form; // Long form of the command switch
+ int word; // Byte offset of word in message header
+ uint16_t mask; // Bit mask of field in the flags word
+ int offset; // Offset of field in flags word
+ uint32_t defval; // Default value
+ uint32_t minval; // Minimum valid value for this field
+ uint32_t maxval; // Maximum valid value for this field
+ };
+
+ /// \brief Return index for command option
+ ///
+ /// Given the short form of a command-line option, return the index in the
+ /// options array corresponding to that option.
+ ///
+ /// \param c The character that is the short form of the command line option.
+ /// An 'int' is used as the value passed will be the return value
+ /// from 'getopt()' (or equivalent) which is an int. If the
+ /// character is not found, an exception will be thrown.
+ ///
+ /// \return A valid index value.
+ static int getIndex(int c);
+
+ /// \brief Return long form of command switch for this field
+ ///
+ /// \param index A valid index (one of the values in the 'Index' enum).
+ ///
+ /// \return The long option name (e.q. "qr" for the Query/Response field).
+ static const char* name(int index);
+
+ /// \brief Return header word offset
+ ///
+ /// Returns the byte offset in the DNS message header of the two-byte word
+ /// holding the data in question.
+ ///
+ /// \param index A valid index (one of the values in the 'Index' enum).
+ ///
+ /// \return The offset in the header for this datum.
+ static int word(int index);
+
+ /// \brief Return mask associated with switch field
+ ///
+ /// \param index A valid index (one of the values in the 'Index' enum).
+ ///
+ /// \return The mask for this particular option in the DNS message flags
+ /// word. The returned value is only valid for options that
+ /// correspond to fields in the flags word.
+ static uint16_t mask(int index);
+
+ /// \brief Return offset associated with option field
+ ///
+ /// \param index A valid index (one of the values in the 'Index' enum).
+ ///
+ /// \return The offset of the field corresponding to this option in the DNS
+ /// message flags field. The returned value is only valid for
+ /// options that correpond to fields in the flags word.
+ static int offset(int index);
+
+ /// \brief Return minimum allowed value of an option
+ ///
+ /// \param index A valid index (one of the values in the 'Index' enum).
+ ///
+ /// \return Minimum allowed value for this option.
+ static uint32_t minval(int index);
+
+ /// \brief Return default value of an option
+ ///
+ /// \param index A valid index (one of the values in the 'Index' enum).
+ ///
+ /// \return Default value for this option
+ static uint32_t defval(int index);
+
+ /// \brief Return maximum allowed value of an option
+ ///
+ /// \param index A valid index (one of the values in the 'Index' enum).
+ ///
+ /// \return Maximum allowed value for this option. If the option is a bit
+ /// in the flags field of the DNS message hearder, this will be 1.
+ static uint32_t maxval(int index);
+
+ /// \brief Check Array Index
+ ///
+ /// Checks the passed field index and throws an exception if it does not
+ /// correspond to one of the valid indexes in the 'Index' enum.
+ ///
+ /// \param index An index value.
+ static void checkIndex(int i) {
+ if ((i < 0) || (i >= SIZE)) {
+ isc_throw(isc::OutOfRange, "option index must be in the range "
+ "0 to " << SIZE);
+ }
+ }
+};
+
+} // namespace badpacket
+} // namespace isc
+
+#endif // __OPTION_INFO_H
diff --git a/tests/tools/badpacket/scan.cc b/tests/tools/badpacket/scan.cc
new file mode 100644
index 0000000..c14cbe7
--- /dev/null
+++ b/tests/tools/badpacket/scan.cc
@@ -0,0 +1,310 @@
+// Copyright (C) 2011 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 <iostream>
+#include <iomanip>
+#include <sstream>
+#include <string>
+
+#include <stdlib.h>
+
+#include <asio.hpp>
+
+#include <asiolink/io_address.h>
+#include <asiodns/io_fetch.h>
+#include <util/buffer.h>
+#include <dns/message.h>
+#include <dns/messagerenderer.h>
+#include <dns/opcode.h>
+#include <dns/question.h>
+#include <dns/rcode.h>
+#include <dns/rrclass.h>
+#include <dns/rrtype.h>
+#include <util/strutil.h>
+
+#include "command_options.h"
+#include "header_flags.h"
+#include "scan.h"
+
+using namespace std;
+using namespace isc::asiolink;
+using namespace isc::asiodns;
+using namespace isc::dns;
+using namespace isc::util;
+using namespace isc::util::str;
+
+namespace isc {
+namespace badpacket {
+
+// Perform the scan from start to end on a single question.
+void
+Scan::scan(const CommandOptions& options) {
+
+ // Create the message buffer to use
+ Message message(Message::RENDER);
+ message.setOpcode(Opcode::QUERY());
+ message.setRcode(Rcode::NOERROR());
+ message.addQuestion(Question(Name(options.getQname()), RRClass::IN(),
+ RRType::A()));
+
+ OutputBufferPtr msgbuf(new OutputBuffer(512));
+ MessageRenderer renderer(*msgbuf);
+ message.toWire(renderer);
+
+ iterateFlagsStart(msgbuf, options);
+}
+
+// Iterate through the various settings in the flags fields.
+void
+Scan::iterateFlagsStart(OutputBufferPtr& msgbuf, const CommandOptions& options) {
+ HeaderFlags flags;
+ iterateFlags(msgbuf, options, flags, OptionInfo::FLAGS_START,
+ OptionInfo::FLAGS_END);
+}
+void
+Scan::iterateFlags(OutputBufferPtr& msgbuf, const CommandOptions& options,
+ HeaderFlags& flags, int index, int maxindex)
+{
+ // Is the index valid?
+ if (index <= maxindex) {
+
+ // Index is valid, did the command line specify a range of values for
+ // this field?
+ if (options.present(index)) {
+
+ // It did, so loop between minimum and maximum values given.
+ for (uint32_t i = options.minimum(index);
+ i <= options.maximum(index); ++i) {
+ flags.set(index, i);
+
+ // Recurse to set the next option.
+ iterateFlags(msgbuf, options, flags, (index + 1), maxindex);
+ }
+ } else {
+
+ // Not specified on command line, so set the default value in the
+ // flags and process the next index.
+ flags.set(index, OptionInfo::defval(index));
+ iterateFlags(msgbuf, options, flags, (index + 1), maxindex);
+ }
+ } else {
+
+ // Index is not valid, so we have recursed enough to process all the
+ // flags fields. Set the value in the message header and call the next
+ // stage in the processing.
+ //
+ // (In the next statement, the "word" offset of in the header is the
+ // same for all flags options, so the value for an arbitrary field
+ // (QR) has been used.)
+ msgbuf->writeUint16At(flags.getValue(),
+ OptionInfo::word(OptionInfo::QR));
+ iterateCountStart(msgbuf, options);
+ }
+}
+
+// Iterate through the various count fields
+void
+Scan::iterateCountStart(OutputBufferPtr& msgbuf, const CommandOptions& options)
+{
+ iterateCount(msgbuf, options, OptionInfo::COUNT_START,
+ OptionInfo::COUNT_END);
+}
+
+void
+Scan::iterateCount(OutputBufferPtr& msgbuf, const CommandOptions& options,
+ int index, int maxindex)
+{
+ // If the index is valid, process the iteration over the range for this
+ // flags field.
+ if (index <= maxindex) {
+
+ // Index is valid, did the command line specify a range of values for
+ // this field?
+ if (options.present(index)) {
+
+ // It did, so loop between minimum and maximum values given.
+ for (uint32_t i = options.minimum(index);
+ i <= options.maximum(index); ++i) {
+
+ // Set the value in the message buffer header and recurse to
+ // the next option.
+ msgbuf->writeUint16At(i, OptionInfo::word(index));
+ iterateCount(msgbuf, options, (index + 1), maxindex);
+ }
+ } else {
+
+ // Not specified on command line, so do change anything and process
+ // the next index.
+ iterateCount(msgbuf, options, (index + 1), maxindex);
+ }
+ } else {
+
+ // Index is not valid, so we have recursed enough to process all the
+ // flags fields. Do the next stage of the processing.
+ sizeMessage(msgbuf, options);
+ }
+}
+
+// Alter the message size.
+void
+Scan::sizeMessage(OutputBufferPtr& msgbuf, const CommandOptions& options) {
+
+ if (options.present(OptionInfo::MS)) {
+
+ // Iterate over the range of message sizes
+ for (size_t i = options.minimum(OptionInfo::MS);
+ i <= options.maximum(OptionInfo::MS); ++i) {
+
+ // Copy the data into a new buffer.
+ OutputBufferPtr newbuf(new OutputBuffer(i));
+ newbuf->writeData(msgbuf->getData(), min(msgbuf->getLength(), i));
+
+ // Pad with junk (actually pseudo-random data) if the new buffer is
+ // longer than the old.
+ for (size_t j = newbuf->getLength(); j < i; ++j) {
+ newbuf->writeUint8(static_cast<uint8_t>(rand() & 0xFFU));
+ }
+
+ // ... and process.
+ scanOne(newbuf, options);
+ }
+ } else {
+
+ // No packet size given, just process the message as it.
+ scanOne(msgbuf, options);
+ }
+}
+
+// Perform the message exchange for a single combination command options.
+void
+Scan::scanOne(isc::util::OutputBufferPtr& msgbuf, const CommandOptions& options) {
+ // Store the interpretation of outgoing message.
+ string fields = string("(") + getFields(msgbuf) + string(")");
+
+ // Do the I/O, waiting for a reply
+ OutputBufferPtr replybuf(new OutputBuffer(512));
+ performIO(msgbuf, replybuf, options);
+
+ string status = "";
+ string returned = "";
+ switch (result_) {
+ case IOFetch::SUCCESS:
+ {
+ status = "SUCCESS";
+
+ // Parse the reply and get the fields
+ returned = string("(") + getFields(replybuf) + string(")");
+ lowercase(returned);
+ }
+ break;
+
+ case IOFetch::TIME_OUT:
+ status = "TIMEOUT";
+ break;
+
+ case IOFetch::STOPPED:
+ status = "STOPPED";
+ break;
+
+ default:
+ status = "UNKNOWN";
+ }
+
+ // ... and output the result
+ cout << status << ": " << fields << " " << returned << "\n";
+}
+
+// Get interpretation of the message fields.
+std::string
+Scan::getFields(isc::util::OutputBufferPtr& msgbuf) {
+
+ // Header flags. (Note that all come from the same word in the message, so
+ // using the word offset for the QR flag as the position in the buffer from
+ // which to extract the values is valid.)
+ HeaderFlags flags;
+ InputBuffer inbuf(msgbuf->getData(), msgbuf->getLength());
+ inbuf.setPosition(OptionInfo::word(OptionInfo::QR));
+ flags.setValue(inbuf.readUint16());
+
+ std::ostringstream os;
+ os << std::hex << std::uppercase <<
+ "QR:" << flags.get(OptionInfo::QR) <<
+ " OP:" << flags.get(OptionInfo::OP) <<
+ " AA:" << flags.get(OptionInfo::AA) <<
+ " TC:" << flags.get(OptionInfo::TC) <<
+ " RD:" << flags.get(OptionInfo::RD) <<
+ " RA:" << flags.get(OptionInfo::RA) <<
+ " Z:" << flags.get(OptionInfo::Z) <<
+ " AD:" << flags.get(OptionInfo::AD) <<
+ " CD:" << flags.get(OptionInfo::CD) <<
+ " RC:" << flags.get(OptionInfo::RC);
+
+ // Section count fields.
+ inbuf.setPosition(OptionInfo::word(OptionInfo::QC));
+ os << std::dec << std::uppercase <<
+ " QC:" << inbuf.readUint16();
+
+ inbuf.setPosition(OptionInfo::word(OptionInfo::AC));
+ os << std::dec << std::uppercase <<
+ " AC:" << inbuf.readUint16();
+
+ inbuf.setPosition(OptionInfo::word(OptionInfo::UC));
+ os << std::dec << std::uppercase <<
+ " UC:" << inbuf.readUint16();
+
+ inbuf.setPosition(OptionInfo::word(OptionInfo::DC));
+ os << std::dec << std::uppercase <<
+ " DC:" << inbuf.readUint16();
+
+ // ... and message size.
+ os << std::dec << std::uppercase <<
+ " MS:" << msgbuf->getLength();
+
+ return (os.str());
+}
+
+// Perform the I/O to the nameserver.
+void
+Scan::performIO(OutputBufferPtr& sendbuf, OutputBufferPtr& recvbuf,
+ const CommandOptions& options)
+{
+ // Set up an I/O service for the I/O. This needs to be initialized before
+ // every call as the callback called when the I/O completes stops it.
+ service_.reset(new IOService());
+
+ // The object that will do the I/O
+ IOFetch fetch(IOFetch::UDP, *service_, sendbuf,
+ IOAddress(options.getAddress()), options.getPort(), recvbuf,
+ this, options.getTimeout());
+
+ // Execute the message exchange. The call to run() will return when a
+ // response is received or when the I/O times out.
+ (service_->get_io_service()).post(fetch);
+ service_->run();
+}
+
+// I/O Callback. Called when the message exchange completes or times out.
+void
+Scan::operator()(IOFetch::Result result) {
+
+ // Record the result. This is accessed when deciding what was returned
+ // (if a timeout, nothing was returned).
+ result_ = result;
+
+ // Stop the I/O service. This will cause the call to run() to return.
+ service_->stop();
+}
+
+} // namespace test
+} // namespace isc
diff --git a/tests/tools/badpacket/scan.h b/tests/tools/badpacket/scan.h
new file mode 100644
index 0000000..ca56646
--- /dev/null
+++ b/tests/tools/badpacket/scan.h
@@ -0,0 +1,198 @@
+// Copyright (C) 2011 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 __SCAN_H
+#define __SCAN_H
+
+#include <stdint.h>
+
+#include <boost/scoped_ptr.hpp>
+
+#include <config.h>
+
+#include <asiolink/io_service.h>
+#include <asiodns/io_fetch.h>
+#include <util/buffer.h>
+
+#include "command_options.h"
+#include "header_flags.h"
+
+namespace isc {
+namespace badpacket {
+
+/// \brief Field Scan
+///
+/// This class implements a field scan. Given a CommandOptions object, it will
+/// cycle through combinations of the given options, sending and receiving
+/// messages. For each packet exchange, a summary is written to stdout.
+
+class Scan : public isc::asiodns::IOFetch::Callback {
+public:
+
+ /// \brief Constructor
+ Scan() : service_(), result_()
+ {}
+
+ /// \brief Run Scan
+ ///
+ /// Actually performs the scan for the combination of options.
+ ///
+ /// \param options Command-line options
+ void scan(const CommandOptions& options);
+
+ /// \brief Callback
+ ///
+ /// This class is derived from the IOFetch::Callback class as it acts as the
+ /// callback object. When an asynchronous I/I has completed, this method
+ /// will be called.
+ ///
+ /// \param result Result of the asynchronous I/O. Zero implies success.
+ virtual void operator()(isc::asiodns::IOFetch::Result result);
+
+private:
+ /// \brief Iterate over flags fields options
+ ///
+ /// This method relies on the fact that data concerning the settings for
+ /// the fields in the flags word of the DNS message are held at adjacent
+ /// elements in the various data arrays and so can be accessed by a set
+ /// of contiguous index values.
+ ///
+ /// The method is passed an index value and the maximum valid index value.
+ /// If a set of values for the field at the given index was specified on
+ /// the command line, it loops through those values and sets the appropriate
+ /// value in the a copy of the DNS message header flags. It then calls
+ /// itself with an incremented index. If the value was not given, it just
+ /// sets a default value calls itself (with the incremented index). When
+ /// called with an index above the maximum valid index, the header flags
+ /// in the message buffer are set and the next stage of processing called.
+ ///
+ /// In this way, all fields can be cycled through without the need for a
+ /// single function to nest loops very deeply.
+ ///
+ /// \param msgbuf Message that will be sent to the remote nameserver. The
+ /// QID given will be ignored - the value used will be determined by
+ /// the sending code
+ /// \param options Command-line options (the important ones being address,
+ /// port and timeout).
+ /// \param flags Header flags
+ /// \param index Index of the current field to be processed.
+ /// \param maxindex Maximum valid index value
+ void iterateFlags(isc::util::OutputBufferPtr& msgbuf,
+ const CommandOptions& options, HeaderFlags& flags,
+ int index, int maxindex);
+
+ /// \brief Start iterating over flags field options
+ ///
+ /// Kicks off the call to \c iterateFlags by calling it with the initial
+ /// index value.
+ ///
+ /// \param msgbuf Message that will be sent to the remote nameserver. The
+ /// QID given will be ignored - the value used will be determined by
+ /// the sending code
+ /// \param options Command-line options (the important ones being address,
+ /// port and timeout).
+ void iterateFlagsStart(isc::util::OutputBufferPtr& msgbuf,
+ const CommandOptions& options);
+
+ /// \brief Iterate over count fields
+ ///
+ /// In a manner similar to iterateFlags, this iterates over all specified
+ /// values for each count field, recursively calling itself to process the
+ /// next field. When all fields have been processed, it chains to the
+ /// next stage of packet processing.
+ ///
+ /// \param msgbuf Message that will be sent to the remote nameserver. The
+ /// QID given will be ignored - the value used will be determined by
+ /// the sending code
+ /// \param options Command-line options (the important ones being address,
+ /// port and timeout).
+ /// \param index Index of the current field to be processed.
+ /// \param maxindex Maximum valid index value
+ void iterateCount(isc::util::OutputBufferPtr& msgbuf,
+ const CommandOptions& options, int index, int maxindex);
+
+ /// \brief Start iterating over count fields
+ ///
+ /// Kicks off the call to \c iterateCount by calling it with the initial
+ /// index value.
+ ///
+ /// \param msgbuf Message that will be sent to the remote nameserver. The
+ /// QID given will be ignored - the value used will be determined by
+ /// the sending code
+ /// \param options Command-line options (the important ones being address,
+ /// port and timeout).
+ void iterateCountStart(isc::util::OutputBufferPtr& msgbuf,
+ const CommandOptions& options);
+
+ /// \brief Iterate over message sizes
+ ///
+ /// If the message size option is given on the command line, the message
+ /// sent to the remote system is either truncated or extended (with zeroes)
+ /// before being set.
+ ///
+ /// \param msgbuf Message that will be sent to the remote nameserver. The
+ /// QID given will be ignored - the value used will be determined by
+ /// the sending code
+ /// \param options Command-line options (the important ones being address,
+ /// port and timeout).
+ void sizeMessage(isc::util::OutputBufferPtr& msgbuf,
+ const CommandOptions& options);
+
+ /// \brief Scan One Value
+ ///
+ /// Performs one exchange of messages with the remote nameserver, sending
+ /// the specified message.
+ ///
+ /// \param msgbuf Message that will be sent to the remote nameserver. The
+ /// QID given will be ignored - the value used will be determined by
+ /// the sending code
+ /// \param options Command-line options (the important ones being address,
+ /// port and timeout).
+ void scanOne(isc::util::OutputBufferPtr& msgbuf,
+ const CommandOptions& options);
+
+ /// \brief Perform I/O
+ ///
+ /// Performs a single query to the nameserver and reads the response. It
+ /// outputs a summary of the result.
+ ///
+ /// \param sendbuf Buffer sent to the nameserver
+ /// \param recvbuf Buffer to hold reply from the nameserver
+ /// \param options Command-line options
+ void performIO(isc::util::OutputBufferPtr& sendbuf,
+ isc::util::OutputBufferPtr& recvbuf,
+ const CommandOptions& options);
+
+ /// \brief Get Fields
+ ///
+ /// Interprets the fields in a DNS message and converts them to a brief
+ /// textual format.
+ ///
+ /// \param msg Message for which the header is value
+ ///
+ /// \return A string that holds a textual interpretation of all the fields
+ /// in the header.
+ std::string getFields(isc::util::OutputBufferPtr& msgbuf);
+
+ // Member variables
+
+ boost::scoped_ptr<isc::asiolink::IOService> service_;
+ ///< Service to run the scan
+ isc::asiodns::IOFetch::Result result_; ///< Result of the I/O
+};
+
+} // namespace test
+} // namespace isc
+
+#endif // __SCAN_H
diff --git a/tests/tools/badpacket/tests/Makefile.am b/tests/tools/badpacket/tests/Makefile.am
new file mode 100644
index 0000000..7cde4aa
--- /dev/null
+++ b/tests/tools/badpacket/tests/Makefile.am
@@ -0,0 +1,31 @@
+SUBDIRS = .
+
+AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CXXFLAGS = $(B10_CXXFLAGS)
+
+if USE_STATIC_LINK
+AM_LDFLAGS = -static
+endif
+
+CLEANFILES = *.gcno *.gcda
+
+TESTS =
+if HAVE_GTEST
+TESTS += run_unittests
+run_unittests_SOURCES = run_unittests.cc
+run_unittests_SOURCES += command_options_unittest.cc
+run_unittests_SOURCES += option_info_unittest.cc
+run_unittests_SOURCES += header_flags_unittest.cc
+run_unittests_SOURCES += $(top_builddir)/tests/tools/badpacket/command_options.cc
+run_unittests_SOURCES += $(top_builddir)/tests/tools/badpacket/option_info.cc
+
+run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
+run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
+run_unittests_LDFLAGS += $(top_builddir)/src/lib/log/liblog.la
+run_unittests_LDFLAGS += $(top_builddir)/src/lib/exceptions/libexceptions.la
+
+run_unittests_LDADD = $(GTEST_LDADD)
+endif
+
+noinst_PROGRAMS = $(TESTS)
diff --git a/tests/tools/badpacket/tests/command_options_unittest.cc b/tests/tools/badpacket/tests/command_options_unittest.cc
new file mode 100644
index 0000000..014618e
--- /dev/null
+++ b/tests/tools/badpacket/tests/command_options_unittest.cc
@@ -0,0 +1,300 @@
+// Copyright (C) 2011 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 <cstddef>
+#include <string>
+#include <gtest/gtest.h>
+
+#include "../command_options.h"
+
+#include "exceptions/exceptions.h"
+
+using namespace std;
+using namespace isc;
+using namespace isc::badpacket;
+
+
+/// \brief Test Fixture Class
+
+class CommandOptionsTest : public virtual ::testing::Test,
+ public virtual CommandOptions
+{
+public:
+
+ /// \brief Default Constructor
+ CommandOptionsTest()
+ {}
+
+ /// \brief Check Non-Limit Options
+ ///
+ /// Checks that the options that are NOT related to the message are set to
+ /// their default values.
+ void checkDefaultOtherValues() {
+ EXPECT_EQ("127.0.0.1", getAddress());
+ EXPECT_EQ(53, getPort());
+ EXPECT_EQ(500, getTimeout());
+ EXPECT_EQ("www.example.com", getQname());
+ }
+
+ /// \brief Checks the minimum and maximum value specified for an option
+ ///
+ /// Checks the values for one of the options whose values are stored in the
+ /// class's options_ array.
+ ///
+ /// \param index Index of the option in the limits_ array
+ /// \param minval Expected minimum value
+ /// \param maxval Expected maximum value
+ void checkValuePair(int index, uint32_t minval = 0, uint32_t maxval = 0) {
+ EXPECT_EQ(minimum(index), minval);
+ EXPECT_EQ(maximum(index), maxval);
+ }
+
+ /// \brief Checks that all options are at default values
+ ///
+ /// Checks that all options have both their maximum and minimum set to the
+ /// default values.
+ ///
+ /// \param except Index not to check. (This allows options not being tested
+ /// to be checked to see that they are at the default value.) As all
+ /// index values are positive, a negative value means check
+ /// everything.
+ void checkDefaultLimitsValues(int except = -1) {
+ for (int i = 0; i < OptionInfo::SIZE; ++i) {
+ if (i != except) {
+ checkValuePair(i, OptionInfo::defval(i),
+ OptionInfo::defval(i));
+ }
+ }
+ }
+
+ /// \brief Check valid command option
+ ///
+ /// Checks that the command line specification of one of the options taking
+ /// a value correctly processes the option.
+ ///
+ /// \param index Option index
+ /// \param optflag Option flag (in the form '--option')
+ /// \param optval Value to be passed to the option.
+ /// \param minval Expected minimum value
+ /// \param maxval Expected maximum value
+ void checkCommandValid(int index, const char* optflag, const char* optval,
+ uint32_t minval, uint32_t maxval) {
+
+ // Set up the command line and parse it.
+ const char* argv[] = {"badpacket", NULL, NULL};
+ argv[1] = optflag;
+ argv[2] = optval;
+ int argc = 3;
+ parse(argc, const_cast<char**>(argv));
+
+ // Check the results. Everything should be at the defaults except for
+ // the specified option, where the minimum and maximum should be as
+ // specified.
+ checkDefaultOtherValues();
+ checkDefaultLimitsValues(index);
+ checkValuePair(index, minval, maxval);
+ }
+
+ /// \brief Check invalid command option
+ ///
+ /// Passed a command with an invalid value, checks that the parsing throws
+ /// a BadValue exception.
+ ///
+ /// \param optflag Option flag (in the form '--option')
+ /// \param optval Value to be passed to the option.
+ void checkCommandInvalid(const char* optflag, const char* optval) {
+
+ // Set up the command line and parse it.
+ const char* argv[] = {"badpacket", NULL, NULL};
+ argv[1] = optflag;
+ argv[2] = optval;
+ int argc = 3;
+ EXPECT_THROW(parse(argc, const_cast<char**>(argv)), isc::BadValue);
+ }
+
+ /// \brief Check one-bit field
+ ///
+ /// Explicitly for those fields in the flags word that are one bit wide,
+ /// perform a series of tests to check that they accept valid values and
+ /// reject invalid ones.
+ ///
+ /// \param index Option index
+ /// \param optflag Option flag (in the form '--option')
+ void checkOneBitField(int index, const char* optflag) {
+ checkCommandValid(index, optflag, "0", 0, 0);
+ checkCommandValid(index, optflag, "1", 1, 1);
+ checkCommandValid(index, optflag, "0-1", 0, 1);
+ checkCommandValid(index, optflag, "1-0", 0, 1);
+ checkCommandInvalid(optflag, "0-3");
+ checkCommandInvalid(optflag, "4");
+ checkCommandInvalid(optflag, "xyz");
+ }
+
+ /// \brief Check four-bit field
+ ///
+ /// Explicitly for those fields in the flags word that are four bits wide,
+ /// perform a series of tests to check that they accept valid values and
+ /// reject invalid ones.
+ ///
+ /// \param index Option index
+ /// \param optflag Option flag (in the form '--option')
+ void checkFourBitField(int index, const char* optflag) {
+ checkCommandValid(index, optflag, "0", 0, 0);
+ checkCommandValid(index, optflag, "15", 15, 15);
+ checkCommandValid(index, optflag, "0-15", 0, 15);
+ checkCommandValid(index, optflag, "15-0", 0, 15);
+ checkCommandInvalid(optflag, "0-17");
+ checkCommandInvalid(optflag, "24");
+ checkCommandInvalid(optflag, "xyz");
+ }
+
+ /// \brief Check sixteen-bit field
+ ///
+ /// Explicitly test the parsing of the fields that can take a 16-bit
+ /// value ranging from 0 to 65535.
+ ///
+ /// \param index Option index
+ /// \param optflag Option flag (in the form '--option')
+ void checkSixteenBitField(int index, const char* optflag) {
+ checkCommandValid(index, optflag, "0", 0, 0);
+ checkCommandValid(index, optflag, "65535", 65535, 65535);
+ checkCommandValid(index, optflag, "0-65535", 0, 65535);
+ checkCommandValid(index, optflag, "65535-0", 0, 65535);
+ checkCommandInvalid(optflag, "0-65536");
+ checkCommandInvalid(optflag, "65537");
+ checkCommandInvalid(optflag, "xyz");
+ }
+};
+
+// Check that each of the non-message options will be recognised
+
+TEST_F(CommandOptionsTest, address) {
+ const char* argv[] = {"badpacket", "--address", "192.0.2.1"};
+ int argc = sizeof(argv) / sizeof(const char*);
+
+ // The conversion is ugly but it simplifies the process of entering the
+ // string constant. The cast throws away the "const"ness of the pointed-to
+ // strings in order to conform to the function signature; however, the
+ // called functions all treat the strings as const.
+ parse(argc, const_cast<char**>(argv));
+ EXPECT_EQ("192.0.2.1", getAddress());
+ EXPECT_EQ(53, getPort());
+ EXPECT_EQ(500, getTimeout());
+ EXPECT_EQ("www.example.com", getQname());
+ checkDefaultLimitsValues();
+}
+
+TEST_F(CommandOptionsTest, port) {
+ const char* argv[] = {"badpacket", "--port", "153"};
+ int argc = sizeof(argv) / sizeof(const char*);
+
+ parse(argc, const_cast<char**>(argv));
+ EXPECT_EQ("127.0.0.1", getAddress());
+ EXPECT_EQ(153, getPort());
+ EXPECT_EQ(500, getTimeout());
+ EXPECT_EQ("www.example.com", getQname());
+ checkDefaultLimitsValues();
+}
+
+TEST_F(CommandOptionsTest, timeout) {
+ const char* argv[] = {"badpacket", "--timeout", "250"};
+ int argc = sizeof(argv) / sizeof(const char*);
+
+ parse(argc, const_cast<char**>(argv));
+ EXPECT_EQ("127.0.0.1", getAddress());
+ EXPECT_EQ(53, getPort());
+ EXPECT_EQ(250, getTimeout());
+ EXPECT_EQ("www.example.com", getQname());
+ checkDefaultLimitsValues();
+}
+
+TEST_F(CommandOptionsTest, parameter) {
+ const char* argv[] = {"badpacket", "ftp.example.net"};
+ int argc = sizeof(argv) / sizeof(const char*);
+
+ parse(argc, const_cast<char**>(argv));
+ EXPECT_EQ("127.0.0.1", getAddress());
+ EXPECT_EQ(53, getPort());
+ EXPECT_EQ(500, getTimeout());
+ EXPECT_EQ("ftp.example.net", getQname());
+ checkDefaultLimitsValues();
+}
+
+// Test options representing the flags fields.
+
+TEST_F(CommandOptionsTest, qr) {
+ checkOneBitField(OptionInfo::QR, "--qr");
+}
+
+TEST_F(CommandOptionsTest, op) {
+ checkFourBitField(OptionInfo::OP, "--op");
+}
+
+TEST_F(CommandOptionsTest, aa) {
+ checkOneBitField(OptionInfo::AA, "--aa");
+}
+
+TEST_F(CommandOptionsTest, tc) {
+ checkOneBitField(OptionInfo::TC, "--tc");
+}
+
+TEST_F(CommandOptionsTest, z) {
+ checkOneBitField(OptionInfo::Z, "--z");
+}
+
+TEST_F(CommandOptionsTest, ad) {
+ checkOneBitField(OptionInfo::AD, "--ad");
+}
+
+TEST_F(CommandOptionsTest, cd) {
+ checkOneBitField(OptionInfo::CD, "--cd");
+}
+
+TEST_F(CommandOptionsTest, rc) {
+ checkFourBitField(OptionInfo::RC, "--rc");
+}
+
+// Section count options
+
+TEST_F(CommandOptionsTest, qc) {
+ checkSixteenBitField(OptionInfo::QC, "--qc");
+}
+
+TEST_F(CommandOptionsTest, ac) {
+ checkSixteenBitField(OptionInfo::AC, "--ac");
+}
+
+TEST_F(CommandOptionsTest, uc) {
+ checkSixteenBitField(OptionInfo::UC, "--uc");
+}
+
+TEST_F(CommandOptionsTest, dc) {
+ checkSixteenBitField(OptionInfo::DC, "--dc");
+}
+
+// ... and the message size option
+
+TEST_F(CommandOptionsTest, ms) {
+ int index = OptionInfo::MS;
+ const char* optflag = "--ms";
+
+ checkCommandValid(index, optflag, "1", 1, 1);
+ checkCommandValid(index, optflag, "65536", 65536, 65536);
+ checkCommandValid(index, optflag, "1-65536", 1, 65536);
+ checkCommandValid(index, optflag, "65536-1", 1, 65536);
+ checkCommandInvalid(optflag, "0");
+ checkCommandInvalid(optflag, "1-65537");
+ checkCommandInvalid(optflag, "65538");
+ checkCommandInvalid(optflag, "xyz");
+}
diff --git a/tests/tools/badpacket/tests/header_flags_unittest.cc b/tests/tools/badpacket/tests/header_flags_unittest.cc
new file mode 100644
index 0000000..5a7a722
--- /dev/null
+++ b/tests/tools/badpacket/tests/header_flags_unittest.cc
@@ -0,0 +1,141 @@
+// Copyright (C) 2011 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 <cstddef>
+#include <stdint.h>
+#include <gtest/gtest.h>
+
+#include "../option_info.h"
+#include "../header_flags.h"
+
+using namespace isc::badpacket;
+
+// Test fixture class
+
+class HeaderFlagsTest : public ::testing::Test {
+public:
+ HeaderFlagsTest() {}
+
+
+ /// \brief Checks that all options are zero
+ ///
+ /// Checks that all flags options are set to zero.
+ ///
+ /// \param flags Flags structure to check.
+ /// \param except Index not to check. (This allows options not being tested
+ /// to be checked to see that they are at the default value.) As all
+ /// index values are positive, a negative value means check
+ /// everything.
+ void checkZero(const HeaderFlags& flags, int except = -1) {
+
+ // Check individual fields
+ for (int i = OptionInfo::FLAGS_START; i < OptionInfo::FLAGS_END; ++i) {
+ if (i != except) {
+ EXPECT_EQ(0, flags.get(i));
+ }
+ }
+
+ // ... and check the composite
+ if (except == -1) {
+ EXPECT_EQ(0, flags.getValue());
+ } else {
+ EXPECT_NE(0, flags.getValue());
+ }
+ }
+
+ /// \brief Check Option
+ ///
+ /// Checks that an option will only set the appropriate bits in the flags
+ /// field.
+ ///
+ /// \param index Index of the flags field to check.
+ /// \param maxval Maximum value of the header field.
+ void checkOption(int index, uint32_t maxval) {
+
+ // Create header flags and check initialized properly.
+ HeaderFlags flags;
+ checkZero(flags);
+
+ // Check we can set field to maximum.
+ flags.set(index, maxval);
+ EXPECT_EQ(maxval, flags.get(index));
+ checkZero(flags, index);
+
+ // Check we can reset it to zero.
+ flags.set(index, 0);
+ checkZero(flags);
+ }
+};
+
+// Set of tests to check that setting a bit only sets that bit and nothing
+// else.
+
+TEST_F(HeaderFlagsTest, fields) {
+ checkOption(OptionInfo::QR, 1);
+ checkOption(OptionInfo::OP, 15);
+ checkOption(OptionInfo::AA, 1);
+ checkOption(OptionInfo::TC, 1);
+ checkOption(OptionInfo::RD, 1);
+ checkOption(OptionInfo::RA, 1);
+ checkOption(OptionInfo::Z, 1);
+ checkOption(OptionInfo::AD, 1);
+ checkOption(OptionInfo::CD, 1);
+ checkOption(OptionInfo::RC, 15);
+}
+
+// Check that the correct bits are set
+
+TEST_F(HeaderFlagsTest, bitValues) {
+ HeaderFlags flags;
+ checkZero(flags);
+
+ flags.set(OptionInfo::QR, 1);
+ EXPECT_EQ(0x8000, flags.getValue());
+
+ flags.set(OptionInfo::QR, 0);
+ flags.set(OptionInfo::OP, 15);
+ EXPECT_EQ(0x7800, flags.getValue());
+
+ flags.set(OptionInfo::OP, 0);
+ flags.set(OptionInfo::AA, 1);
+ EXPECT_EQ(0x0400, flags.getValue());
+
+ flags.set(OptionInfo::AA, 0);
+ flags.set(OptionInfo::TC, 1);
+ EXPECT_EQ(0x0200, flags.getValue());
+
+ flags.set(OptionInfo::TC, 0);
+ flags.set(OptionInfo::RD, 1);
+ EXPECT_EQ(0x0100, flags.getValue());
+
+ flags.set(OptionInfo::RD, 0);
+ flags.set(OptionInfo::RA, 1);
+ EXPECT_EQ(0x0080, flags.getValue());
+
+ flags.set(OptionInfo::RA, 0);
+ flags.set(OptionInfo::Z, 1);
+ EXPECT_EQ(0x0040, flags.getValue());
+
+ flags.set(OptionInfo::Z, 0);
+ flags.set(OptionInfo::AD, 1);
+ EXPECT_EQ(0x0020, flags.getValue());
+
+ flags.set(OptionInfo::AD, 0);
+ flags.set(OptionInfo::CD, 1);
+ EXPECT_EQ(0x0010, flags.getValue());
+
+ flags.set(OptionInfo::CD, 0);
+ flags.set(OptionInfo::RC, 15);
+ EXPECT_EQ(0x000F, flags.getValue());
+}
diff --git a/tests/tools/badpacket/tests/option_info_unittest.cc b/tests/tools/badpacket/tests/option_info_unittest.cc
new file mode 100644
index 0000000..8c061de
--- /dev/null
+++ b/tests/tools/badpacket/tests/option_info_unittest.cc
@@ -0,0 +1,161 @@
+// Copyright (C) 2011 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 <cstddef>
+#include <stdint.h>
+#include <gtest/gtest.h>
+
+#include "../option_info.h"
+
+using namespace isc::badpacket;
+
+
+// Test fixture class
+
+class OptionInfoTest : public ::testing::Test {
+public:
+ OptionInfoTest() {}
+};
+
+
+// Check the values are as expected
+
+TEST_F(OptionInfoTest, FlagValues) {
+ EXPECT_STREQ("qr", OptionInfo::name(OptionInfo::QR));
+ EXPECT_STREQ("qr", OptionInfo::name(OptionInfo::getIndex('Q')));
+ EXPECT_EQ(2, OptionInfo::word(OptionInfo::QR));
+ EXPECT_EQ(0x8000, OptionInfo::mask(OptionInfo::QR));
+ EXPECT_EQ(15, OptionInfo::offset(OptionInfo::QR));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::QR));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::QR));
+ EXPECT_EQ(1, OptionInfo::maxval(OptionInfo::QR));
+
+ EXPECT_STREQ("op", OptionInfo::name(OptionInfo::OP));
+ EXPECT_STREQ("op", OptionInfo::name(OptionInfo::getIndex('O')));
+ EXPECT_EQ(2, OptionInfo::word(OptionInfo::OP));
+ EXPECT_EQ(0x7800, OptionInfo::mask(OptionInfo::OP));
+ EXPECT_EQ(11, OptionInfo::offset(OptionInfo::OP));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::OP));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::OP));
+ EXPECT_EQ(15, OptionInfo::maxval(OptionInfo::OP));
+
+ EXPECT_STREQ("aa", OptionInfo::name(OptionInfo::AA));
+ EXPECT_STREQ("aa", OptionInfo::name(OptionInfo::getIndex('A')));
+ EXPECT_EQ(2, OptionInfo::word(OptionInfo::AA));
+ EXPECT_EQ(0x0400, OptionInfo::mask(OptionInfo::AA));
+ EXPECT_EQ(10, OptionInfo::offset(OptionInfo::AA));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::AA));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::AA));
+ EXPECT_EQ(1, OptionInfo::maxval(OptionInfo::AA));
+
+ EXPECT_STREQ("tc", OptionInfo::name(OptionInfo::TC));
+ EXPECT_STREQ("tc", OptionInfo::name(OptionInfo::getIndex('T')));
+ EXPECT_EQ(2, OptionInfo::word(OptionInfo::TC));
+ EXPECT_EQ(0x0200, OptionInfo::mask(OptionInfo::TC));
+ EXPECT_EQ(9, OptionInfo::offset(OptionInfo::TC));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::TC));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::TC));
+ EXPECT_EQ(1, OptionInfo::maxval(OptionInfo::TC));
+
+ EXPECT_STREQ("rd", OptionInfo::name(OptionInfo::RD));
+ EXPECT_STREQ("rd", OptionInfo::name(OptionInfo::getIndex('D')));
+ EXPECT_EQ(2, OptionInfo::word(OptionInfo::RD));
+ EXPECT_EQ(0x0100, OptionInfo::mask(OptionInfo::RD));
+ EXPECT_EQ(8, OptionInfo::offset(OptionInfo::RD));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::RD));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::RD));
+ EXPECT_EQ(1, OptionInfo::maxval(OptionInfo::RD));
+
+ EXPECT_STREQ("ra", OptionInfo::name(OptionInfo::RA));
+ EXPECT_STREQ("ra", OptionInfo::name(OptionInfo::getIndex('R')));
+ EXPECT_EQ(2, OptionInfo::word(OptionInfo::RA));
+ EXPECT_EQ(0x0080, OptionInfo::mask(OptionInfo::RA));
+ EXPECT_EQ(7, OptionInfo::offset(OptionInfo::RA));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::RA));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::RA));
+ EXPECT_EQ(1, OptionInfo::maxval(OptionInfo::RA));
+
+ EXPECT_STREQ("z", OptionInfo::name(OptionInfo::Z));
+ EXPECT_STREQ("z", OptionInfo::name(OptionInfo::getIndex('Z')));
+ EXPECT_EQ(2, OptionInfo::word(OptionInfo::Z));
+ EXPECT_EQ(0x0040, OptionInfo::mask(OptionInfo::Z));
+ EXPECT_EQ(6, OptionInfo::offset(OptionInfo::Z));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::Z));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::Z));
+ EXPECT_EQ(1, OptionInfo::maxval(OptionInfo::Z));
+
+ EXPECT_STREQ("ad", OptionInfo::name(OptionInfo::AD));
+ EXPECT_STREQ("ad", OptionInfo::name(OptionInfo::getIndex('U')));
+ EXPECT_EQ(2, OptionInfo::word(OptionInfo::AD));
+ EXPECT_EQ(0x0020, OptionInfo::mask(OptionInfo::AD));
+ EXPECT_EQ(5, OptionInfo::offset(OptionInfo::AD));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::AD));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::AD));
+ EXPECT_EQ(1, OptionInfo::maxval(OptionInfo::AD));
+
+ EXPECT_STREQ("cd", OptionInfo::name(OptionInfo::CD));
+ EXPECT_STREQ("cd", OptionInfo::name(OptionInfo::getIndex('C')));
+ EXPECT_EQ(2, OptionInfo::word(OptionInfo::CD));
+ EXPECT_EQ(0x0010, OptionInfo::mask(OptionInfo::CD));
+ EXPECT_EQ(4, OptionInfo::offset(OptionInfo::CD));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::CD));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::CD));
+ EXPECT_EQ(1, OptionInfo::maxval(OptionInfo::CD));
+
+ EXPECT_STREQ("rc", OptionInfo::name(OptionInfo::RC));
+ EXPECT_STREQ("rc", OptionInfo::name(OptionInfo::getIndex('E')));
+ EXPECT_EQ(2, OptionInfo::word(OptionInfo::RC));
+ EXPECT_EQ(0x000F, OptionInfo::mask(OptionInfo::RC));
+ EXPECT_EQ(0, OptionInfo::offset(OptionInfo::RC));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::RC));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::RC));
+ EXPECT_EQ(15, OptionInfo::maxval(OptionInfo::RC));
+}
+
+TEST_F(OptionInfoTest, CountValues) {
+ EXPECT_STREQ("qc", OptionInfo::name(OptionInfo::QC));
+ EXPECT_STREQ("qc", OptionInfo::name(OptionInfo::getIndex('Y')));
+ EXPECT_EQ(4, OptionInfo::word(OptionInfo::QC));
+ EXPECT_EQ(1, OptionInfo::defval(OptionInfo::QC));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::QC));
+ EXPECT_EQ(0xFFFF, OptionInfo::maxval(OptionInfo::QC));
+
+ EXPECT_STREQ("ac", OptionInfo::name(OptionInfo::AC));
+ EXPECT_STREQ("ac", OptionInfo::name(OptionInfo::getIndex('W')));
+ EXPECT_EQ(6, OptionInfo::word(OptionInfo::AC));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::AC));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::AC));
+ EXPECT_EQ(0xFFFF, OptionInfo::maxval(OptionInfo::AC));
+
+ EXPECT_STREQ("uc", OptionInfo::name(OptionInfo::UC));
+ EXPECT_STREQ("uc", OptionInfo::name(OptionInfo::getIndex('H')));
+ EXPECT_EQ(8, OptionInfo::word(OptionInfo::UC));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::UC));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::UC));
+ EXPECT_EQ(0xFFFF, OptionInfo::maxval(OptionInfo::UC));
+
+ EXPECT_STREQ("dc", OptionInfo::name(OptionInfo::DC));
+ EXPECT_STREQ("dc", OptionInfo::name(OptionInfo::getIndex('I')));
+ EXPECT_EQ(10, OptionInfo::word(OptionInfo::DC));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::DC));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::DC));
+ EXPECT_EQ(0xFFFF, OptionInfo::maxval(OptionInfo::DC));
+}
+
+TEST_F(OptionInfoTest, OtherValues) {
+ EXPECT_STREQ("ms", OptionInfo::name(OptionInfo::MS));
+ EXPECT_STREQ("ms", OptionInfo::name(OptionInfo::getIndex('M')));
+ EXPECT_EQ(1, OptionInfo::minval(OptionInfo::MS));
+ EXPECT_EQ(65536, OptionInfo::maxval(OptionInfo::MS));
+}
diff --git a/tests/tools/badpacket/tests/run_unittests.cc b/tests/tools/badpacket/tests/run_unittests.cc
new file mode 100644
index 0000000..624cf6f
--- /dev/null
+++ b/tests/tools/badpacket/tests/run_unittests.cc
@@ -0,0 +1,24 @@
+// Copyright (C) 2009 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 <gtest/gtest.h>
+
+int
+main(int argc, char* argv[]) {
+ ::testing::InitGoogleTest(&argc, argv);
+
+ return (RUN_ALL_TESTS());
+}
diff --git a/tests/tools/badpacket/version.h b/tests/tools/badpacket/version.h
new file mode 100644
index 0000000..dc59b11
--- /dev/null
+++ b/tests/tools/badpacket/version.h
@@ -0,0 +1,26 @@
+// Copyright (C) 2011 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 __VERSION_H
+#define __VERSION_H
+
+namespace isc {
+namespace badpacket {
+
+static const char* BADPACKET_VERSION = "1.0-1";
+
+} // namespace badpacket
+} // namespace isc
+
+#endif // __VERSION_H
diff --git a/tools/query_cmp/README b/tools/query_cmp/README
new file mode 100644
index 0000000..bd3efcc
--- /dev/null
+++ b/tools/query_cmp/README
@@ -0,0 +1,27 @@
+This is a tool to compare two DNS server's response to query.
+
+DIRECTORY STRUCTURE
+
+zonefile
+ The file under this directory is for the testee servers
+ to load before running the test, containing various types
+ of RRs in the test cases. It is in bind9's format. One
+ file is signed while the other is not, which you can choose.
+
+queries
+ The files under this directory are the input of the test,
+ involving various types of query cases.
+
+src
+ The scripts of this test.
+ It uses the dns python binding interface of bind10 from the
+ source tree, so src/lib/dns/python/.libs must be added to
+ PYTHONPATH environment variable ahead of running the tests.
+
+RUNNING
+
+e.g.
+cd src
+./query_two_server.py -u -f ../queries/dquery01 -s 10.10.1.1 -p 30000 -t 10.10.10.2 -q 30002 > bind10test_normal
+
+./query_two_server.py --help' for more details
diff --git a/tools/query_cmp/queries/dquery01 b/tools/query_cmp/queries/dquery01
new file mode 100644
index 0000000..923ba7d
--- /dev/null
+++ b/tools/query_cmp/queries/dquery01
@@ -0,0 +1,394 @@
+# Fields Description
+#
+#query:ID QR OPCODE AA TC RD RA Z AD CD RCODE QDCOUNT ANCOUNT NSCOUNT ARCOUNT QNAME QTYPE QCLASS
+#response:ID QR OPCODE AA TC RD RA Z AD CD RCODE QDCOUNT ANCOUNT NSCOUNT ARCOUNT QNAME QTYPE QCLASS <answer> <authority> <additional>
+# <answer> := <rr1> .. <rrN>
+# <rr> := NAME TYPE CLASS TTL RDLENGTH <rdata>
+# <rdata> := ADDRESS |
+# NSDNAME |
+# MNAME RNAME SERIAL REFRESH RETRY EXPIRE MINIMUM |
+# ...
+# <authority> := <rr1> .. <rrN>
+# <additional> := <rr1> .. <rrN>
+#
+#
+#
+# Description in BNF (http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form)
+# <query> ::= <header> <question>
+# <header> ::= <ID> <QR> <OPCODE> <AA> <TC> <RD> <RA> <Z> <AD> <CD> <RCODE>
+# <QDCOUNT> <ANCOUNT> <NSCOUNT> <ARCOUNT>
+# <question> ::= <QNAME> <QTYPE> <QCLASS>
+#
+# <response> ::= <header> <question> <answer> <authority> <additional>
+# <answer> ::= <rrset>
+# <authority> ::= <rrset>
+# <additional> ::= <rrset>
+# <rrset> ::= { <rr> }
+# <rr> ::= <name> <type> <class> <ttl> <rdlength> <rdata>
+# <name> ::= <subdomain> | ""
+# <subdomain> ::= <label> | <subdomain> "." <label>
+# <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
+# <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
+# <let-dig-hyp> ::= <let-dig> | "-"
+# <let-dig> ::= <letter> | <digit>
+# <letter> ::= "a" | .. | "z" | "A" | .. | "Z"
+# <digit> ::= "0" | .. | "9"
+# <type> ::= A | NS | CNAME | SOA | PTR | MX | ..
+# <class> ::= IN | CH | HS | CS
+# <ttl> ::= <digit> | { <digit> }
+# <rdlength> ::= <digit> | { <digit> }
+# <rdata> ::= <address> |
+# <nsdname> |
+# <cname> |
+# <preference> <exchange> |
+# <ptrdname> |
+# ...
+
+0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com A IN
+1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com A IN
+2 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+3 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com A IN
+4 0 0 0 0 1 0 0 0 0 0 1 0 0 0 BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com A IN
+5 0 0 0 0 1 0 0 0 0 0 1 0 0 0 EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com A IN
+6 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com A IN
+7 0 0 0 0 1 0 0 0 0 0 1 0 0 0 B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com A IN
+8 0 0 0 0 1 0 0 0 0 0 1 0 0 0 M.example.com A IN
+9 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-a-record.example.com A IN
+
+10 0 0 0 0 1 0 0 0 0 0 1 0 0 0 NS.example.com A IN
+11 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nS.example.com A IN
+12 0 0 0 0 1 0 0 0 0 0 1 0 0 0 NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+13 0 0 0 0 1 0 0 0 0 0 1 0 0 0 NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com A IN
+14 0 0 0 0 1 0 0 0 0 0 1 0 0 0 N.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com A IN
+15 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.multiple-type-ns-record.example.com a IN
+
+20 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.example.com A IN
+21 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.example.com CNAME IN
+22 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.example.com MX IN
+23 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.example.com ANY IN
+
+24 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C0.example.com A IN
+25 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C0.example.com CNAME IN
+26 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C0.example.com MX IN
+27 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C0.example.com ANY IN
+
+28 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C10.example.com A IN
+29 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C10.example.com CNAME IN
+30 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C10.example.com MX IN
+31 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C10.example.com ANY IN
+
+32 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C36.example.com A IN
+33 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C36.example.com CNAME IN
+34 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C36.example.com MX IN
+35 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C36.example.com ANY IN
+
+36 0 0 0 0 1 0 0 0 0 0 1 0 0 0 c.Example.coM A IN
+37 0 0 0 0 1 0 0 0 0 0 1 0 0 0 c.Example.coM CNAME IN
+38 0 0 0 0 1 0 0 0 0 0 1 0 0 0 c.Example.coM MX IN
+39 0 0 0 0 1 0 0 0 0 0 1 0 0 0 c.Example.coM ANY IN
+
+40 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com A IN
+41 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com CNAME IN
+42 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com MX IN
+43 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com ANY IN
+
+44 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA1.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA2.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA3.example.com A IN
+45 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA1.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA2.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA3.example.com CNAME IN
+46 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA1.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA2.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA3.example.com MX IN
+47 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA1.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA2.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA3.example.com ANY IN
+
+48 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA1.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA2.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA4.example.com A IN
+49 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA1.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA2.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA4.example.com CNAME IN
+50 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA1.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA2.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA4.example.com MX IN
+51 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA1.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA2.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA4.example.com ANY IN
+
+52 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.example.com A IN
+53 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.example.com CNAME IN
+54 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.example.com MX IN
+55 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.example.com ANY IN
+
+56 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.1.example.com A IN
+57 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.1.example.com CNAME IN
+58 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.1.example.com MX IN
+59 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.1.example.com ANY IN
+
+60 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C0.name1.cn A IN
+61 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C12.name1.cn A IN
+
+70 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example.com SOA IN
+71 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example.com ANY IN
+
+72 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example1.com SOA IN
+73 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example1.com A IN
+74 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example1.com NS IN
+75 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example1.com ANY IN
+
+76 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example2.com SOA IN
+77 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example2.com A IN
+78 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example2.com NS IN
+79 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example2.com ANY IN
+
+80 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example3.com SOA IN
+81 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example3.com A IN
+82 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example3.com NS IN
+83 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example3.com ANY IN
+
+84 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example4.com SOA IN
+85 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example4.com A IN
+86 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example4.com NS IN
+87 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example4.com ANY IN
+
+88 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example13.com SOA IN
+89 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example13.com A IN
+90 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example13.com NS IN
+91 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example13.com ANY IN
+
+92 0 0 0 0 1 0 0 0 0 0 1 0 0 0 noexist.example.com A IN
+93 0 0 0 0 1 0 0 0 0 0 1 0 0 0 noexist.example.com ANY IN
+94 0 0 0 0 1 0 0 0 0 0 1 0 0 0 noexist.example.com NS IN
+
+95 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example9.com SOA IN
+96 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example9.com ns IN
+97 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example9.com ANY IN
+
+98 0 0 0 0 1 0 0 0 0 0 1 0 0 0 noexist.example.com SOA IN
+99 0 0 0 0 1 0 0 0 0 0 1 0 0 0 noexist.noexist SOA IN
+
+100 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1.1.10.10.in-addr.arpA PTR IN
+101 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com PTR IN
+102 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1.1.10.10.in-addr.arpa PTR IN
+103 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.examPle.com PTR IN
+104 0 0 0 0 1 0 0 0 0 0 1 0 0 0 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com PTR IN
+105 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com PTR IN
+106 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com PTR IN
+107 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1.2.168.192.in-addr.arpa PTR IN
+108 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-a-record.example.com PTR IN
+
+110 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com MX IN
+111 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com MX IN
+112 0 0 0 0 1 0 0 0 0 0 1 0 0 0 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com MX IN
+113 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com MX IN
+114 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com MX IN
+115 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-mx-record.example.com MX IN
+
+120 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com TXT IN
+121 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com TXT IN
+122 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com TXT IN
+123 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com TXT IN
+124 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com TXT IN
+125 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-txt-record.example.com TXT IN
+
+130 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com AAAA IN
+131 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com AAAA IN
+132 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com AAAA IN
+133 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com AAAA IN
+134 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com AAAA IN
+135 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-aaaa-record.example.com AAAA IN
+
+140 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com NAPTR IN
+141 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com NAPTR IN
+142 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com NAPTR IN
+143 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com NAPTR IN
+144 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com NAPTR IN
+145 0 0 0 0 1 0 0 0 0 0 1 0 0 0 2.1.2.1.5.5.5.0.7.7.1.e164.arpa NAPTR IN
+146 0 0 0 0 1 0 0 0 0 0 1 0 0 0 b.e164.arpa NAPTR IN
+147 0 0 0 0 1 0 0 0 0 0 1 0 0 0 6.8.e164.arpa NAPTR IN
+
+#150 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com A6 IN
+#151 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com A6 IN
+#152 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A6 IN
+#153 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com A6 IN
+#154 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com A6 IN
+#155 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-a6-record.example.com A6 IN
+
+# case 160-163
+160 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com DNAME IN
+161 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com ANY IN
+162 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.A.example.com A IN
+163 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.A.example.com ANY IN
+
+# case 164-167
+164 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.exAmple.com DNAME IN
+165 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.exAmple.com ANY IN
+166 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.a.exAmple.com A IN
+167 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.a.exAmple.com ANY IN
+
+# case 168-171
+168 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com DNAME IN
+169 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com ANY IN
+170 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+171 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com ANY IN
+
+# case 172-175
+172 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com DNAME IN
+173 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com ANY IN
+174 0 0 0 0 1 0 0 0 0 0 1 0 0 0 D.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com A IN
+175 0 0 0 0 1 0 0 0 0 0 1 0 0 0 D.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com ANY IN
+
+# case 176-179
+176 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.example.com DNAME IN
+177 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.example.com ANY IN
+178 0 0 0 0 1 0 0 0 0 0 1 0 0 0 D.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.example.com A IN
+179 0 0 0 0 1 0 0 0 0 0 1 0 0 0 D.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.example.com ANY IN
+
+# case 180-195
+180 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.d0.example.com a IN
+181 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.d1.example.com a IN
+182 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.d2.example.com a IN
+183 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.d4.example.com a IN
+184 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.d5.example.com a IN
+185 0 0 0 0 1 0 0 0 0 0 1 0 0 0 ns.d0.example.com a IN
+186 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.a.b.d1.example.com a IN
+187 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.a.b.d1.example.com mx IN
+
+188 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.d10.example.com a IN
+189 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.d20.example.com a IN
+190 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.d30.example.com a IN
+191 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.d40.example.com a IN
+192 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.d50.example.com a IN
+193 0 0 0 0 1 0 0 0 0 0 1 0 0 0 c45.example.com any IN
+194 0 0 0 0 1 0 0 0 0 0 1 0 0 0 d45.example.com any IN
+195 0 0 0 0 1 0 0 0 0 0 1 0 0 0 noexist.d45.example.com any IN
+196 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.d45.example.com any IN
+
+197 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.d72.example.com a IN
+198 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.d1.example.com a IN
+
+# case 200-205
+200 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com WKS IN
+201 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com WKS IN
+202 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com WKS IN
+203 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com WKS IN
+204 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com WKS IN
+205 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-wks-record.example.com WKS IN
+
+# case 210-215
+210 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com HINFO IN
+211 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com HINFO IN
+212 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com HINFO IN
+213 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com HINFO IN
+214 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com HINFO IN
+215 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-hinfo-record.example.com HINFO IN
+
+# case 220-225
+220 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com MINFO IN
+221 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com MINFO IN
+222 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com MINFO IN
+223 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com MINFO IN
+224 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com MINFO IN
+225 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-minfo-record.example.com MINFO IN
+
+# case 230-235
+230 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com NSAP IN
+231 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com NSAP IN
+232 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com NSAP IN
+233 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com NSAP IN
+234 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com NSAP IN
+235 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-nsap-record.example.com NSAP IN
+
+# case 240-245
+240 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com PX IN
+241 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com PX IN
+242 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com PX IN
+243 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com PX IN
+244 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com PX IN
+245 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-px-record.example.com PX IN
+
+# case 250-255
+250 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com LOC IN
+251 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com LOC IN
+252 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com LOC IN
+253 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com LOC IN
+254 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com LOC IN
+255 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-loc-record.example.com LOC IN
+
+# case 260-265
+260 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com SRV IN
+261 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com SRV IN
+262 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SRV IN
+263 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com SRV IN
+264 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com SRV IN
+265 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-srv-record.example.com SRV IN
+
+# case 270-275
+270 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com KX IN
+271 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com KX IN
+272 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com KX IN
+273 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com KX IN
+274 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com KX IN
+275 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-kx-record.example.com KX IN
+
+# case 280-285
+280 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com CERT IN
+281 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com CERT IN
+282 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com CERT IN
+283 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com CERT IN
+284 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com CERT IN
+285 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-cert-record.example.com CERT IN
+
+# case 290-295
+290 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com APL IN
+291 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com APL IN
+292 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com APL IN
+293 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com APL IN
+294 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com APL IN
+295 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-apl-record.example.com APL IN
+
+# case 300-305
+300 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com SSHFP IN
+301 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com SSHFP IN
+302 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SSHFP IN
+303 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com SSHFP IN
+304 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com SSHFP IN
+305 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-sshfp-record.example.com SSHFP IN
+
+# case 310-315
+310 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com IPSECKEY IN
+311 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com IPSECKEY IN
+312 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com IPSECKEY IN
+313 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com IPSECKEY IN
+314 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com IPSECKEY IN
+315 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-ipseckey-record.example.com IPSECKEY IN
+
+# case 320-325
+#320 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com DHCID IN
+#321 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com DHCID IN
+#322 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com DHCID IN
+#323 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com DHCID IN
+#324 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com DHCID IN
+#325 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-dhcid-record.example.com DHCID IN
+
+# case 330-335
+330 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com SPF IN
+331 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com SPF IN
+332 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SPF IN
+333 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com SPF IN
+334 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com SPF IN
+335 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-spf-record.example.com SPF IN
+
+360 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0.example.com A IN
+361 0 0 0 0 1 0 0 0 0 0 1 0 0 0 9.example.com A IN
+
+370 0 0 0 0 1 0 0 0 0 0 1 0 0 0 sub-cname.example.com A IN
+371 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.sub-dname.example.com A IN
+
+381 0 0 0 0 1 0 0 0 0 0 1 0 0 0 type-a-answer.toobigudp.com A IN
+382 0 0 0 0 1 0 0 0 0 0 1 0 0 0 type-a-authority.toobigudp.com A IN
+383 0 0 0 0 1 0 0 0 0 0 1 0 0 0 toobigudp.com NS IN
+384 0 0 0 0 1 0 0 0 0 0 1 0 0 0 type-txt-answer.toobigudp.com TXT IN
+385 0 0 0 0 1 0 0 0 0 0 1 0 0 0 type-txt-authority.toobigudp.com TXT IN
+386 0 0 0 0 1 0 0 0 0 0 1 0 0 0 type-cname-answer.toobigudp.com A IN
+387 0 0 0 0 1 0 0 0 0 0 1 0 0 0 type-cname-answer.toobigudp.com TXT IN
+
+390 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example.com DNSKEY IN
+391 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example.com RRSIG IN
+392 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example.com NSEC IN
+393 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example.com DS IN
+#0x1000 0 0 0 0 1 0 0 0 0 0 1 0 0 0 version.bind txt CH
+#0x1001 0 0 0 0 1 0 0 0 0 0 1 0 0 0 hostname.bind txt CH
+#0x1002 0 0 0 0 1 0 0 0 0 0 1 0 0 0 id.server txt CH
+#0x1003 0 0 0 0 1 0 0 0 0 0 1 0 0 0 authors.bind txt CH
+#0x1000 0 0 0 0 1 0 0 0 0 0 1 0 0 0 version.bind txt CH
+#0x1001 0 0 0 0 1 0 0 0 0 0 1 0 0 0 hostname.bind txt CH
+#0x1002 0 0 0 0 1 0 0 0 0 0 1 0 0 0 id.server txt CH
+#0x1003 0 0 0 0 1 0 0 0 0 0 1 0 0 0 authors.bind txt CH
diff --git a/tools/query_cmp/queries/dquery01_no-type b/tools/query_cmp/queries/dquery01_no-type
new file mode 100644
index 0000000..69b09ba
--- /dev/null
+++ b/tools/query_cmp/queries/dquery01_no-type
@@ -0,0 +1,316 @@
+# Fields Description
+#
+#query:ID QR OPCODE AA TC RD RA Z AD CD RCODE QDCOUNT ANCOUNT NSCOUNT ARCOUNT testa.no-type.QNAME QTYPE QCLASS
+#response:ID QR OPCODE AA TC RD RA Z AD CD RCODE QDCOUNT ANCOUNT NSCOUNT ARCOUNT testa.no-type.QNAME QTYPE QCLASS
+# <answer> := <rr1> .. <rrN>
+# <rr> := NAME TYPE CLASS TTL RDLENGTH <rdata>
+# <rdata> := ADDRESS |
+# NSDNAME |
+# MNAME RNAME SERIAL REFRESH RETRY EXPIRE MINIMUM |
+# ...
+# <authority> := <rr1> .. <rrN>
+# <additional> := <rr1> .. <rrN>
+#
+#
+#
+# Description in BNF (http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form)
+# <query> ::= <header> <question>
+# <header> ::= <ID> <QR> <OPCODE> <AA> <TC> <RD> <RA> <Z> <AD> <CD> <RCODE>
+# <QDCOUNT> <ANCOUNT> <NSCOUNT> <ARCOUNT>
+# <question> ::= <QNAME> <QTYPE> <QCLASS>
+#
+# <response> ::= <header> <question> <answer> <authority> <additional>
+# <answer> ::= <rrset>
+# <authority> ::= <rrset>
+# <additional> ::= <rrset>
+# <rrset> ::= { <rr> }
+# <rr> ::= <name> <type> <class> <ttl> <rdlength> <rdata>
+# <name> ::= <subdomain> | ""
+# <subdomain> ::= <label> | <subdomain> "." <label>
+# <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
+# <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
+# <let-dig-hyp> ::= <let-dig> | "-"
+# <let-dig> ::= <letter> | <digit>
+# <letter> ::= "a" | .. | "z" | "A" | .. | "Z"
+# <digit> ::= "0" | .. | "9"
+# <type> ::= A | NS | CNAME | SOA | PTR | MX | testa.no-type...
+# <class> ::= IN | CH | HS | CS
+# <ttl> ::= <digit> | { <digit> }
+# <rdlength> ::= <digit> | { <digit> }
+# <rdata> ::= <address> |
+# <nsdname> |
+# <cname> |
+# <preference> <exchange> |
+# <ptrdname> |
+# ...
+
+0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com A IN
+1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com A IN
+2 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+5 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com A IN
+8 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.M.example.com A IN
+9 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-a-record.example.com A IN
+
+10 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.NS.example.com A IN
+11 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.nS.example.com A IN
+12 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+15 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.multiple-type-ns-record.example.com a IN
+
+20 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C.example.com A IN
+21 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C.example.com CNAME IN
+22 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C.example.com MX IN
+23 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C.example.com ANY IN
+
+24 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C0.example.com A IN
+25 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C0.example.com CNAME IN
+26 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C0.example.com MX IN
+27 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C0.example.com ANY IN
+
+28 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C10.example.com A IN
+29 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C10.example.com CNAME IN
+30 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C10.example.com MX IN
+31 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C10.example.com ANY IN
+
+32 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C36.example.com A IN
+33 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C36.example.com CNAME IN
+34 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C36.example.com MX IN
+35 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C36.example.com ANY IN
+
+36 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.c.Example.coM A IN
+37 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.c.Example.coM CNAME IN
+38 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.c.Example.coM MX IN
+39 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.c.Example.coM ANY IN
+
+40 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com A IN
+41 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com CNAME IN
+42 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com MX IN
+43 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com ANY IN
+
+60 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C0.name1.cn A IN
+61 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C12.name1.cn A IN
+
+70 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example.com SOA IN
+71 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example.com ANY IN
+
+72 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example1.com SOA IN
+73 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example1.com A IN
+74 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example1.com NS IN
+75 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example1.com ANY IN
+
+76 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example2.com SOA IN
+77 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example2.com A IN
+78 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example2.com NS IN
+79 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example2.com ANY IN
+
+80 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example3.com SOA IN
+81 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example3.com A IN
+82 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example3.com NS IN
+83 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example3.com ANY IN
+
+84 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example4.com SOA IN
+85 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example4.com A IN
+86 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example4.com NS IN
+87 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example4.com ANY IN
+
+88 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example13.com SOA IN
+89 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example13.com A IN
+90 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example13.com NS IN
+91 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example13.com ANY IN
+
+92 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.noexist.example.com A IN
+93 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.noexist.example.com ANY IN
+94 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.noexist.example.com NS IN
+
+95 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example9.com SOA IN
+96 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example9.com ns IN
+97 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example9.com ANY IN
+
+98 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.noexist.example.com SOA IN
+99 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.noexist.noexist SOA IN
+
+100 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.1.1.10.10.in-addr.arpA PTR IN
+101 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com PTR IN
+102 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.1.1.10.10.in-addr.arpa PTR IN
+103 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.examPle.com PTR IN
+104 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com PTR IN
+107 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.1.2.168.192.in-addr.arpa PTR IN
+108 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-a-record.example.com PTR IN
+
+110 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com MX IN
+111 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com MX IN
+112 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com MX IN
+115 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-mx-record.example.com MX IN
+
+120 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com TXT IN
+121 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com TXT IN
+122 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com TXT IN
+125 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-txt-record.example.com TXT IN
+
+130 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com AAAA IN
+131 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com AAAA IN
+132 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com AAAA IN
+135 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-aaaa-record.example.com AAAA IN
+
+140 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com NAPTR IN
+141 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com NAPTR IN
+142 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com NAPTR IN
+145 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.2.1.2.1.5.5.5.0.7.7.1.e164.arpa NAPTR IN
+146 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.b.e164.arpa NAPTR IN
+147 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.6.8.e164.arpa NAPTR IN
+
+#150 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com A6 IN
+#151 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com A6 IN
+#152 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A6 IN
+#155 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-a6-record.example.com A6 IN
+
+# case 160-163
+160 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com DNAME IN
+161 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com ANY IN
+162 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.A.example.com A IN
+163 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.A.example.com ANY IN
+
+# case 164-167
+164 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.exAmple.com DNAME IN
+165 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.exAmple.com ANY IN
+166 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.a.exAmple.com A IN
+167 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.a.exAmple.com ANY IN
+
+# case 168-171
+168 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com DNAME IN
+169 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com ANY IN
+170 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+171 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com ANY IN
+
+# case 180-195
+180 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.d0.example.com a IN
+181 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.d1.example.com a IN
+182 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.d2.example.com a IN
+183 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.d4.example.com a IN
+184 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.d5.example.com a IN
+185 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.ns.d0.example.com a IN
+186 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.a.b.d1.example.com a IN
+187 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.a.b.d1.example.com mx IN
+
+188 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.d10.example.com a IN
+189 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.d20.example.com a IN
+190 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.d30.example.com a IN
+191 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.d40.example.com a IN
+192 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.d50.example.com a IN
+193 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.c45.example.com any IN
+194 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.d45.example.com any IN
+195 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.noexist.d45.example.com any IN
+196 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.d45.example.com any IN
+
+197 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.d72.example.com a IN
+198 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.d1.example.com a IN
+
+# case 200-205
+200 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com WKS IN
+201 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com WKS IN
+202 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com WKS IN
+205 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-wks-record.example.com WKS IN
+
+# case 210-215
+210 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com HINFO IN
+211 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com HINFO IN
+212 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com HINFO IN
+215 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-hinfo-record.example.com HINFO IN
+
+# case 220-225
+220 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com MINFO IN
+221 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com MINFO IN
+222 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com MINFO IN
+225 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-minfo-record.example.com MINFO IN
+
+# case 230-235
+230 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com NSAP IN
+231 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com NSAP IN
+232 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com NSAP IN
+235 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-nsap-record.example.com NSAP IN
+
+# case 240-245
+240 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com PX IN
+241 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com PX IN
+242 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com PX IN
+245 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-px-record.example.com PX IN
+
+# case 250-255
+250 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com LOC IN
+251 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com LOC IN
+252 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com LOC IN
+255 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-loc-record.example.com LOC IN
+
+# case 260-265
+260 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com SRV IN
+261 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com SRV IN
+262 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SRV IN
+265 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-srv-record.example.com SRV IN
+
+# case 270-275
+270 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com KX IN
+271 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com KX IN
+272 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com KX IN
+275 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-kx-record.example.com KX IN
+
+# case 280-285
+280 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com CERT IN
+281 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com CERT IN
+282 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com CERT IN
+285 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-cert-record.example.com CERT IN
+
+# case 290-295
+290 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com APL IN
+291 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com APL IN
+292 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com APL IN
+295 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-apl-record.example.com APL IN
+
+# case 300-305
+300 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com SSHFP IN
+301 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com SSHFP IN
+302 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SSHFP IN
+305 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-sshfp-record.example.com SSHFP IN
+
+# case 310-315
+310 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com IPSECKEY IN
+311 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com IPSECKEY IN
+312 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com IPSECKEY IN
+315 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-ipseckey-record.example.com IPSECKEY IN
+
+# case 320-325
+#320 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com DHCID IN
+#321 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com DHCID IN
+#322 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com DHCID IN
+#325 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-dhcid-record.example.com DHCID IN
+
+# case 330-335
+330 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com SPF IN
+331 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com SPF IN
+332 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SPF IN
+335 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-spf-record.example.com SPF IN
+
+360 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.0.example.com A IN
+361 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.9.example.com A IN
+
+370 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.sub-cname.example.com A IN
+371 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.sub-dname.example.com A IN
+
+381 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.type-a-answer.toobigudp.com A IN
+382 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.type-a-authority.toobigudp.com A IN
+383 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.toobigudp.com NS IN
+384 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.type-txt-answer.toobigudp.com TXT IN
+385 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.type-txt-authority.toobigudp.com TXT IN
+386 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.type-cname-answer.toobigudp.com A IN
+387 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.type-cname-answer.toobigudp.com TXT IN
+
+390 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example.com DNSKEY IN
+391 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example.com RRSIG IN
+392 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example.com NSEC IN
+393 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example.com DS IN
+#0x1000 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.version.bind txt CH
+#0x1001 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.hostname.bind txt CH
+#0x1002 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.id.server txt CH
+#0x1003 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.authors.bind txt CH
+#0x1000 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.version.bind txt CH
+#0x1001 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.hostname.bind txt CH
+#0x1002 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.id.server txt CH
+#0x1003 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.authors.bind txt CH
diff --git a/tools/query_cmp/queries/dquery01_non-terminal b/tools/query_cmp/queries/dquery01_non-terminal
new file mode 100644
index 0000000..2bbd9de
--- /dev/null
+++ b/tools/query_cmp/queries/dquery01_non-terminal
@@ -0,0 +1,317 @@
+# Fields Description
+#
+#query:ID QR OPCODE AA TC RD RA Z AD CD RCODE QDCOUNT ANCOUNT NSCOUNT ARCOUNT non-terminal.QNAME QTYPE QCLASS
+#response:ID QR OPCODE AA TC RD RA Z AD CD RCODE QDCOUNT ANCOUNT NSCOUNT ARCOUNT non-terminal.QNAME QTYPE QCLASS
+# <answer> := <rr1> .. <rrN>
+# <rr> := NAME TYPE CLASS TTL RDLENGTH <rdata>
+# <rdata> := ADDRESS |
+# NSDNAME |
+# MNAME RNAME SERIAL REFRESH RETRY EXPIRE MINIMUM |
+# ...
+# <authority> := <rr1> .. <rrN>
+# <additional> := <rr1> .. <rrN>
+#
+#
+#
+# Description in BNF (http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form)
+# <query> ::= <header> <question>
+# <header> ::= <ID> <QR> <OPCODE> <AA> <TC> <RD> <RA> <Z> <AD> <CD> <RCODE>
+# <QDCOUNT> <ANCOUNT> <NSCOUNT> <ARCOUNT>
+# <question> ::= <QNAME> <QTYPE> <QCLASS>
+#
+# <response> ::= <header> <question> <answer> <authority> <additional>
+# <answer> ::= <rrset>
+# <authority> ::= <rrset>
+# <additional> ::= <rrset>
+# <rrset> ::= { <rr> }
+# <rr> ::= <name> <type> <class> <ttl> <rdlength> <rdata>
+# <name> ::= <subdomain> | ""
+# <subdomain> ::= <label> | <subdomain> "." <label>
+# <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
+# <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
+# <let-dig-hyp> ::= <let-dig> | "-"
+# <let-dig> ::= <letter> | <digit>
+# <letter> ::= "a" | .. | "z" | "A" | .. | "Z"
+# <digit> ::= "0" | .. | "9"
+# <type> ::= A | NS | CNAME | SOA | PTR | MX | non-terminal...
+# <class> ::= IN | CH | HS | CS
+# <ttl> ::= <digit> | { <digit> }
+# <rdlength> ::= <digit> | { <digit> }
+# <rdata> ::= <address> |
+# <nsdname> |
+# <cname> |
+# <preference> <exchange> |
+# <ptrdname> |
+# ...
+
+0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com A IN
+1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com A IN
+2 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+5 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com A IN
+8 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.M.example.com A IN
+9 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-a-record.example.com A IN
+
+10 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.NS.example.com A IN
+11 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.nS.example.com A IN
+12 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+15 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.multiple-type-ns-record.example.com a IN
+
+20 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C.example.com A IN
+21 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C.example.com CNAME IN
+22 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C.example.com MX IN
+23 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C.example.com ANY IN
+
+24 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C0.example.com A IN
+25 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C0.example.com CNAME IN
+26 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C0.example.com MX IN
+27 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C0.example.com ANY IN
+
+28 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C10.example.com A IN
+29 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C10.example.com CNAME IN
+30 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C10.example.com MX IN
+31 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C10.example.com ANY IN
+
+32 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C36.example.com A IN
+33 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C36.example.com CNAME IN
+34 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C36.example.com MX IN
+35 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C36.example.com ANY IN
+
+36 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.c.Example.coM A IN
+37 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.c.Example.coM CNAME IN
+38 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.c.Example.coM MX IN
+39 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.c.Example.coM ANY IN
+
+40 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com A IN
+41 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com CNAME IN
+42 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com MX IN
+43 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com ANY IN
+
+
+60 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C0.name1.cn A IN
+61 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C12.name1.cn A IN
+
+70 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example.com SOA IN
+71 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example.com ANY IN
+
+72 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example1.com SOA IN
+73 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example1.com A IN
+74 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example1.com NS IN
+75 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example1.com ANY IN
+
+76 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example2.com SOA IN
+77 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example2.com A IN
+78 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example2.com NS IN
+79 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example2.com ANY IN
+
+80 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example3.com SOA IN
+81 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example3.com A IN
+82 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example3.com NS IN
+83 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example3.com ANY IN
+
+84 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example4.com SOA IN
+85 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example4.com A IN
+86 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example4.com NS IN
+87 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example4.com ANY IN
+
+88 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example13.com SOA IN
+89 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example13.com A IN
+90 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example13.com NS IN
+91 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example13.com ANY IN
+
+92 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.noexist.example.com A IN
+93 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.noexist.example.com ANY IN
+94 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.noexist.example.com NS IN
+
+95 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example9.com SOA IN
+96 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example9.com ns IN
+97 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example9.com ANY IN
+
+98 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.noexist.example.com SOA IN
+99 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.noexist.noexist SOA IN
+
+100 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.1.1.10.10.in-addr.arpA PTR IN
+101 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com PTR IN
+102 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.1.1.10.10.in-addr.arpa PTR IN
+103 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.examPle.com PTR IN
+104 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com PTR IN
+107 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.1.2.168.192.in-addr.arpa PTR IN
+108 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-a-record.example.com PTR IN
+
+110 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com MX IN
+111 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com MX IN
+112 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com MX IN
+115 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-mx-record.example.com MX IN
+
+120 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com TXT IN
+121 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com TXT IN
+122 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com TXT IN
+125 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-txt-record.example.com TXT IN
+
+130 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com AAAA IN
+131 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com AAAA IN
+132 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com AAAA IN
+135 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-aaaa-record.example.com AAAA IN
+
+140 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com NAPTR IN
+141 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com NAPTR IN
+142 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com NAPTR IN
+145 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.2.1.2.1.5.5.5.0.7.7.1.e164.arpa NAPTR IN
+146 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.b.e164.arpa NAPTR IN
+147 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.6.8.e164.arpa NAPTR IN
+
+#150 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com A6 IN
+#151 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com A6 IN
+#152 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A6 IN
+#155 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-a6-record.example.com A6 IN
+
+# case 160-163
+160 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com DNAME IN
+161 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com ANY IN
+162 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.A.example.com A IN
+163 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.A.example.com ANY IN
+
+# case 164-167
+164 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.exAmple.com DNAME IN
+165 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.exAmple.com ANY IN
+166 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.a.exAmple.com A IN
+167 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.a.exAmple.com ANY IN
+
+# case 168-171
+168 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com DNAME IN
+169 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com ANY IN
+170 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+171 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com ANY IN
+
+# case 180-195
+180 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.d0.example.com a IN
+181 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.d1.example.com a IN
+182 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.d2.example.com a IN
+183 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.d4.example.com a IN
+184 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.d5.example.com a IN
+185 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.ns.d0.example.com a IN
+186 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.a.b.d1.example.com a IN
+187 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.a.b.d1.example.com mx IN
+
+188 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.d10.example.com a IN
+189 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.d20.example.com a IN
+190 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.d30.example.com a IN
+191 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.d40.example.com a IN
+192 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.d50.example.com a IN
+193 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.c45.example.com any IN
+194 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.d45.example.com any IN
+195 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.noexist.d45.example.com any IN
+196 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.d45.example.com any IN
+
+197 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.d72.example.com a IN
+198 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.d1.example.com a IN
+
+# case 200-205
+200 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com WKS IN
+201 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com WKS IN
+202 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com WKS IN
+205 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-wks-record.example.com WKS IN
+
+# case 210-215
+210 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com HINFO IN
+211 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com HINFO IN
+212 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com HINFO IN
+215 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-hinfo-record.example.com HINFO IN
+
+# case 220-225
+220 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com MINFO IN
+221 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com MINFO IN
+222 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com MINFO IN
+225 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-minfo-record.example.com MINFO IN
+
+# case 230-235
+230 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com NSAP IN
+231 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com NSAP IN
+232 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com NSAP IN
+235 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-nsap-record.example.com NSAP IN
+
+# case 240-245
+240 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com PX IN
+241 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com PX IN
+242 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com PX IN
+245 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-px-record.example.com PX IN
+
+# case 250-255
+250 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com LOC IN
+251 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com LOC IN
+252 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com LOC IN
+255 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-loc-record.example.com LOC IN
+
+# case 260-265
+260 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com SRV IN
+261 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com SRV IN
+262 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SRV IN
+265 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-srv-record.example.com SRV IN
+
+# case 270-275
+270 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com KX IN
+271 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com KX IN
+272 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com KX IN
+275 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-kx-record.example.com KX IN
+
+# case 280-285
+280 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com CERT IN
+281 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com CERT IN
+282 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com CERT IN
+285 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-cert-record.example.com CERT IN
+
+# case 290-295
+290 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com APL IN
+291 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com APL IN
+292 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com APL IN
+295 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-apl-record.example.com APL IN
+
+# case 300-305
+300 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com SSHFP IN
+301 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com SSHFP IN
+302 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SSHFP IN
+305 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-sshfp-record.example.com SSHFP IN
+
+# case 310-315
+310 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com IPSECKEY IN
+311 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com IPSECKEY IN
+312 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com IPSECKEY IN
+315 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-ipseckey-record.example.com IPSECKEY IN
+
+# case 320-325
+#320 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com DHCID IN
+#321 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com DHCID IN
+#322 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com DHCID IN
+#325 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-dhcid-record.example.com DHCID IN
+
+# case 330-335
+330 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com SPF IN
+331 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com SPF IN
+332 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SPF IN
+335 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-spf-record.example.com SPF IN
+
+360 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.0.example.com A IN
+361 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.9.example.com A IN
+
+370 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.sub-cname.example.com A IN
+371 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.sub-dname.example.com A IN
+
+381 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.type-a-answer.toobigudp.com A IN
+382 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.type-a-authority.toobigudp.com A IN
+383 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.toobigudp.com NS IN
+384 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.type-txt-answer.toobigudp.com TXT IN
+385 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.type-txt-authority.toobigudp.com TXT IN
+386 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.type-cname-answer.toobigudp.com A IN
+387 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.type-cname-answer.toobigudp.com TXT IN
+
+390 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example.com DNSKEY IN
+391 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example.com RRSIG IN
+392 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example.com NSEC IN
+393 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example.com DS IN
+#0x1000 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.version.bind txt CH
+#0x1001 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.hostname.bind txt CH
+#0x1002 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.id.server txt CH
+#0x1003 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.authors.bind txt CH
+#0x1000 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.version.bind txt CH
+#0x1001 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.hostname.bind txt CH
+#0x1002 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.id.server txt CH
+#0x1003 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.authors.bind txt CH
diff --git a/tools/query_cmp/queries/dquery01_nxdomain b/tools/query_cmp/queries/dquery01_nxdomain
new file mode 100644
index 0000000..aed1ceb
--- /dev/null
+++ b/tools/query_cmp/queries/dquery01_nxdomain
@@ -0,0 +1,316 @@
+# Fields Description
+#
+#query:ID QR OPCODE AA TC RD RA Z AD CD RCODE QDCOUNT ANCOUNT NSCOUNT ARCOUNT nxdomain.QNAME QTYPE QCLASS
+#response:ID QR OPCODE AA TC RD RA Z AD CD RCODE QDCOUNT ANCOUNT NSCOUNT ARCOUNT nxdomain.QNAME QTYPE QCLASS
+# <answer> := <rr1> .. <rrN>
+# <rr> := NAME TYPE CLASS TTL RDLENGTH <rdata>
+# <rdata> := ADDRESS |
+# NSDNAME |
+# MNAME RNAME SERIAL REFRESH RETRY EXPIRE MINIMUM |
+# ...
+# <authority> := <rr1> .. <rrN>
+# <additional> := <rr1> .. <rrN>
+#
+#
+#
+# Description in BNF (http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form)
+# <query> ::= <header> <question>
+# <header> ::= <ID> <QR> <OPCODE> <AA> <TC> <RD> <RA> <Z> <AD> <CD> <RCODE>
+# <QDCOUNT> <ANCOUNT> <NSCOUNT> <ARCOUNT>
+# <question> ::= <QNAME> <QTYPE> <QCLASS>
+#
+# <response> ::= <header> <question> <answer> <authority> <additional>
+# <answer> ::= <rrset>
+# <authority> ::= <rrset>
+# <additional> ::= <rrset>
+# <rrset> ::= { <rr> }
+# <rr> ::= <name> <type> <class> <ttl> <rdlength> <rdata>
+# <name> ::= <subdomain> | ""
+# <subdomain> ::= <label> | <subdomain> "." <label>
+# <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
+# <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
+# <let-dig-hyp> ::= <let-dig> | "-"
+# <let-dig> ::= <letter> | <digit>
+# <letter> ::= "a" | .. | "z" | "A" | .. | "Z"
+# <digit> ::= "0" | .. | "9"
+# <type> ::= A | NS | CNAME | SOA | PTR | MX | nxdomain...
+# <class> ::= IN | CH | HS | CS
+# <ttl> ::= <digit> | { <digit> }
+# <rdlength> ::= <digit> | { <digit> }
+# <rdata> ::= <address> |
+# <nsdname> |
+# <cname> |
+# <preference> <exchange> |
+# <ptrdname> |
+# ...
+
+0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com A IN
+1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com A IN
+2 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+5 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com A IN
+8 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.M.example.com A IN
+9 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-a-record.example.com A IN
+
+10 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.NS.example.com A IN
+11 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.nS.example.com A IN
+12 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+15 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.multiple-type-ns-record.example.com a IN
+
+20 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C.example.com A IN
+21 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C.example.com CNAME IN
+22 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C.example.com MX IN
+23 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C.example.com ANY IN
+
+24 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C0.example.com A IN
+25 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C0.example.com CNAME IN
+26 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C0.example.com MX IN
+27 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C0.example.com ANY IN
+
+28 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C10.example.com A IN
+29 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C10.example.com CNAME IN
+30 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C10.example.com MX IN
+31 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C10.example.com ANY IN
+
+32 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C36.example.com A IN
+33 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C36.example.com CNAME IN
+34 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C36.example.com MX IN
+35 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C36.example.com ANY IN
+
+36 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.c.Example.coM A IN
+37 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.c.Example.coM CNAME IN
+38 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.c.Example.coM MX IN
+39 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.c.Example.coM ANY IN
+
+40 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com A IN
+41 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com CNAME IN
+42 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com MX IN
+43 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com ANY IN
+
+60 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C0.name1.cn A IN
+61 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C12.name1.cn A IN
+
+70 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example.com SOA IN
+71 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example.com ANY IN
+
+72 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example1.com SOA IN
+73 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example1.com A IN
+74 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example1.com NS IN
+75 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example1.com ANY IN
+
+76 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example2.com SOA IN
+77 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example2.com A IN
+78 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example2.com NS IN
+79 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example2.com ANY IN
+
+80 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example3.com SOA IN
+81 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example3.com A IN
+82 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example3.com NS IN
+83 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example3.com ANY IN
+
+84 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example4.com SOA IN
+85 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example4.com A IN
+86 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example4.com NS IN
+87 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example4.com ANY IN
+
+88 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example13.com SOA IN
+89 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example13.com A IN
+90 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example13.com NS IN
+91 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example13.com ANY IN
+
+92 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.noexist.example.com A IN
+93 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.noexist.example.com ANY IN
+94 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.noexist.example.com NS IN
+
+95 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example9.com SOA IN
+96 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example9.com ns IN
+97 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example9.com ANY IN
+
+98 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.noexist.example.com SOA IN
+99 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.noexist.noexist SOA IN
+
+100 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.1.1.10.10.in-addr.arpA PTR IN
+101 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com PTR IN
+102 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.1.1.10.10.in-addr.arpa PTR IN
+103 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.examPle.com PTR IN
+104 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com PTR IN
+107 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.1.2.168.192.in-addr.arpa PTR IN
+108 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-a-record.example.com PTR IN
+
+110 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com MX IN
+111 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com MX IN
+112 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com MX IN
+115 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-mx-record.example.com MX IN
+
+120 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com TXT IN
+121 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com TXT IN
+122 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com TXT IN
+125 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-txt-record.example.com TXT IN
+
+130 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com AAAA IN
+131 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com AAAA IN
+132 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com AAAA IN
+135 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-aaaa-record.example.com AAAA IN
+
+140 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com NAPTR IN
+141 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com NAPTR IN
+142 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com NAPTR IN
+145 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.2.1.2.1.5.5.5.0.7.7.1.e164.arpa NAPTR IN
+146 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.b.e164.arpa NAPTR IN
+147 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.6.8.e164.arpa NAPTR IN
+
+#150 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com A6 IN
+#151 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com A6 IN
+#152 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A6 IN
+#155 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-a6-record.example.com A6 IN
+
+# case 160-163
+160 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com DNAME IN
+161 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com ANY IN
+162 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.A.example.com A IN
+163 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.A.example.com ANY IN
+
+# case 164-167
+164 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.exAmple.com DNAME IN
+165 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.exAmple.com ANY IN
+166 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.a.exAmple.com A IN
+167 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.a.exAmple.com ANY IN
+
+# case 168-171
+168 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com DNAME IN
+169 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com ANY IN
+170 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+171 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com ANY IN
+
+# case 180-195
+180 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.d0.example.com a IN
+181 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.d1.example.com a IN
+182 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.d2.example.com a IN
+183 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.d4.example.com a IN
+184 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.d5.example.com a IN
+185 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.ns.d0.example.com a IN
+186 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.a.b.d1.example.com a IN
+187 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.a.b.d1.example.com mx IN
+
+188 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.d10.example.com a IN
+189 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.d20.example.com a IN
+190 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.d30.example.com a IN
+191 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.d40.example.com a IN
+192 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.d50.example.com a IN
+193 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.c45.example.com any IN
+194 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.d45.example.com any IN
+195 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.noexist.d45.example.com any IN
+196 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.d45.example.com any IN
+
+197 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.d72.example.com a IN
+198 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.d1.example.com a IN
+
+# case 200-205
+200 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com WKS IN
+201 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com WKS IN
+202 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com WKS IN
+205 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-wks-record.example.com WKS IN
+
+# case 210-215
+210 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com HINFO IN
+211 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com HINFO IN
+212 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com HINFO IN
+215 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-hinfo-record.example.com HINFO IN
+
+# case 220-225
+220 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com MINFO IN
+221 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com MINFO IN
+222 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com MINFO IN
+225 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-minfo-record.example.com MINFO IN
+
+# case 230-235
+230 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com NSAP IN
+231 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com NSAP IN
+232 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com NSAP IN
+235 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-nsap-record.example.com NSAP IN
+
+# case 240-245
+240 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com PX IN
+241 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com PX IN
+242 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com PX IN
+245 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-px-record.example.com PX IN
+
+# case 250-255
+250 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com LOC IN
+251 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com LOC IN
+252 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com LOC IN
+255 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-loc-record.example.com LOC IN
+
+# case 260-265
+260 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com SRV IN
+261 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com SRV IN
+262 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SRV IN
+265 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-srv-record.example.com SRV IN
+
+# case 270-275
+270 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com KX IN
+271 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com KX IN
+272 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com KX IN
+275 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-kx-record.example.com KX IN
+
+# case 280-285
+280 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com CERT IN
+281 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com CERT IN
+282 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com CERT IN
+285 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-cert-record.example.com CERT IN
+
+# case 290-295
+290 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com APL IN
+291 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com APL IN
+292 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com APL IN
+295 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-apl-record.example.com APL IN
+
+# case 300-305
+300 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com SSHFP IN
+301 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com SSHFP IN
+302 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SSHFP IN
+305 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-sshfp-record.example.com SSHFP IN
+
+# case 310-315
+310 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com IPSECKEY IN
+311 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com IPSECKEY IN
+312 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com IPSECKEY IN
+315 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-ipseckey-record.example.com IPSECKEY IN
+
+# case 320-325
+#320 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com DHCID IN
+#321 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com DHCID IN
+#322 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com DHCID IN
+#325 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-dhcid-record.example.com DHCID IN
+
+# case 330-335
+330 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com SPF IN
+331 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com SPF IN
+332 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SPF IN
+335 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-spf-record.example.com SPF IN
+
+360 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.0.example.com A IN
+361 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.9.example.com A IN
+
+370 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.sub-cname.example.com A IN
+371 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.sub-dname.example.com A IN
+
+381 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.type-a-answer.toobigudp.com A IN
+382 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.type-a-authority.toobigudp.com A IN
+383 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.toobigudp.com NS IN
+384 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.type-txt-answer.toobigudp.com TXT IN
+385 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.type-txt-authority.toobigudp.com TXT IN
+386 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.type-cname-answer.toobigudp.com A IN
+387 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.type-cname-answer.toobigudp.com TXT IN
+
+390 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example.com DNSKEY IN
+391 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example.com RRSIG IN
+392 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example.com NSEC IN
+393 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example.com DS IN
+#0x1000 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.version.bind txt CH
+#0x1001 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.hostname.bind txt CH
+#0x1002 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.id.server txt CH
+#0x1003 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.authors.bind txt CH
+#0x1000 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.version.bind txt CH
+#0x1001 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.hostname.bind txt CH
+#0x1002 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.id.server txt CH
+#0x1003 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.authors.bind txt CH
diff --git a/tools/query_cmp/src/lib/compare_rrset.py b/tools/query_cmp/src/lib/compare_rrset.py
new file mode 100755
index 0000000..737d761
--- /dev/null
+++ b/tools/query_cmp/src/lib/compare_rrset.py
@@ -0,0 +1,285 @@
+#!/usr/bin/python3
+
+# Copyright (C) 2011 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.
+
+import struct
+from pydnspp import *
+
+# Some position parameters used in the formatted output report.
+POS_TOTAL = 80
+POS_TITLE = 14
+POS_LEFT = int((POS_TOTAL - POS_TITLE) / 2)
+
+def get_header_field(msg):
+ header = {}
+ header['id'] = msg.get_qid()
+ header['qr'] = msg.get_header_flag(Message.HEADERFLAG_QR)
+ header['opcode'] = msg.get_opcode()
+ header['aa'] = msg.get_header_flag(Message.HEADERFLAG_AA)
+ header['tc'] = msg.get_header_flag(Message.HEADERFLAG_TC)
+ header['rd'] = msg.get_header_flag(Message.HEADERFLAG_RD)
+ header['ra'] = msg.get_header_flag(Message.HEADERFLAG_RA)
+ header['ad'] = msg.get_header_flag(Message.HEADERFLAG_AD)
+ header['cd'] = msg.get_header_flag(Message.HEADERFLAG_CD)
+ #header['rcode'] = dns.rcode.from_flags(msg.flags, msg.ednsflags)
+ header['rcode'] = msg.get_rcode()
+
+ header['qdcount'] = msg.get_rr_count(Message.SECTION_QUESTION)
+ header['ancount'] = msg.get_rr_count(Message.SECTION_ANSWER)
+ header['nscount'] = msg.get_rr_count(Message.SECTION_AUTHORITY)
+ header['arcount'] = msg.get_rr_count(Message.SECTION_ADDITIONAL)
+
+ return header
+
+def header_cmp(buf, msg1, msg2, diff):
+ """ Compare the header of msg1 and msg2.
+
+ @param buf: the formatted difference for output.
+ @type buf: dict
+ @param diff: the key is each flag in the header, the value is
+ True for different and False for same
+ @type diff: dict
+ """
+
+ header1 = get_header_field(msg1)
+ header2 = get_header_field(msg2)
+
+ list = ['id', 'qr', 'opcode', 'aa', 'tc', 'rd', \
+ 'ra', 'ad', 'cd', 'rcode', 'qdcount', 'ancount', \
+ 'nscount', 'arcount']
+
+ for header in list:
+ diff[header] = header1[header] != header2[header]
+
+ buf['header'] = ''
+ for key in list:
+ if diff[key]:
+ buf['header'] = buf['header'] + \
+ '%-*s%-*s%-*s\n' % (POS_TITLE, key, \
+ POS_LEFT, header1[key], POS_LEFT, \
+ header2[key])
+
+ for key in diff.keys():
+ if diff[key]: return(False)
+
+ return(True)
+
+
+def output(sect, buf, rrset, isleft):
+ """ Format and return the rrset according to which section
+ and which message it belongs to.
+
+ @param sect: section name
+ @type sect: string
+ @param buf: passed by parameter, to store the formatted string
+ @param buf: dict
+ @param rrset: the rrset to be formatted
+ @type rrset: RRset
+ @param isleft: to be compared, the report has the content corresponding to
+ the 1st message printed on the left, while the one corresponding
+ to the 2nd message on the right. This is a flag to which one it is.
+ @type isleft: BOOL
+ """
+
+ if not sect in buf:
+ buf[sect] = ''
+ if sect == 'question':
+ buf[sect] = buf[sect] + '%-*s' % (POS_TITLE, 'name')
+ if not isleft:
+ buf[sect] = buf[sect] + ' ' * POS_LEFT
+ buf[sect] = buf[sect] + rrset.get_name().to_text() + "\n"
+
+ buf[sect] = buf[sect] + '%-*s' % (POS_TITLE, 'class')
+ if not isleft:
+ buf[sect] = buf[sect] + ' ' * POS_LEFT
+ buf[sect] = buf[sect] + rrset.get_class().to_text() + "\n"
+
+ buf[sect] = buf[sect] + '%-*s' % (POS_TITLE, 'type')
+ if not isleft:
+ buf[sect] = buf[sect] + ' ' * POS_LEFT
+ buf[sect] = buf[sect] + rrset.get_type().to_text() + "\n"
+
+ else:
+ buf[sect] = buf[sect] + '%-*s' % (POS_TITLE, 'ttl')
+ if not isleft:
+ buf[sect] = buf[sect] + ' ' * int(POS_LEFT)
+ buf[sect] = buf[sect] + rrset.get_ttl().to_text() + "\n"
+
+ buf[sect] = buf[sect] + '%-*s' % (POS_TITLE, 'name')
+ if not isleft:
+ buf[sect] = buf[sect] + ' ' * int(POS_LEFT)
+ buf[sect] = buf[sect] + rrset.get_name().to_text() + "\n"
+
+ buf[sect] = buf[sect] + '%-*s' % (POS_TITLE, 'class')
+ if not isleft:
+ buf[sect] = buf[sect] + ' ' * int(POS_LEFT)
+ buf[sect] = buf[sect] + rrset.get_class().to_text() + "\n"
+
+ buf[sect] = buf[sect] + '%-*s' % (POS_TITLE, 'type')
+ if not isleft:
+ buf[sect] = buf[sect] + ' ' * int(POS_LEFT)
+ buf[sect] = buf[sect] + rrset.get_type().to_text() + "\n"
+
+ buf[sect] = buf[sect] + '%-*s' % (POS_TITLE, 'rdata')
+
+ i = 0
+ rdata = rrset.get_rdata()
+ for item in rdata:
+ if i > 0:
+ buf[sect] = buf[sect] + ' ' * POS_TITLE
+ if not isleft:
+ buf[sect] = buf[sect] + ' ' * POS_LEFT
+ buf[sect] = buf[sect] + item.to_text() + "\n"
+ i = i + 1
+
+ buf[sect] = buf[sect] + "\n"
+
+def array_cmp(sectname, buf, rlist1, rlist2):
+ """ Compare each entry of the question section of rlist1 and rlist2.
+ Compare each RRset of the sectname section (can be answer, authority,
+ additional) of rlist1 and rlist2.
+
+ @param buf: store the formatted output of difference
+ @type: dict
+ """
+
+ diff_flag = True
+ while len(rlist1) > 0:
+ rr1 = rlist1.pop()
+ find2 = False
+ for rr2 in rlist2:
+ if sectname == 'question':
+ res = question_cmp(rr1, rr2)
+ else:
+ res = rr_cmp(rr1, rr2)
+ if res:
+ find2 = True
+ rlist2.remove(rr2)
+ break
+ if not find2:
+ output(sectname, buf, rr1, True)
+ diff_flag = False
+
+ while len(rlist2) > 0:
+ rr2 = rlist2.pop()
+ output(sectname, buf, rr2, False)
+ diff_flag = False
+ return(diff_flag)
+
+def question_cmp(rra, rrb):
+ if rra.get_name() != rrb.get_name(): return(False)
+ if rra.get_class() != rrb.get_class(): return(False)
+ if rra.get_type() != rrb.get_type(): return(False)
+ return(True)
+
+def rr_cmp(rra, rrb):
+ """ Compare two rrsets: rra and rrb """
+
+ if rra.get_name() != rrb.get_name(): return(False)
+ if rra.get_class() != rrb.get_class(): return(False)
+ if rra.get_type() != rrb.get_type(): return(False)
+ if rra.get_ttl() != rrb.get_ttl(): return(False)
+ rdata_a = rra.get_rdata()
+ rdata_b = rrb.get_rdata()
+ rdata_al = len(rdata_a)
+ rdata_bl = len(rdata_b)
+
+ if rdata_al != rdata_bl:
+ return(False)
+
+ cmp_flag = False
+ # Iterate rdata in rrset a, find if there is same rdata in rrset b
+ for ra in rdata_a:
+ for rb in rdata_b:
+ if ra.to_text() == rb.to_text():
+ cmp_flag = True
+ rdata_b.remove(rb)
+ break
+ if not cmp_flag:
+ break
+ return(cmp_flag)
+
+def resp_casecmp(msg1, msg2, num):
+ """ Compare two response message, and print the different part
+ in formatted report.
+
+ @param msg1: 1st response message
+ @type msg1: Message
+ @param msg2: 2nd response message
+ @type msg2: Message
+ @param num: the id of the query case in the 1st column of the input file.
+ Used by output report to locate the specified query case.
+ @type num: int
+ """
+
+ diff = {}
+ buf = {}
+
+ query = msg1.get_question()[0]
+
+ res_hdr = header_cmp(buf, msg1, msg2, diff)
+ res_ques = array_cmp('question', buf, \
+ msg1.get_question(), msg2.get_question())
+ res_ans = array_cmp('answer', buf, \
+ msg1.get_section(Message.SECTION_ANSWER), \
+ msg2.get_section(Message.SECTION_ANSWER))
+ res_auth = array_cmp('authority', buf, \
+ msg1.get_section(Message.SECTION_AUTHORITY), \
+ msg2.get_section(Message.SECTION_AUTHORITY))
+ res_addi = array_cmp('additional', buf, \
+ msg1.get_section(Message.SECTION_ADDITIONAL), \
+ msg2.get_section(Message.SECTION_ADDITIONAL))
+
+ # If there are any differnt comparisons in the sections above, print the details
+ # contained in buf formattedly.
+ if not res_hdr or not res_ques or not res_ans or not res_auth or not res_addi:
+ print('=' * 30, ' BEGIN QUERY %s ' % num, '=' * 30, sep='')
+ print('%-*s%-*s%-*s' % (POS_TITLE, '', int(POS_LEFT), 'SERVER1', \
+ POS_TOTAL - POS_TITLE, 'SERVER2'))
+ print('-' * 80)
+ print('Query: ', query.to_text(), sep='')
+ print('-' * 80)
+
+ if not res_hdr:
+ print(buf['header'])
+ print('-' * 80)
+
+ if not res_ques:
+ print("QUESTION")
+ print('-' * 80)
+ print(buf['question'])
+
+ if not res_ans:
+ print("ANSWER")
+ print('-' * 80)
+ print(buf['answer'])
+
+ if not res_auth:
+ print("AUTHORITY")
+ print('-' * 80)
+ print(buf['authority'])
+
+ if not res_addi:
+ print("ADDITIONAL")
+ print('-' * 80)
+ print(buf['additional'])
+
+ print('=' * 30, ' END QUERY %s ' % num, '=' * 30, sep='')
+ print("\n\n")
+
+ return False
+
+ return True
+
diff --git a/tools/query_cmp/src/lib/handledns.py b/tools/query_cmp/src/lib/handledns.py
new file mode 100755
index 0000000..e33ce9e
--- /dev/null
+++ b/tools/query_cmp/src/lib/handledns.py
@@ -0,0 +1,284 @@
+#!/usr/bin/python3
+
+# Copyright (C) 2011 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.
+
+import errno
+import sys
+import select
+import socket
+import struct
+import time
+
+from pydnspp import *
+
+RECV_BUFSIZE = 65536
+
+def _wait_for(ir, iw, ix, expiration):
+ done = False
+ while not done:
+ if expiration is None:
+ timeout = None
+ else:
+ timeout = expiration - time.time()
+ if timeout <= 0.0:
+ raise socket.timeout
+ try:
+ if timeout is None:
+ (r,w,x) = select.select(ir,iw,ix)
+ else:
+ (r,w,x) = select.select(ir,iw,ix,timeout)
+ except select.error as e:
+ if e.args[0] != errno.EINTR:
+ raise e
+ else:
+ done = True
+ if len(r) == 0 and len(w) == 0 and len(x) == 0:
+ raise socket.timeout
+
+def _wait_for_readable(s,expiration):
+ _wait_for([s],[],[s],expiration)
+
+def _compute_expiration(timeout):
+ if timeout is None:
+ return None
+ else:
+ return time.time() + timeout
+
+def _send_udp(q, where, timeout=None, port=53, source=None, source_port=0):
+ """ Return the response obtained after sending a query via UDP.
+ Refered to dnspython source code. """
+
+ qwire = MessageRenderer()
+ q.to_wire(qwire)
+ if source is not None:
+ source = (source, source_port)
+
+ udpCliSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
+
+ expiration = _compute_expiration(timeout)
+ if source is not None:
+ udpCliSock.bind(source)
+
+ dest = (where, port)
+ udpCliSock.sendto(qwire.get_data(), dest)
+
+ while True:
+ _wait_for_readable(udpCliSock, expiration)
+ rwire, r_addr = udpCliSock.recvfrom(RECV_BUFSIZE)
+ if dest[0] == r_addr[0] and dest[1:] == r_addr[1:]:
+ break
+ else:
+ sys.stderr.write('Got a respose from: %s instead of %s\n' % (r_addr, dest))
+
+ udpCliSock.close()
+
+ resp = Message(Message.PARSE)
+ resp.from_wire(rwire)
+
+ return resp
+
+def _connect(s, address):
+ try:
+ s.connect(address)
+ except socket.error as msg:
+ (exctype,value) = sys.exc_info()[:2]
+ if value.errno != errno.EINPROGRESS and \
+ value.errno != errno.EWOULDBLOCK and \
+ value.errno != errno.EALREADY:
+ raise value
+
+def _net_read(sock, count, expiration):
+ """ Read the specified number of bytes from sock. Keep trying until we
+ either get the desired amount, or we hit EOF.
+ A Timeout exception will be raised if the operation is not completed
+ by the expiration time.
+ """
+
+ msgdata = b''
+ while count > 0:
+ _wait_for_readable(sock, expiration)
+ data = sock.recv(count)
+ if not data:
+ return None
+
+ count -= len(data)
+ msgdata += data
+
+ return msgdata
+
+def _net_write(sock, data, expiration):
+ """ Write the specified data to the socket.
+ A Timeout exception will be raised if the operation is not completed
+ by the expiration time.
+ """
+ current = 0
+ l = len(data)
+ while current < 1:
+ _wait_for_writable(sock, expiration)
+ current += sock.send(data[current:])
+
+def _send_tcp(q, dest, timeout=None, dest_port=53, source=None, source_port=0):
+ """ Return the response obtained after sending a query via TCP.
+ Refered to dnspython source code """
+
+ qwire = MessageRenderer()
+ q.to_wire(qwire)
+
+ if source is not None:
+ source = (source, source_port)
+ dest = (dest, dest_port)
+ tcpCliSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
+
+ expiration = _compute_expiration(timeout)
+ tcpCliSock.setblocking(False)
+ if source is not None:
+ tcpCliSock.bind(source)
+ _connect(tcpCliSock, dest)
+
+ wire_s = qwire.get_data()
+ l = len(wire_s)
+
+ tcpmsg = struct.pack("!H", l) + wire_s
+ _net_write(tcpCliSock, tcpmsg, expiration)
+ ldata = _net_read(tcpCliSock, 2, expiration)
+ (l,) = struct.unpack("!H", ldata)
+ res_wire = _net_read(tcpCliSock, l, expiration)
+ tcpCliSock.close()
+
+ resp = Message(Message.PARSE)
+ resp.from_wire(res_wire)
+
+ return resp
+
+def send_req(query, server, port=53, timeout=5):
+ """ Return the response message obtained after
+ sending the query.
+
+ @param query: the query readed from input file
+ @type query: dict
+ @param server: the testee server ip address
+ @type server: string
+ @param port: the testee server listening port. The default is 53.
+ @type port: int
+ @param timeout: the number of seconds to wait before the query times out.
+ The default is 5.
+ @type timeout: float
+ """
+
+ qname = query["qname"]
+ qtype = query["qtype"]
+ qclass = query["qclass"]
+ edns = query["edns"]
+ dnssec = query["dnssec"]
+ qheader = query['header']
+ protocol = query['protocol']
+
+ msg = Message(Message.RENDER)
+ msg.set_qid(int(qheader['id']))
+ msg.set_opcode(Opcode.QUERY())
+ msg.set_rcode(Rcode(int(qheader['rcode'])))
+
+ if qheader['qr'] == 1:
+ msg.set_header_flag(Message.HEADERFLAG_QR)
+ if qheader['aa'] == 1:
+ msg.set_header_flag(Message.HEADERFLAG_AA)
+ if qheader['tc'] == 1:
+ msg.set_header_flag(Message.HEADERFLAG_TC)
+ if qheader['rd'] == 1:
+ msg.set_header_flag(Message.HEADERFLAG_RD)
+ if qheader['ra'] == 1:
+ msg.set_header_flag(Message.HEADERFLAG_RA)
+ if qheader['ad'] == 1:
+ msg.set_header_flag(Message.HEADERFLAG_AD)
+ if qheader['cd'] == 1:
+ msg.set_header_flag(Message.HEADERFLAG_CD)
+
+ try:
+ msg.add_question(Question(Name(qname), \
+ RRClass(qclass), RRType(qtype)))
+ except InvalidRRType as e:
+ sys.stderr.write('Unrecognized RR queryeter string: %s\n' % qtype)
+ return None
+
+ if edns == 1 or dnssec == 1:
+ edns_conf = EDNS()
+ payload = query['payload']
+ edns_conf.set_udp_size(payload)
+
+ if dnssec == 1:
+ edns_conf.set_dnssec_awareness(True)
+ else:
+ edns_conf.set_dnssec_awareness(False)
+
+ msg.set_edns(edns_conf)
+
+ port = int(port)
+ if protocol == 'udp':
+ resp = _send_udp(msg, server, timeout, port)
+ else:
+ resp = _send_tcp(msg, server, timeout, port)
+
+ return resp
+
+
+def main():
+ query = {}
+ query['qname'] = "A.example.com"
+ query['qtype'] = "ANY"
+ query['qclass'] = "IN"
+ query["edns"] = 1
+ query["dnssec"] = 1
+ query["protocol"] = 'tcp'
+ query["payload"] = 4096
+
+ query['header'] = {}
+ query['header']['id'] = 0
+ query['header']['qr'] = 0
+ query['header']['opcode'] = 0
+ query['header']['aa'] = 0
+ query['header']['tc'] = 0
+ query['header']['rd'] = 1
+ query['header']['ra'] = 0
+ query['header']['z'] = 0
+ query['header']['ad'] = 0
+ query['header']['cd'] = 0
+ query['header']['rcode'] = 0
+ query['header']['qdcount'] = 0
+ query['header']['ancount'] = 0
+ query['header']['nscount'] = 0
+ query['header']['arcount'] = 0
+
+ resp = send_req(query, "218.241.108.124", "4040")
+
+ if resp == None:
+ print('timeout')
+ exit(1)
+
+ print('qid -----')
+ print(resp.get_qid())
+
+ rrset = resp.get_section(Message.SECTION_ANSWER)[0]
+ print('name-----')
+ print(rrset.get_name())
+ print('type')
+ print(rrset.get_type())
+ print('class-----')
+ print(rrset.get_class())
+ print(rrset.get_ttl())
+ rdata = rrset.get_rdata()
+ print(rdata[0].to_text())
+
+if __name__ == "__main__":
+ main()
diff --git a/tools/query_cmp/src/lib/read_query.py b/tools/query_cmp/src/lib/read_query.py
new file mode 100755
index 0000000..01d64fe
--- /dev/null
+++ b/tools/query_cmp/src/lib/read_query.py
@@ -0,0 +1,93 @@
+#!/usr/bin/python3
+
+# Copyright (C) 2011 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.
+
+import re
+import sys
+
+def read_query(file, querylist):
+ fh = open(file)
+ while True:
+ query = {}
+ query['header'] = {}
+
+ line = fh.readline()
+ if not line: break
+ line = line.rstrip('\n')
+
+ if re.search('^#', line): continue
+ if re.search('^\s*$', line): continue
+
+ fields = line.split(' ')
+ query['header']['id'] = fields.pop(0)
+ query['header']['qr'] = fields.pop(0)
+ query['header']['opcode'] = int(fields.pop(0))
+ query['header']['aa'] = fields.pop(0)
+ query['header']['tc'] = fields.pop(0)
+ query['header']['rd'] = fields.pop(0)
+ query['header']['ra'] = fields.pop(0)
+ query['header']['z'] = fields.pop(0)
+ query['header']['ad'] = fields.pop(0)
+ query['header']['cd'] = fields.pop(0)
+ query['header']['rcode'] = fields.pop(0)
+ query['header']['qdcount'] = fields.pop(0)
+ query['header']['ancount'] = fields.pop(0)
+ query['header']['nscount'] = fields.pop(0)
+ query['header']['arcount'] = fields.pop(0)
+
+ if query['header']['opcode'] == 0:
+ get_qtuple(query, 'question', fields)
+
+ querylist.append(query)
+
+ fh.close()
+
+def get_qtuple(query, sectname, list):
+ if sectname == 'question':
+ count = int(query['header']['qdcount'])
+ item = {}
+ i = 0
+ while i < count:
+ query[sectname] = []
+ item['qname'] = list.pop(0)
+ item['qtype'] = list.pop(0)
+ item['qclass'] = list.pop(0)
+ query[sectname].append(item)
+ i += 1
+
+def print_query(querylist):
+ keylist = ['id', 'qr', 'opcode', 'aa', 'tc', 'rd', 'ra', 'z',
+ 'ad', 'cd', 'rcode', 'qdcount', 'ancount', 'nscount',
+ 'arcount']
+ for q in querylist:
+ for key in keylist:
+ print(q['header'][key], ' ')
+ print_question(q)
+
+def print_question(query):
+ i = 0
+
+ while i < len(query['question']):
+ print(query['question'][i]['qname'], \
+ query['question'][i]['qtype'], \
+ query['question'][i]['qclass'], \
+ sep=' ')
+ i += 1
+
+if __name__ == '__main__':
+ qlist = []
+ read_query(sys.argv[1], qlist)
+ print_query(qlist)
+
diff --git a/tools/query_cmp/src/query_two_server.py b/tools/query_cmp/src/query_two_server.py
new file mode 100755
index 0000000..13e234a
--- /dev/null
+++ b/tools/query_cmp/src/query_two_server.py
@@ -0,0 +1,102 @@
+#!/usr/bin/python3
+
+# Copyright (C) 2011 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.
+
+import sys; sys.path.append('lib')
+from optparse import OptionParser
+
+from read_query import *
+import handledns
+import compare_rrset
+
+def getopt():
+ """
+ get options from user.
+ """
+ usage = "usage: %prog -f <file> -s <svr1> [-p <port1>] -t <svr2> [-q <port2>] [-e] [-u] [--bufsize] [--edns]"
+ parser = OptionParser(usage)
+ parser.add_option("-f", "--file", dest="filename",
+ help="specify the input data filename")
+ parser.add_option("-s", "--svr1", dest="server1",
+ help="specify the tested DNS server 1")
+ parser.add_option("-p",
+ help="specify the port of the tested DNS server 1, default is 53")
+ parser.add_option("-t", "--svr2", dest="server2",
+ help="specify the tested DNS server 2")
+ parser.add_option("-q",
+ help="specify the port of the tested DNS server 2, default is 53")
+ parser.add_option("-e", "--dnssec", action="store_true",
+ default=False, help="turn on dnssec")
+ parser.add_option("", "--edns", action="store_true",
+ default=False, help="turn on edns, if -e is set, --edns will lapse, it must be True")
+ parser.add_option("-u", "--udp", action="store_true", default=False,
+ help="if set, query by udp, otherwise by tcp, default is unset")
+ parser.add_option("", "--bufsize", default=4096,
+ help="if --edns is set, --bufsize specifies payload of edns0, default is 4096")
+
+
+ (options, args) = parser.parse_args()
+
+ if(options.filename == None or options.server1 == None or
+ options.server2 == None):
+ parser.print_help()
+ sys.exit(1)
+
+ return options
+
+def main():
+ opts = getopt()
+
+ qlist = []
+ read_query(opts.filename, qlist)
+
+ for q in qlist:
+ # initial query
+ query = {}
+ if opts.dnssec:
+ query['edns'] = 1
+ query['dnssec'] = 1
+ elif opts.edns:
+ query['edns'] = 1
+ query['dnssec'] = 0
+ else:
+ query['edns'] = 0
+ query['dnssec'] = 0
+
+ if opts.udp:
+ query['protocol'] = 'udp'
+ else:
+ query['protocol'] = 'tcp'
+
+ query['payload'] = opts.bufsize
+ query['qname'] = q['question'][0]['qname']
+ query['qtype'] = q['question'][0]['qtype']
+ query['qclass'] = q['question'][0]['qclass']
+ query['header'] = q['header']
+ id = q['header']['id']
+
+ # send the query to the 1st and 2nd server, and store the
+ # response in res1 and res2
+ res1 = handledns.send_req(query, opts.server1, opts.p)
+ res2 = handledns.send_req(query, opts.server2, opts.q)
+
+ if res1 != None and res2 != None:
+ # compare res1 and res2, print the different part.
+ res3 = compare_rrset.resp_casecmp(res1, res2, id)
+ else:
+ sys.stderr.write('Empty response.\n')
+
+if __name__ == "__main__":
+ main()
diff --git a/tools/query_cmp/zonefile/example.com.txt b/tools/query_cmp/zonefile/example.com.txt
new file mode 100644
index 0000000..5154014
--- /dev/null
+++ b/tools/query_cmp/zonefile/example.com.txt
@@ -0,0 +1,1298 @@
+$TTL 86400
+@ IN SOA NS1.example.com. root.example.com. (
+ 2010091701 ; serial
+ 3600 ; refresh
+ 900 ; retry
+ 604800 ; expire
+ 3600 ; minimum
+ )
+ IN NS NS1.example.com.
+ IN NS NS2.demo.example.com.
+ IN NS NS3.noexist.cn.
+
+NS1 IN A 218.241.111.236
+NS2.demo IN A 218.241.108.15
+
+$ORIGIN example.com.
+minittl 100 IN A 10.10.1.1
+
+a IN A 192.168.1.10
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN A 192.168.1.10
+
+subdomain IN NS ns1.mysub.com.
+subdomain IN NS ns2.mysub.com.
+
+subdn IN NS ns.subdn.cn.
+
+NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA NS ns1.NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ns1.NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 192.168.2.1
+
+NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE NS ns1.NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+ns1.NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE A 192.168.2.2
+N.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M IN NS ns1.N.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M
+ns1.N.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M IN A 192.168.2.3
+
+C IN CNAME A
+C0 IN CNAME C1
+C1 IN CNAME C2
+C2 IN CNAME C3
+C3 IN CNAME C4
+C4 IN CNAME C5
+C5 IN CNAME C6
+C6 IN CNAME C7
+C7 IN CNAME C8
+C8 IN CNAME C9
+C9 IN CNAME C10
+C10 IN CNAME C11
+C11 IN CNAME C12
+C12 IN CNAME C13
+C13 IN CNAME C14
+C14 IN CNAME C15
+C15 IN CNAME C16
+C16 IN CNAME C17
+C17 IN CNAME C18
+C18 IN CNAME C19
+C19 IN CNAME C20
+C20 IN CNAME C21
+C21 IN CNAME C22
+C22 IN CNAME C23
+C23 IN CNAME C24
+C24 IN CNAME C25
+
+C30 IN CNAME C31
+C31 IN CNAME C32
+C32 IN CNAME C33
+C33 IN CNAME C34
+C34 IN CNAME C35
+C35 IN CNAME C36
+C36 IN CNAME C37
+C37 IN CNAME C38
+C38 IN CNAME C39
+C39 IN CNAME C40
+C40 IN CNAME C41
+C41 IN CNAME C42
+C42 IN CNAME C43
+C43 IN CNAME C44
+C44 IN CNAME C45
+C45 IN CNAME C46
+C46 IN CNAME C47
+C47 IN CNAME C48
+C48 IN CNAME C49
+C49 IN CNAME C50
+C50 IN CNAME C51
+C51 IN CNAME A
+
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA CNAME AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+
+A2 IN A 192.168.1.12
+B1 IN CNAME A2
+
+a IN PTR 1.1.226.159.cnnic.cn.
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN PTR 2.1.226.159.cnnic.cn.
+multiple-type-ptr-record IN PTR 192.168.2.1
+multiple-type-ptr-record IN PTR 192.168.2.2
+multiple-type-ptr-record IN PTR 192.168.2.3
+multiple-type-ptr-record IN PTR 192.168.2.4
+multiple-type-ptr-record IN PTR 192.168.2.5
+multiple-type-ptr-record IN PTR 192.168.2.6
+multiple-type-ptr-record IN PTR 192.168.2.7
+multiple-type-ptr-record IN PTR 192.168.2.8
+multiple-type-ptr-record IN PTR 192.168.2.9
+multiple-type-ptr-record IN PTR 192.168.2.10
+multiple-type-ptr-record IN PTR 192.168.2.11
+multiple-type-ptr-record IN PTR 192.168.2.12
+multiple-type-ptr-record IN PTR 192.168.2.13
+multiple-type-ptr-record IN PTR 192.168.2.14
+multiple-type-ptr-record IN PTR 192.168.2.15
+multiple-type-ptr-record IN PTR 192.168.2.16
+multiple-type-ptr-record IN PTR 192.168.2.17
+multiple-type-ptr-record IN PTR 192.168.2.18
+
+A IN MX 10 mail
+mail IN A 10.4.0.1
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN MX 1 mail1
+
+multiple-type-mx-record IN MX 10 mail1
+multiple-type-mx-record IN MX 10 mail2
+multiple-type-mx-record IN MX 10 mail3
+multiple-type-mx-record IN MX 10 mail4
+multiple-type-mx-record IN MX 10 mail5
+multiple-type-mx-record IN MX 10 mail6
+multiple-type-mx-record IN MX 10 mail7
+multiple-type-mx-record IN MX 10 mail8
+multiple-type-mx-record IN MX 10 mail9
+multiple-type-mx-record IN MX 10 mail10
+multiple-type-mx-record IN MX 10 mail11
+multiple-type-mx-record IN MX 10 mail12
+multiple-type-mx-record IN MX 20 mail13
+multiple-type-mx-record IN MX 30 mail14
+multiple-type-mx-record IN MX 40 mail15
+multiple-type-mx-record IN MX 50 mail16
+multiple-type-mx-record IN MX 60 mail17
+multiple-type-mx-record IN MX 70 mail18
+multiple-type-mx-record IN MX 80 mail19
+multiple-type-mx-record IN MX 90 mail20
+mail1 IN A 10.4.1.1
+mail2 IN A 10.4.1.2
+mail3 IN A 10.4.1.3
+mail4 IN A 10.4.1.4
+mail5 IN A 10.4.1.5
+mail6 IN A 10.4.1.6
+mail7 IN A 10.4.1.7
+mail8 IN A 10.4.1.8
+mail9 IN A 10.4.1.9
+mail10 IN A 10.4.1.10
+mail11 IN A 10.4.1.11
+mail12 IN A 10.4.1.12
+mail13 IN A 10.4.1.13
+mail14 IN A 10.4.1.14
+mail15 IN A 10.4.1.15
+mail16 IN A 10.4.1.16
+mail17 IN A 10.4.1.17
+mail18 IN A 10.4.1.18
+mail19 IN A 10.4.1.19
+mail20 IN A 10.4.1.20
+
+
+A IN TXT "ms-dos 3.0/6.0 ?" "google-app_,;!@#$%^&*()[]{}=+|\`~'<>,."
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN TXT "kkkkkkkkkkkkkkkkkkkkkkkk"
+
+multiple-type-txt-record IN TXT txt::1
+multiple-type-txt-record IN TXT txt::2
+multiple-type-txt-record IN TXT txt::3
+multiple-type-txt-record IN TXT txt::4
+multiple-type-txt-record IN TXT txt::5
+multiple-type-txt-record IN TXT txt::6
+multiple-type-txt-record IN TXT txt::7
+multiple-type-txt-record IN TXT txt::8
+multiple-type-txt-record IN TXT txt::9
+multiple-type-txt-record IN TXT txt::10
+multiple-type-txt-record IN TXT txt::11
+multiple-type-txt-record IN TXT txt::12
+multiple-type-txt-record IN TXT txt::13
+multiple-type-txt-record IN TXT txt::14
+multiple-type-txt-record IN TXT txt::15
+multiple-type-txt-record IN TXT txt::16
+multiple-type-txt-record IN TXT txt::17
+multiple-type-txt-record IN TXT txt::18
+multiple-type-txt-record IN TXT txt::19
+multiple-type-txt-record IN TXT txt::20
+multiple-type-txt-record IN TXT txt::21
+multiple-type-txt-record IN TXT txt::22
+multiple-type-txt-record IN TXT txt::23
+multiple-type-txt-record IN TXT txt::24
+multiple-type-txt-record IN TXT txt::25
+multiple-type-txt-record IN TXT txt::26
+multiple-type-txt-record IN TXT txt::27
+multiple-type-txt-record IN TXT txt::28
+multiple-type-txt-record IN TXT txt::29
+multiple-type-txt-record IN TXT txt::30
+multiple-type-txt-record IN TXT txt::31
+
+
+A IN AAAA 2001:dc7::1
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN AAAA 2001:dc7::2
+multiple-type-aaaa-record IN AAAA aaaa::1
+multiple-type-aaaa-record IN AAAA aaaa::2
+multiple-type-aaaa-record IN AAAA aaaa::3
+multiple-type-aaaa-record IN AAAA aaaa::4
+multiple-type-aaaa-record IN AAAA aaaa::5
+multiple-type-aaaa-record IN AAAA aaaa::6
+multiple-type-aaaa-record IN AAAA aaaa::7
+multiple-type-aaaa-record IN AAAA aaaa::8
+multiple-type-aaaa-record IN AAAA aaaa::9
+multiple-type-aaaa-record IN AAAA aaaa::10
+multiple-type-aaaa-record IN AAAA aaaa::11
+multiple-type-aaaa-record IN AAAA aaaa::12
+multiple-type-aaaa-record IN AAAA aaaa::13
+multiple-type-aaaa-record IN AAAA aaaa::14
+multiple-type-aaaa-record IN AAAA aaaa::15
+multiple-type-aaaa-record IN AAAA aaaa::16
+multiple-type-aaaa-record IN AAAA aaaa::17
+multiple-type-aaaa-record IN AAAA aaaa::18
+multiple-type-aaaa-record IN AAAA aaaa::19
+multiple-type-aaaa-record IN AAAA aaaa::20
+multiple-type-aaaa-record IN AAAA aaaa::21
+multiple-type-aaaa-record IN AAAA aaaa::22
+multiple-type-aaaa-record IN AAAA aaaa::23
+multiple-type-aaaa-record IN AAAA aaaa::24
+multiple-type-aaaa-record IN AAAA aaaa::25
+multiple-type-aaaa-record IN AAAA aaaa::26
+multiple-type-aaaa-record IN AAAA aaaa::27
+multiple-type-aaaa-record IN AAAA aaaa::28
+multiple-type-aaaa-record IN AAAA aaaa::29
+multiple-type-aaaa-record IN AAAA aaaa::30
+multiple-type-aaaa-record IN AAAA aaaa::31
+
+A IN NAPTR 18 35 "Au" "siip+E2000U" "!^.*$!simmmp:information at cnnic.cn!" mb
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN NAPTR 18 35 "Au" "siip+E2001U" "!^.*$!simmmp:information at cnnic.cn!" .
+
+sub IN ns ns.sub
+ns.sub IN A 218.241.111.236
+sub-cname IN CNAME www.sub
+sub-dname IN DNAME sub
+
+www.a.b.sub2 IN A 192.168.1.1
+
+A IN DNAME sub1.cnnic.cn.
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN DNAME sub2.cnnic.cn.
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE IN DNAME sub3.cnnic.cn.
+
+d0 IN DNAME sub
+d1 IN DNAME sub2
+test.d0 IN A 192.168.1.2
+test.d1 IN A 192.168.1.3
+d0 IN A 192.168.1.4
+d1 IN A 192.168.1.5
+
+d2 IN DNAME d3
+d3 IN DNAME d2
+
+d4 IN DNAME d5
+d5 IN CNAME d4
+www.d5 IN A 192.168.1.6
+
+d10 IN DNAME d11
+d11 IN DNAME d12
+d12 IN DNAME d13
+d13 IN DNAME d14
+d14 IN DNAME d15
+d15 IN DNAME d16
+d16 IN DNAME d17
+d17 IN DNAME d18
+d18 IN DNAME d19
+d19 IN DNAME d20
+d20 IN DNAME d21
+d21 IN DNAME d22
+d22 IN DNAME d23
+d23 IN DNAME d24
+d24 IN DNAME d25
+d25 IN DNAME d26
+d26 IN DNAME d27
+d27 IN DNAME d28
+d28 IN DNAME d29
+d29 IN DNAME d30
+d30 IN DNAME d31
+d31 IN DNAME d32
+d32 IN DNAME d33
+d33 IN DNAME d34
+d34 IN DNAME d35
+d35 IN DNAME d36
+d36 IN DNAME d37
+d37 IN DNAME d38
+d38 IN DNAME d39
+d39 IN DNAME d40
+www.d40 IN CNAME www.d41
+d41 IN DNAME d42
+d42 IN DNAME d43
+d43 IN DNAME d44
+d44 IN DNAME d45
+d45 IN DNAME d46
+d46 IN DNAME d47
+d47 IN DNAME d48
+d48 IN DNAME d49
+d49 IN DNAME d50
+d50 IN DNAME d51
+d51 IN DNAME d52
+d52 IN DNAME d53
+d53 IN DNAME d54
+d54 IN DNAME d55
+d55 IN DNAME d56
+d56 IN DNAME d57
+d57 IN DNAME d58
+d58 IN DNAME d59
+d59 IN DNAME d60
+
+d70 IN DNAME dicarl.cnnic.cn.
+
+d72 IN DNAME sub01.d72
+;sub01 IN DNAME sub02.d72
+
+cname-point-to-multiple-type-a-record IN CNAME multiple-type-a-record
+multiple-type-a-record IN A 192.168.2.1
+multiple-type-a-record IN A 192.168.2.2
+multiple-type-a-record IN A 192.168.2.3
+multiple-type-a-record IN A 192.168.2.4
+multiple-type-a-record IN A 192.168.2.5
+multiple-type-a-record IN A 192.168.2.6
+multiple-type-a-record IN A 192.168.2.7
+multiple-type-a-record IN A 192.168.2.8
+multiple-type-a-record IN A 192.168.2.9
+multiple-type-a-record IN A 192.168.2.10
+multiple-type-a-record IN A 192.168.2.11
+multiple-type-a-record IN A 192.168.2.12
+multiple-type-a-record IN A 192.168.2.13
+multiple-type-a-record IN A 192.168.2.14
+multiple-type-a-record IN A 192.168.2.15
+multiple-type-a-record IN A 192.168.2.16
+multiple-type-a-record IN A 192.168.2.17
+multiple-type-a-record IN A 192.168.2.18
+multiple-type-a-record IN A 192.168.2.19
+multiple-type-a-record IN A 192.168.2.20
+multiple-type-a-record IN A 192.168.2.21
+multiple-type-a-record IN A 192.168.2.22
+multiple-type-a-record IN A 192.168.2.23
+multiple-type-a-record IN A 192.168.2.24
+multiple-type-a-record IN A 192.168.2.25
+multiple-type-a-record IN A 192.168.2.26
+multiple-type-a-record IN A 192.168.2.27
+multiple-type-a-record IN A 192.168.2.28
+multiple-type-a-record IN A 192.168.2.29
+multiple-type-a-record IN A 192.168.2.30
+multiple-type-a-record IN A 192.168.2.31
+
+multiple-type-ns-record IN NS dns1.multiple-type-ns-record
+multiple-type-ns-record IN NS dns2.multiple-type-ns-record
+multiple-type-ns-record IN NS dns3.multiple-type-ns-record
+multiple-type-ns-record IN NS dns4.multiple-type-ns-record
+multiple-type-ns-record IN NS dns5.multiple-type-ns-record
+multiple-type-ns-record IN NS dns6.multiple-type-ns-record
+multiple-type-ns-record IN NS dns7.multiple-type-ns-record
+multiple-type-ns-record IN NS dns8.multiple-type-ns-record
+multiple-type-ns-record IN NS dns9.multiple-type-ns-record
+multiple-type-ns-record IN NS dns10.multiple-type-ns-record
+multiple-type-ns-record IN NS dns11.multiple-type-ns-record
+multiple-type-ns-record IN NS dns12.multiple-type-ns-record
+multiple-type-ns-record IN NS dns13.multiple-type-ns-record
+multiple-type-ns-record IN NS dns14.multiple-type-ns-record
+multiple-type-ns-record IN NS dns15.multiple-type-ns-record
+multiple-type-ns-record IN NS dns16.multiple-type-ns-record
+multiple-type-ns-record IN NS dns17.multiple-type-ns-record
+multiple-type-ns-record IN NS dns18.multiple-type-ns-record
+multiple-type-ns-record IN NS dns19.multiple-type-ns-record
+multiple-type-ns-record IN NS dns20.multiple-type-ns-record
+multiple-type-ns-record IN NS dns21.multiple-type-ns-record
+multiple-type-ns-record IN NS dns22.multiple-type-ns-record
+multiple-type-ns-record IN NS dns23.multiple-type-ns-record
+multiple-type-ns-record IN NS dns24.multiple-type-ns-record
+dns1.multiple-type-ns-record IN A 192.168.4.1
+dns2.multiple-type-ns-record IN A 192.168.4.2
+dns3.multiple-type-ns-record IN A 192.168.4.3
+dns4.multiple-type-ns-record IN A 192.168.4.4
+dns5.multiple-type-ns-record IN A 192.168.4.5
+dns6.multiple-type-ns-record IN A 192.168.4.6
+dns7.multiple-type-ns-record IN A 192.168.4.7
+dns8.multiple-type-ns-record IN A 192.168.4.8
+dns9.multiple-type-ns-record IN A 192.168.4.9
+dns10.multiple-type-ns-record IN A 192.168.4.10
+dns11.multiple-type-ns-record IN A 192.168.4.11
+dns12.multiple-type-ns-record IN A 192.168.4.12
+dns13.multiple-type-ns-record IN A 192.168.4.13
+dns14.multiple-type-ns-record IN A 192.168.4.14
+dns15.multiple-type-ns-record IN A 192.168.4.15
+dns16.multiple-type-ns-record IN A 192.168.4.16
+dns17.multiple-type-ns-record IN A 192.168.4.17
+dns18.multiple-type-ns-record IN A 192.168.4.18
+dns19.multiple-type-ns-record IN A 192.168.4.19
+dns20.multiple-type-ns-record IN A 192.168.4.20
+dns21.multiple-type-ns-record IN A 192.168.4.21
+dns22.multiple-type-ns-record IN A 192.168.4.22
+dns23.multiple-type-ns-record IN A 192.168.4.23
+dns24.multiple-type-ns-record IN A 192.168.4.24
+dns25.multiple-type-ns-record IN A 192.168.4.25
+
+;demo IN NS ns1
+
+a IN WKS 218.241.108.4 TCP (telnet smtp domain)
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN WKS 218.241.108.5 TCP (telnet smtp domain)
+
+multiple-type-wks-record IN WKS 218.241.109.1 TCP (telnet smtp domain)
+multiple-type-wks-record IN WKS 218.241.109.2 TCP (telnet smtp domain)
+multiple-type-wks-record IN WKS 218.241.109.3 TCP (telnet smtp domain)
+multiple-type-wks-record IN WKS 218.241.109.4 TCP (telnet smtp domain)
+multiple-type-wks-record IN WKS 218.241.109.5 TCP (telnet smtp domain)
+multiple-type-wks-record IN WKS 218.241.109.6 TCP (telnet smtp domain x11)
+multiple-type-wks-record IN WKS 218.241.109.7 TCP (telnet smtp domain)
+multiple-type-wks-record IN WKS 218.241.109.8 TCP (telnet smtp domain)
+multiple-type-wks-record IN WKS 218.241.109.9 TCP (telnet smtp domain)
+multiple-type-wks-record IN WKS 218.241.109.10 TCP (telnet smtp domain)
+multiple-type-wks-record IN WKS 218.241.109.11 TCP (telnet ssh smtp domain)
+multiple-type-wks-record IN WKS 218.241.109.12 TCP (telnet ssh smtp domain)
+multiple-type-wks-record IN WKS 218.241.109.13 TCP (telnet ssh smtp domain)
+multiple-type-wks-record IN WKS 218.241.109.14 TCP (http ssh smtp domain)
+multiple-type-wks-record IN WKS 218.241.109.15 TCP (http ssh smtp domain)
+multiple-type-wks-record IN WKS 218.241.109.16 TCP (http ssh smtp x11)
+
+a IN HINFO VAX-11/780 UNIX
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN HINFO SHARP "PC-1500 1983"
+
+multiple-type-hinfo-record IN HINFO "DG MV-4000" 1990
+multiple-type-hinfo-record IN HINFO "DG MV-4001" 1990
+multiple-type-hinfo-record IN HINFO "DG MV-4002" 1990
+multiple-type-hinfo-record IN HINFO "DG MV-4003" 1990
+multiple-type-hinfo-record IN HINFO "DG MV-4004" 1990
+multiple-type-hinfo-record IN HINFO "DG MV-4005" 1990
+multiple-type-hinfo-record IN HINFO "DG MV-4006" 1990
+multiple-type-hinfo-record IN HINFO "DG MV-4007" 1990
+multiple-type-hinfo-record IN HINFO "DG MV-4008" 1990
+multiple-type-hinfo-record IN HINFO "DG MV-4009" 1990
+multiple-type-hinfo-record IN HINFO "DG MV-4010" 1990
+multiple-type-hinfo-record IN HINFO "DG MV-4011" 1990
+multiple-type-hinfo-record IN HINFO "DG MV-4012" 1990
+multiple-type-hinfo-record IN HINFO "DG MV-4013" 1990
+multiple-type-hinfo-record IN HINFO "DG MV-4014" 1990
+multiple-type-hinfo-record IN HINFO "DG MV-4015" 1990
+multiple-type-hinfo-record IN HINFO "DG MV-4016" 1990
+
+a IN MINFO root.cnnic.cn. error.cnnic.cn.
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN MINFO root63.cnnic.cn. error63.cnnic.cn.
+multiple-type-minfo-record IN MINFO sun00.abc.foo.bar.liu.zhang.han.cnnic.cn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+multiple-type-minfo-record IN MINFO sun01.abc.foo.bar.liu.zhang.han.cnnic.cn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+multiple-type-minfo-record IN MINFO sun02.abc.foo.bar.liu.zhang.han.cnnic.cn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+multiple-type-minfo-record IN MINFO sun03.abc.foo.bar.liu.zhang.han.cnnic.cn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+multiple-type-minfo-record IN MINFO sun04.abc.foo.bar.liu.zhang.han.cnnic.cn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+multiple-type-minfo-record IN MINFO sun04.abc.foo.bar.liu.zhang.han.cnnic.dn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+multiple-type-minfo-record IN MINFO sun04.abc.foo.bar.liu.zhang.han.cnnic.en. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+multiple-type-minfo-record IN MINFO sun04.abc.foo.bar.liu.zhang.han.cnnic.fn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+multiple-type-minfo-record IN MINFO sun04.abc.foo.bar.liu.zhang.han.cnnic.gn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+
+a IN NSAP 0x47000580ffff0000003210999911112222333343
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN NSAP 0x47000580ffff0000003210999911112222333344
+multiple-type-nsap-record IN NSAP 0x47000580ffff0000003210999911112222333345
+multiple-type-nsap-record IN NSAP 0x47000580ffff0000003210999911112222333346
+multiple-type-nsap-record IN NSAP 0x47000580ffff0000003210999911112222333347
+multiple-type-nsap-record IN NSAP 0x47000580ffff0000003210999911112222333348
+multiple-type-nsap-record IN NSAP 0x47000580ffff0000003210999911112222333349
+multiple-type-nsap-record IN NSAP 0x47000580ffff000000321099991111222233334A
+multiple-type-nsap-record IN NSAP 0x47000580ffff000000321099991111222233334b
+multiple-type-nsap-record IN NSAP 0x47000580ffff000000321099991111222233334C
+multiple-type-nsap-record IN NSAP 0x47000580ffff000000321099991111222233334d
+multiple-type-nsap-record IN NSAP 0x47000580ffff000000321099991111222233334E
+multiple-type-nsap-record IN NSAP 0x47000580ffff000000321099991111222233334f
+multiple-type-nsap-record IN NSAP 0x47000580ffff0000003210999911112222333350
+multiple-type-nsap-record IN NSAP 0x47000580ffff0000003210999911112222333351
+multiple-type-nsap-record IN NSAP 0x47000580ffff0000003210999911112222333352
+multiple-type-nsap-record IN NSAP 0x47000580ffff0000003210999911112222333353
+
+; zebra don't support NSAP-PTR now.
+;47000580ffff000000321099991111222233334444 IN NSAP-PTR a
+
+A IN PX 10 ab.net2.it. O-ab.PRMD-net2.ADMDb.C-it.
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN PX 10 ab.net2.it. O-ab.PRMD-net2.ADMDb.C-it.
+multiple-type-px-record IN PX 10 ab.net2.it. O-ab.PRMD-net2.ADMDb.C-it.
+multiple-type-px-record IN PX 11 ab.net3.it. 1-ab.PRMD-net2.ADMDb.C-it.
+multiple-type-px-record IN PX 12 ab.net4.it. 2-ab.PRMD-net2.ADMDb.C-it.
+multiple-type-px-record IN PX 13 ab.net5.it. 3-ab.PRMD-net2.ADMDb.C-it.
+multiple-type-px-record IN PX 14 ab.net6.it. 4-ab.PRMD-net2.ADMDb.C-it.
+multiple-type-px-record IN PX 15 ab.net7.it. 5-ab.PRMD-net2.ADMDb.C-it.
+multiple-type-px-record IN PX 16 ab.net8.it. 6-ab.PRMD-net2.ADMDb.C-it.
+multiple-type-px-record IN PX 10 ab.net9.it. 7-ab.PRMD-net2.ADMDb.C-it.
+multiple-type-px-record IN PX 10 ab.net2.it. 8-ab.PRMD-net2.ADMDb.C-it.
+multiple-type-px-record IN PX 10 ab.net2.it. 9-ab.PRMD-net2.ADMDb.C-it.
+
+A IN LOC 32 7 19 S 116 2 25 E 10m
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN LOC 32 7 19 S 116 2 25 E 10m
+multiple-type-loc-record IN LOC 32 7 19 S 116 2 25 E 10m
+multiple-type-loc-record IN LOC 33 7 19 S 117 2 25 E 11m
+multiple-type-loc-record IN LOC 34 7 19 S 118 2 25 E 12m
+multiple-type-loc-record IN LOC 35 7 19 S 119 2 25 E 13m
+multiple-type-loc-record IN LOC 36 7 19 S 120 2 25 E 14m
+multiple-type-loc-record IN LOC 37 7 19 S 121 2 25 E 15m
+multiple-type-loc-record IN LOC 38 7 19 S 122 2 25 E 16m
+multiple-type-loc-record IN LOC 39 7 19 S 123 2 25 E 17m
+multiple-type-loc-record IN LOC 40 7 19 S 124 2 25 E 18m
+multiple-type-loc-record IN LOC 41 7 19 S 125 2 25 E 19m
+multiple-type-loc-record IN LOC 42 7 19 S 126 2 25 E 20m
+multiple-type-loc-record IN LOC 43 7 19 S 127 2 25 E 21m
+multiple-type-loc-record IN LOC 44 7 19 S 128 2 25 E 22m
+multiple-type-loc-record IN LOC 45 7 19 S 129 2 25 E 23m
+multiple-type-loc-record IN LOC 46 7 19 S 130 2 25 E 24m
+multiple-type-loc-record IN LOC 47 7 19 S 131 2 25 E 25m
+multiple-type-loc-record IN LOC 89 59 59.999 S 179 59 59.999 E 1000000m 1000m 1000m
+multiple-type-loc-record IN LOC 90 S 180 E 0.01 0.01 0.01
+
+_http._tcp.a IN SRV 0 2 80 www.movie.edu.
+a IN SRV 0 2 80 www.movie.edu.
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN SRV 0 2 80 www.movie.edu.
+multiple-type-srv-record IN SRV 0 2 80 www.movie0.edu.
+multiple-type-srv-record IN SRV 1 3 80 www.movie1.edu.
+multiple-type-srv-record IN SRV 2 4 80 www.movie2.edu.
+multiple-type-srv-record IN SRV 3 5 80 www.movie3.edu.
+multiple-type-srv-record IN SRV 4 6 80 www.movie4.edu.
+multiple-type-srv-record IN SRV 5 7 80 www.movie5.edu.
+multiple-type-srv-record IN SRV 6 8 80 www.movie6.edu.
+multiple-type-srv-record IN SRV 7 9 80 www.movie7.edu.
+multiple-type-srv-record IN SRV 8 10 80 www.movie8.edu.
+multiple-type-srv-record IN SRV 9 11 80 www.movie9.edu.
+multiple-type-srv-record IN SRV 10 12 80 www.movie10.edu.
+multiple-type-srv-record IN SRV 11 13 80 www.movie11.edu.
+multiple-type-srv-record IN SRV 12 14 80 www.movie12.edu.
+
+a IN KX 20 kaku.google.com.
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN KX 20 kaku.google.com.
+multiple-type-kx-record IN KX 0 kaku0.google.com.
+multiple-type-kx-record IN KX 10 kaku1.google.com.
+multiple-type-kx-record IN KX 20 kaku2.google.com.
+multiple-type-kx-record IN KX 30 kaku3.google.com.
+multiple-type-kx-record IN KX 40 kaku4.google.com.
+multiple-type-kx-record IN KX 50 kaku5.google.com.
+multiple-type-kx-record IN KX 60 kaku6.google.com.
+multiple-type-kx-record IN KX 70 kaku7.google.com.
+multiple-type-kx-record IN KX 80 kaku8.google.com.
+multiple-type-kx-record IN KX 90 kaku9.google.com.
+multiple-type-kx-record IN KX 100 kaku10.google.com.
+multiple-type-kx-record IN KX 110 kaku11.google.com.
+multiple-type-kx-record IN KX 120 kaku12.google.com.
+multiple-type-kx-record IN KX 130 kaku13.google.com.
+
+A IN CERT 65534 65535 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgi
+ WCn/GxHhai6VAuHAoNUz4YoU1tVfSCSqQYn6//11U6Nl
+ d80jEeC8aTrO+KKmCaY= )
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN CERT 65534 65535 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgi
+ WCn/GxHhai6VAuHAoNUz4YoU1tVfSCSqQYn6//11U6Nl
+ d80jEeC8aTrO+KKmCaY= )
+multiple-type-cert-record IN CERT 65534 65535 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgi
+ WCn/GxHhai6VAuHAoNUz4YoU1tVfSCSqQYn6//11U6Nl
+ d80jEeC8aTrO+KKmCaY= )
+multiple-type-cert-record IN CERT 65533 65534 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgi
+ WCn/GxHhai6VAuHAoNUz4YoU1tVfSCSqQYn6//11U6Nl
+ d80jEeC8aTrO+KKmCaY= )
+multiple-type-cert-record IN CERT 65532 65533 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgi
+ WCn/GxHhai6VAuHAoNUz4YoU1tVfSCSqQYn6//11U6Nl
+ d80jEeC8aTrO+KKmCaY= )
+multiple-type-cert-record IN CERT 65531 65532 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgi
+ WCn/GxHhai6VAuHAoNUz4YoU1tVfSCSqQYn6//11U6Nl
+ d80jEeC8aTrO+KKmCaY= )
+multiple-type-cert-record IN CERT 65530 65531 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgi
+ WCn/GxHhai6VAuHAoNUz4YoU1tVfSCSqQYn6//11U6Nl
+ d80jEeC8aTrO+KKmCaY= )
+
+A IN APL 1:192.168.32.0/21 !1:192.168.38.0/28
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN APL 1:192.168.32.0/21 !1:192.168.38.0/28
+multiple-type-apl-record IN APL 1:192.168.32.15/14 !1:192.168.38.0/28
+multiple-type-apl-record IN APL 1:192.168.33.15/15 !1:192.168.39.0/28
+multiple-type-apl-record IN APL 1:192.168.34.15/16 !1:192.168.40.0/28
+multiple-type-apl-record IN APL 1:192.168.35.15/17 !1:192.168.41.0/28
+multiple-type-apl-record IN APL 1:192.168.36.15/18 !1:192.168.42.0/28
+multiple-type-apl-record IN APL 1:192.168.37.15/19 !1:192.168.43.0/28
+multiple-type-apl-record IN APL 1:192.168.38.15/20 !1:192.168.44.0/28
+multiple-type-apl-record IN APL 1:192.168.39.15/21 !1:192.168.45.0/28
+multiple-type-apl-record IN APL 1:192.168.40.15/22 !1:192.168.46.0/28
+multiple-type-apl-record IN APL 1:192.168.41.15/23 !1:192.168.47.0/28
+multiple-type-apl-record IN APL 1:192.168.42.15/24 !1:192.168.48.0/28
+multiple-type-apl-record IN APL 1:192.168.43.15/25 !1:192.168.49.0/28
+multiple-type-apl-record IN APL 1:192.168.44.15/26 !1:192.168.50.0/28
+multiple-type-apl-record IN APL 1:192.168.45.15/27 !1:192.168.51.0/28
+multiple-type-apl-record IN APL 1:192.168.46.15/28 !1:192.168.52.0/28
+multiple-type-apl-record IN APL 1:192.168.47.15/29 !1:192.168.53.0/28
+multiple-type-apl-record IN APL 1:192.168.48.15/20 !1:192.168.54.0/28
+multiple-type-apl-record IN APL 1:224.0.0.0/4 2:FF00:0:0:AAAA:CCCC:BBBB:9999:5555/48
+multiple-type-apl-record IN APL 1:224.0.0.5/8 2:FF00::0/8
+multiple-type-apl-record IN APL 1:224.0.0.9/12 2:FF00::888f:0/24
+multiple-type-apl-record IN APL 1:224.0.0.13/16 2:FF00::7777/72
+
+A IN SSHFP 2 1 123456789abcdef67890123456789abcdef67890
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN SSHFP 2 1 123456789abcdef67890123456789abcdef67890
+multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef67890
+multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef67891
+multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef67892
+multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef67893
+multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef67894
+multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef67895
+multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef67896
+multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef67897
+multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef67898
+multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef67899
+multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef6789a
+multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef6789b
+multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef6789c
+
+a IN IPSECKEY ( 10 1 2
+ 192.0.2.3
+ AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN IPSECKEY ( 10 1 2
+ 192.0.2.3
+ AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+multiple-type-ipseckey-record IN IPSECKEY ( 10 1 2
+ 192.0.2.3
+ AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+multiple-type-ipseckey-record IN IPSECKEY ( 10 1 2
+ 192.0.2.4
+ BQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+multiple-type-ipseckey-record IN IPSECKEY ( 10 1 2
+ 192.0.2.5
+ CQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+multiple-type-ipseckey-record IN IPSECKEY ( 10 1 2
+ 192.0.2.6
+ DQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+multiple-type-ipseckey-record IN IPSECKEY ( 10 1 2
+ 192.0.2.7
+ EQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+multiple-type-ipseckey-record IN IPSECKEY ( 10 1 2
+ 192.0.2.8
+ FQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+multiple-type-ipseckey-record IN IPSECKEY ( 10 1 2
+ 192.0.2.9
+ GQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+multiple-type-ipseckey-record IN IPSECKEY ( 10 1 2
+ 192.0.2.10
+ HQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+multiple-type-ipseckey-record IN IPSECKEY ( 10 1 2
+ 192.0.2.11
+ IQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+
+A IN DHCID ( AAIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN DHCID ( AAIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+multiple-type-dhcid-record IN DHCID ( AAIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+multiple-type-dhcid-record IN DHCID ( BBIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+multiple-type-dhcid-record IN DHCID ( CCIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+multiple-type-dhcid-record IN DHCID ( DDIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+multiple-type-dhcid-record IN DHCID ( EEIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+multiple-type-dhcid-record IN DHCID ( FFIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+multiple-type-dhcid-record IN DHCID ( GGIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+multiple-type-dhcid-record IN DHCID ( HHIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+multiple-type-dhcid-record IN DHCID ( IIIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+multiple-type-dhcid-record IN DHCID ( JJIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+multiple-type-dhcid-record IN DHCID ( KKIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+
+A IN SPF 'sfasf'
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN SPF 'asdfghjkl;'
+multiple-type-spf-record IN SPF 'asdfghjkl;'
+multiple-type-spf-record IN SPF 'sina;'
+multiple-type-spf-record IN SPF 'cnnic;'
+multiple-type-spf-record IN SPF 'jkl;'
+multiple-type-spf-record IN SPF 'c=sina.com.'
+multiple-type-spf-record IN SPF 'fw=fff.com.cn.'
+multiple-type-spf-record IN SPF 'ibm;'
+multiple-type-spf-record IN SPF 'dell;'
+multiple-type-spf-record IN SPF 'google - microsoft;'
+multiple-type-spf-record IN SPF 'leibusi;'
+multiple-type-spf-record IN SPF "v=spf1"
+multiple-type-spf-record IN SPF "v=spf1 -all"
+multiple-type-spf-record IN SPF "v=spf1 ip4:192.168.0.1/16 -all "
+multiple-type-spf-record IN SPF "v=spf1 ip4:192.168.1.1/16 -all "
+multiple-type-spf-record IN SPF "v=spf1 ip4:192.168.2.1/16 -all "
+multiple-type-spf-record IN SPF "v=spf1 ip4:192.168.3.1/16 -all "
+multiple-type-spf-record IN SPF "v=spf1 ip4:192.168.4.1/16 -all "
+multiple-type-spf-record IN SPF "v=spf1 ip4:192.168.5.1/16 -all "
+multiple-type-spf-record IN SPF "v=spf1 ip4:192.168.6.1/16 -all "
+multiple-type-spf-record IN SPF "v=spf1 ip4:192.168.7.1/16 -all "
+
+testa.no-type IN A 10.1.1.1
+testaaaa.no-type IN AAAA ::1
+
+test.non-terminal.minittl 100 IN A 10.10.1.1
+
+test.non-terminal.a IN A 192.168.1.10
+test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN A 192.168.1.10
+
+test.non-terminal.subdomain IN NS ns1.mysub.com.
+test.non-terminal.subdomain IN NS ns2.mysub.com.
+
+test.non-terminal.subdn IN NS ns.subdn.cn.
+
+test.non-terminal.NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA NS ns1.NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+test.non-terminal.ns1.NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 192.168.2.1
+
+
+test.non-terminal.C IN CNAME A
+test.non-terminal.C0 IN CNAME C1
+test.non-terminal.C1 IN CNAME C2
+test.non-terminal.C2 IN CNAME C3
+test.non-terminal.C3 IN CNAME C4
+test.non-terminal.C4 IN CNAME C5
+test.non-terminal.C5 IN CNAME C6
+test.non-terminal.C6 IN CNAME C7
+test.non-terminal.C7 IN CNAME C8
+test.non-terminal.C8 IN CNAME C9
+test.non-terminal.C9 IN CNAME C10
+test.non-terminal.C10 IN CNAME C11
+test.non-terminal.C11 IN CNAME C12
+test.non-terminal.C12 IN CNAME C13
+test.non-terminal.C13 IN CNAME C14
+test.non-terminal.C14 IN CNAME C15
+test.non-terminal.C15 IN CNAME C16
+test.non-terminal.C16 IN CNAME C17
+test.non-terminal.C17 IN CNAME C18
+test.non-terminal.C18 IN CNAME C19
+test.non-terminal.C19 IN CNAME C20
+test.non-terminal.C20 IN CNAME C21
+test.non-terminal.C21 IN CNAME C22
+test.non-terminal.C22 IN CNAME C23
+test.non-terminal.C23 IN CNAME C24
+test.non-terminal.C24 IN CNAME C25
+
+test.non-terminal.C30 IN CNAME C31
+test.non-terminal.C31 IN CNAME C32
+test.non-terminal.C32 IN CNAME C33
+test.non-terminal.C33 IN CNAME C34
+test.non-terminal.C34 IN CNAME C35
+test.non-terminal.C35 IN CNAME C36
+test.non-terminal.C36 IN CNAME C37
+test.non-terminal.C37 IN CNAME C38
+test.non-terminal.C38 IN CNAME C39
+test.non-terminal.C39 IN CNAME C40
+test.non-terminal.C40 IN CNAME C41
+test.non-terminal.C41 IN CNAME C42
+test.non-terminal.C42 IN CNAME C43
+test.non-terminal.C43 IN CNAME C44
+test.non-terminal.C44 IN CNAME C45
+test.non-terminal.C45 IN CNAME C46
+test.non-terminal.C46 IN CNAME C47
+test.non-terminal.C47 IN CNAME C48
+test.non-terminal.C48 IN CNAME C49
+test.non-terminal.C49 IN CNAME C50
+test.non-terminal.C50 IN CNAME C51
+test.non-terminal.C51 IN CNAME A
+
+test.non-terminal.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA CNAME AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+
+test.non-terminal.A2 IN A 192.168.1.12
+test.non-terminal.B1 IN CNAME A2
+
+test.non-terminal.a IN PTR 1.1.226.159.cnnic.cn.
+test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN PTR 2.1.226.159.cnnic.cn.
+test.non-terminal.multiple-type-ptr-record IN PTR 192.168.2.1
+test.non-terminal.multiple-type-ptr-record IN PTR 192.168.2.2
+test.non-terminal.multiple-type-ptr-record IN PTR 192.168.2.3
+test.non-terminal.multiple-type-ptr-record IN PTR 192.168.2.4
+test.non-terminal.multiple-type-ptr-record IN PTR 192.168.2.5
+test.non-terminal.multiple-type-ptr-record IN PTR 192.168.2.6
+test.non-terminal.multiple-type-ptr-record IN PTR 192.168.2.7
+test.non-terminal.multiple-type-ptr-record IN PTR 192.168.2.8
+test.non-terminal.multiple-type-ptr-record IN PTR 192.168.2.9
+test.non-terminal.multiple-type-ptr-record IN PTR 192.168.2.10
+test.non-terminal.multiple-type-ptr-record IN PTR 192.168.2.11
+test.non-terminal.multiple-type-ptr-record IN PTR 192.168.2.12
+test.non-terminal.multiple-type-ptr-record IN PTR 192.168.2.13
+test.non-terminal.multiple-type-ptr-record IN PTR 192.168.2.14
+test.non-terminal.multiple-type-ptr-record IN PTR 192.168.2.15
+test.non-terminal.multiple-type-ptr-record IN PTR 192.168.2.16
+test.non-terminal.multiple-type-ptr-record IN PTR 192.168.2.17
+test.non-terminal.multiple-type-ptr-record IN PTR 192.168.2.18
+
+test.non-terminal.A IN MX 10 mail
+test.non-terminal.mail IN A 10.4.0.1
+test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN MX 1 mail1
+
+test.non-terminal.multiple-type-mx-record IN MX 10 mail1
+test.non-terminal.multiple-type-mx-record IN MX 10 mail2
+test.non-terminal.multiple-type-mx-record IN MX 10 mail3
+test.non-terminal.multiple-type-mx-record IN MX 10 mail4
+test.non-terminal.multiple-type-mx-record IN MX 10 mail5
+test.non-terminal.multiple-type-mx-record IN MX 10 mail6
+test.non-terminal.multiple-type-mx-record IN MX 10 mail7
+test.non-terminal.multiple-type-mx-record IN MX 10 mail8
+test.non-terminal.multiple-type-mx-record IN MX 10 mail9
+test.non-terminal.multiple-type-mx-record IN MX 10 mail10
+test.non-terminal.multiple-type-mx-record IN MX 10 mail11
+test.non-terminal.multiple-type-mx-record IN MX 10 mail12
+test.non-terminal.multiple-type-mx-record IN MX 20 mail13
+test.non-terminal.multiple-type-mx-record IN MX 30 mail14
+test.non-terminal.multiple-type-mx-record IN MX 40 mail15
+test.non-terminal.multiple-type-mx-record IN MX 50 mail16
+test.non-terminal.multiple-type-mx-record IN MX 60 mail17
+test.non-terminal.multiple-type-mx-record IN MX 70 mail18
+test.non-terminal.multiple-type-mx-record IN MX 80 mail19
+test.non-terminal.multiple-type-mx-record IN MX 90 mail20
+test.non-terminal.mail1 IN A 10.4.1.1
+test.non-terminal.mail2 IN A 10.4.1.2
+test.non-terminal.mail3 IN A 10.4.1.3
+test.non-terminal.mail4 IN A 10.4.1.4
+test.non-terminal.mail5 IN A 10.4.1.5
+test.non-terminal.mail6 IN A 10.4.1.6
+test.non-terminal.mail7 IN A 10.4.1.7
+test.non-terminal.mail8 IN A 10.4.1.8
+test.non-terminal.mail9 IN A 10.4.1.9
+test.non-terminal.mail10 IN A 10.4.1.10
+test.non-terminal.mail11 IN A 10.4.1.11
+test.non-terminal.mail12 IN A 10.4.1.12
+test.non-terminal.mail13 IN A 10.4.1.13
+test.non-terminal.mail14 IN A 10.4.1.14
+test.non-terminal.mail15 IN A 10.4.1.15
+test.non-terminal.mail16 IN A 10.4.1.16
+test.non-terminal.mail17 IN A 10.4.1.17
+test.non-terminal.mail18 IN A 10.4.1.18
+test.non-terminal.mail19 IN A 10.4.1.19
+test.non-terminal.mail20 IN A 10.4.1.20
+
+
+test.non-terminal.A IN TXT "ms-dos 3.0/6.0 ?" "google-app_,;!@#$%^&*()[]{}=+|\`~'<>,."
+test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN TXT "kkkkkkkkkkkkkkkkkkkkkkkk"
+
+test.non-terminal.multiple-type-txt-record IN TXT txt::1
+test.non-terminal.multiple-type-txt-record IN TXT txt::2
+test.non-terminal.multiple-type-txt-record IN TXT txt::3
+test.non-terminal.multiple-type-txt-record IN TXT txt::4
+test.non-terminal.multiple-type-txt-record IN TXT txt::5
+test.non-terminal.multiple-type-txt-record IN TXT txt::6
+test.non-terminal.multiple-type-txt-record IN TXT txt::7
+test.non-terminal.multiple-type-txt-record IN TXT txt::8
+test.non-terminal.multiple-type-txt-record IN TXT txt::9
+test.non-terminal.multiple-type-txt-record IN TXT txt::10
+test.non-terminal.multiple-type-txt-record IN TXT txt::11
+test.non-terminal.multiple-type-txt-record IN TXT txt::12
+test.non-terminal.multiple-type-txt-record IN TXT txt::13
+test.non-terminal.multiple-type-txt-record IN TXT txt::14
+test.non-terminal.multiple-type-txt-record IN TXT txt::15
+test.non-terminal.multiple-type-txt-record IN TXT txt::16
+test.non-terminal.multiple-type-txt-record IN TXT txt::17
+test.non-terminal.multiple-type-txt-record IN TXT txt::18
+test.non-terminal.multiple-type-txt-record IN TXT txt::19
+test.non-terminal.multiple-type-txt-record IN TXT txt::20
+test.non-terminal.multiple-type-txt-record IN TXT txt::21
+test.non-terminal.multiple-type-txt-record IN TXT txt::22
+test.non-terminal.multiple-type-txt-record IN TXT txt::23
+test.non-terminal.multiple-type-txt-record IN TXT txt::24
+test.non-terminal.multiple-type-txt-record IN TXT txt::25
+test.non-terminal.multiple-type-txt-record IN TXT txt::26
+test.non-terminal.multiple-type-txt-record IN TXT txt::27
+test.non-terminal.multiple-type-txt-record IN TXT txt::28
+test.non-terminal.multiple-type-txt-record IN TXT txt::29
+test.non-terminal.multiple-type-txt-record IN TXT txt::30
+test.non-terminal.multiple-type-txt-record IN TXT txt::31
+
+
+test.non-terminal.A IN AAAA 2001:dc7::1
+test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN AAAA 2001:dc7::2
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::1
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::2
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::3
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::4
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::5
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::6
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::7
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::8
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::9
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::10
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::11
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::12
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::13
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::14
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::15
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::16
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::17
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::18
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::19
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::20
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::21
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::22
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::23
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::24
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::25
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::26
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::27
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::28
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::29
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::30
+test.non-terminal.multiple-type-aaaa-record IN AAAA aaaa::31
+
+test.non-terminal.A IN NAPTR 18 35 "Au" "siip+E2000U" "!^.*$!simmmp:information at cnnic.cn!" mb
+test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN NAPTR 18 35 "Au" "siip+E2001U" "!^.*$!simmmp:information at cnnic.cn!" .
+
+test.non-terminal.sub IN ns ns.sub
+test.non-terminal.ns.sub IN A 218.241.111.236
+test.non-terminal.sub-cname IN CNAME www.sub
+test.non-terminal.sub-dname IN DNAME sub
+
+test.non-terminal.www.a.b.sub2 IN A 192.168.1.1
+
+test.non-terminal.A IN DNAME sub1.cnnic.cn.
+test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN DNAME sub2.cnnic.cn.
+
+test.non-terminal.d0 IN DNAME sub
+test.non-terminal.d1 IN DNAME sub2
+test.non-terminal.test.d0 IN A 192.168.1.2
+test.non-terminal.test.d1 IN A 192.168.1.3
+test.non-terminal.d0 IN A 192.168.1.4
+test.non-terminal.d1 IN A 192.168.1.5
+
+test.non-terminal.d2 IN DNAME d3
+test.non-terminal.d3 IN DNAME d2
+
+test.non-terminal.d4 IN DNAME d5
+test.non-terminal.d5 IN CNAME d4
+test.non-terminal.www.d5 IN A 192.168.1.6
+
+test.non-terminal.d10 IN DNAME d11
+test.non-terminal.d11 IN DNAME d12
+test.non-terminal.d12 IN DNAME d13
+test.non-terminal.d13 IN DNAME d14
+test.non-terminal.d14 IN DNAME d15
+test.non-terminal.d15 IN DNAME d16
+test.non-terminal.d16 IN DNAME d17
+test.non-terminal.d17 IN DNAME d18
+test.non-terminal.d18 IN DNAME d19
+test.non-terminal.d19 IN DNAME d20
+test.non-terminal.d20 IN DNAME d21
+test.non-terminal.d21 IN DNAME d22
+test.non-terminal.d22 IN DNAME d23
+test.non-terminal.d23 IN DNAME d24
+test.non-terminal.d24 IN DNAME d25
+test.non-terminal.d25 IN DNAME d26
+test.non-terminal.d26 IN DNAME d27
+test.non-terminal.d27 IN DNAME d28
+test.non-terminal.d28 IN DNAME d29
+test.non-terminal.d29 IN DNAME d30
+test.non-terminal.d30 IN DNAME d31
+test.non-terminal.d31 IN DNAME d32
+test.non-terminal.d32 IN DNAME d33
+test.non-terminal.d33 IN DNAME d34
+test.non-terminal.d34 IN DNAME d35
+test.non-terminal.d35 IN DNAME d36
+test.non-terminal.d36 IN DNAME d37
+test.non-terminal.d37 IN DNAME d38
+test.non-terminal.d38 IN DNAME d39
+test.non-terminal.d39 IN DNAME d40
+test.non-terminal.www.d40 IN CNAME www.d41
+test.non-terminal.d41 IN DNAME d42
+test.non-terminal.d42 IN DNAME d43
+test.non-terminal.d43 IN DNAME d44
+test.non-terminal.d44 IN DNAME d45
+test.non-terminal.d45 IN DNAME d46
+test.non-terminal.d46 IN DNAME d47
+test.non-terminal.d47 IN DNAME d48
+test.non-terminal.d48 IN DNAME d49
+test.non-terminal.d49 IN DNAME d50
+test.non-terminal.d50 IN DNAME d51
+test.non-terminal.d51 IN DNAME d52
+test.non-terminal.d52 IN DNAME d53
+test.non-terminal.d53 IN DNAME d54
+test.non-terminal.d54 IN DNAME d55
+test.non-terminal.d55 IN DNAME d56
+test.non-terminal.d56 IN DNAME d57
+test.non-terminal.d57 IN DNAME d58
+test.non-terminal.d58 IN DNAME d59
+test.non-terminal.d59 IN DNAME d60
+
+test.non-terminal.d70 IN DNAME dicarl.cnnic.cn.
+
+test.non-terminal.d72 IN DNAME sub01.d72
+
+test.non-terminal.cname-point-to-multiple-type-a-record IN CNAME multiple-type-a-record
+test.non-terminal.multiple-type-a-record IN A 192.168.2.1
+test.non-terminal.multiple-type-a-record IN A 192.168.2.2
+test.non-terminal.multiple-type-a-record IN A 192.168.2.3
+test.non-terminal.multiple-type-a-record IN A 192.168.2.4
+test.non-terminal.multiple-type-a-record IN A 192.168.2.5
+test.non-terminal.multiple-type-a-record IN A 192.168.2.6
+test.non-terminal.multiple-type-a-record IN A 192.168.2.7
+test.non-terminal.multiple-type-a-record IN A 192.168.2.8
+test.non-terminal.multiple-type-a-record IN A 192.168.2.9
+test.non-terminal.multiple-type-a-record IN A 192.168.2.10
+test.non-terminal.multiple-type-a-record IN A 192.168.2.11
+test.non-terminal.multiple-type-a-record IN A 192.168.2.12
+test.non-terminal.multiple-type-a-record IN A 192.168.2.13
+test.non-terminal.multiple-type-a-record IN A 192.168.2.14
+test.non-terminal.multiple-type-a-record IN A 192.168.2.15
+test.non-terminal.multiple-type-a-record IN A 192.168.2.16
+test.non-terminal.multiple-type-a-record IN A 192.168.2.17
+test.non-terminal.multiple-type-a-record IN A 192.168.2.18
+test.non-terminal.multiple-type-a-record IN A 192.168.2.19
+test.non-terminal.multiple-type-a-record IN A 192.168.2.20
+test.non-terminal.multiple-type-a-record IN A 192.168.2.21
+test.non-terminal.multiple-type-a-record IN A 192.168.2.22
+test.non-terminal.multiple-type-a-record IN A 192.168.2.23
+test.non-terminal.multiple-type-a-record IN A 192.168.2.24
+test.non-terminal.multiple-type-a-record IN A 192.168.2.25
+test.non-terminal.multiple-type-a-record IN A 192.168.2.26
+test.non-terminal.multiple-type-a-record IN A 192.168.2.27
+test.non-terminal.multiple-type-a-record IN A 192.168.2.28
+test.non-terminal.multiple-type-a-record IN A 192.168.2.29
+test.non-terminal.multiple-type-a-record IN A 192.168.2.30
+test.non-terminal.multiple-type-a-record IN A 192.168.2.31
+
+test.non-terminal.multiple-type-ns-record IN NS dns1.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns2.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns3.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns4.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns5.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns6.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns7.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns8.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns9.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns10.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns11.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns12.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns13.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns14.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns15.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns16.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns17.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns18.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns19.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns20.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns21.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns22.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns23.multiple-type-ns-record
+test.non-terminal.multiple-type-ns-record IN NS dns24.multiple-type-ns-record
+test.non-terminal.dns1.multiple-type-ns-record IN A 192.168.4.1
+test.non-terminal.dns2.multiple-type-ns-record IN A 192.168.4.2
+test.non-terminal.dns3.multiple-type-ns-record IN A 192.168.4.3
+test.non-terminal.dns4.multiple-type-ns-record IN A 192.168.4.4
+test.non-terminal.dns5.multiple-type-ns-record IN A 192.168.4.5
+test.non-terminal.dns6.multiple-type-ns-record IN A 192.168.4.6
+test.non-terminal.dns7.multiple-type-ns-record IN A 192.168.4.7
+test.non-terminal.dns8.multiple-type-ns-record IN A 192.168.4.8
+test.non-terminal.dns9.multiple-type-ns-record IN A 192.168.4.9
+test.non-terminal.dns10.multiple-type-ns-record IN A 192.168.4.10
+test.non-terminal.dns11.multiple-type-ns-record IN A 192.168.4.11
+test.non-terminal.dns12.multiple-type-ns-record IN A 192.168.4.12
+test.non-terminal.dns13.multiple-type-ns-record IN A 192.168.4.13
+test.non-terminal.dns14.multiple-type-ns-record IN A 192.168.4.14
+test.non-terminal.dns15.multiple-type-ns-record IN A 192.168.4.15
+test.non-terminal.dns16.multiple-type-ns-record IN A 192.168.4.16
+test.non-terminal.dns17.multiple-type-ns-record IN A 192.168.4.17
+test.non-terminal.dns18.multiple-type-ns-record IN A 192.168.4.18
+test.non-terminal.dns19.multiple-type-ns-record IN A 192.168.4.19
+test.non-terminal.dns20.multiple-type-ns-record IN A 192.168.4.20
+test.non-terminal.dns21.multiple-type-ns-record IN A 192.168.4.21
+test.non-terminal.dns22.multiple-type-ns-record IN A 192.168.4.22
+test.non-terminal.dns23.multiple-type-ns-record IN A 192.168.4.23
+test.non-terminal.dns24.multiple-type-ns-record IN A 192.168.4.24
+test.non-terminal.dns25.multiple-type-ns-record IN A 192.168.4.25
+
+
+test.non-terminal.a IN WKS 218.241.108.4 TCP (telnet smtp domain)
+test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN WKS 218.241.108.5 TCP (telnet smtp domain)
+
+test.non-terminal.multiple-type-wks-record IN WKS 218.241.109.1 TCP (telnet smtp domain)
+test.non-terminal.multiple-type-wks-record IN WKS 218.241.109.2 TCP (telnet smtp domain)
+test.non-terminal.multiple-type-wks-record IN WKS 218.241.109.3 TCP (telnet smtp domain)
+test.non-terminal.multiple-type-wks-record IN WKS 218.241.109.4 TCP (telnet smtp domain)
+test.non-terminal.multiple-type-wks-record IN WKS 218.241.109.5 TCP (telnet smtp domain)
+test.non-terminal.multiple-type-wks-record IN WKS 218.241.109.6 TCP (telnet smtp domain x11)
+test.non-terminal.multiple-type-wks-record IN WKS 218.241.109.7 TCP (telnet smtp domain)
+test.non-terminal.multiple-type-wks-record IN WKS 218.241.109.8 TCP (telnet smtp domain)
+test.non-terminal.multiple-type-wks-record IN WKS 218.241.109.9 TCP (telnet smtp domain)
+test.non-terminal.multiple-type-wks-record IN WKS 218.241.109.10 TCP (telnet smtp domain)
+test.non-terminal.multiple-type-wks-record IN WKS 218.241.109.11 TCP (telnet ssh smtp domain)
+test.non-terminal.multiple-type-wks-record IN WKS 218.241.109.12 TCP (telnet ssh smtp domain)
+test.non-terminal.multiple-type-wks-record IN WKS 218.241.109.13 TCP (telnet ssh smtp domain)
+test.non-terminal.multiple-type-wks-record IN WKS 218.241.109.14 TCP (http ssh smtp domain)
+test.non-terminal.multiple-type-wks-record IN WKS 218.241.109.15 TCP (http ssh smtp domain)
+test.non-terminal.multiple-type-wks-record IN WKS 218.241.109.16 TCP (http ssh smtp x11)
+
+test.non-terminal.a IN HINFO VAX-11/780 UNIX
+test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN HINFO SHARP "PC-1500 1983"
+
+test.non-terminal.multiple-type-hinfo-record IN HINFO "DG MV-4000" 1990
+test.non-terminal.multiple-type-hinfo-record IN HINFO "DG MV-4001" 1990
+test.non-terminal.multiple-type-hinfo-record IN HINFO "DG MV-4002" 1990
+test.non-terminal.multiple-type-hinfo-record IN HINFO "DG MV-4003" 1990
+test.non-terminal.multiple-type-hinfo-record IN HINFO "DG MV-4004" 1990
+test.non-terminal.multiple-type-hinfo-record IN HINFO "DG MV-4005" 1990
+test.non-terminal.multiple-type-hinfo-record IN HINFO "DG MV-4006" 1990
+test.non-terminal.multiple-type-hinfo-record IN HINFO "DG MV-4007" 1990
+test.non-terminal.multiple-type-hinfo-record IN HINFO "DG MV-4008" 1990
+test.non-terminal.multiple-type-hinfo-record IN HINFO "DG MV-4009" 1990
+test.non-terminal.multiple-type-hinfo-record IN HINFO "DG MV-4010" 1990
+test.non-terminal.multiple-type-hinfo-record IN HINFO "DG MV-4011" 1990
+test.non-terminal.multiple-type-hinfo-record IN HINFO "DG MV-4012" 1990
+test.non-terminal.multiple-type-hinfo-record IN HINFO "DG MV-4013" 1990
+test.non-terminal.multiple-type-hinfo-record IN HINFO "DG MV-4014" 1990
+test.non-terminal.multiple-type-hinfo-record IN HINFO "DG MV-4015" 1990
+test.non-terminal.multiple-type-hinfo-record IN HINFO "DG MV-4016" 1990
+
+test.non-terminal.a IN MINFO root.cnnic.cn. error.cnnic.cn.
+test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN MINFO root63.cnnic.cn. error63.cnnic.cn.
+test.non-terminal.multiple-type-minfo-record IN MINFO sun00.abc.foo.bar.liu.zhang.han.cnnic.cn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+test.non-terminal.multiple-type-minfo-record IN MINFO sun01.abc.foo.bar.liu.zhang.han.cnnic.cn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+test.non-terminal.multiple-type-minfo-record IN MINFO sun02.abc.foo.bar.liu.zhang.han.cnnic.cn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+test.non-terminal.multiple-type-minfo-record IN MINFO sun03.abc.foo.bar.liu.zhang.han.cnnic.cn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+test.non-terminal.multiple-type-minfo-record IN MINFO sun04.abc.foo.bar.liu.zhang.han.cnnic.cn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+test.non-terminal.multiple-type-minfo-record IN MINFO sun04.abc.foo.bar.liu.zhang.han.cnnic.dn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+test.non-terminal.multiple-type-minfo-record IN MINFO sun04.abc.foo.bar.liu.zhang.han.cnnic.en. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+test.non-terminal.multiple-type-minfo-record IN MINFO sun04.abc.foo.bar.liu.zhang.han.cnnic.fn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+test.non-terminal.multiple-type-minfo-record IN MINFO sun04.abc.foo.bar.liu.zhang.han.cnnic.gn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+
+test.non-terminal.a IN NSAP 0x47000580ffff0000003210999911112222333343
+test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN NSAP 0x47000580ffff0000003210999911112222333344
+test.non-terminal.multiple-type-nsap-record IN NSAP 0x47000580ffff0000003210999911112222333345
+test.non-terminal.multiple-type-nsap-record IN NSAP 0x47000580ffff0000003210999911112222333346
+test.non-terminal.multiple-type-nsap-record IN NSAP 0x47000580ffff0000003210999911112222333347
+test.non-terminal.multiple-type-nsap-record IN NSAP 0x47000580ffff0000003210999911112222333348
+test.non-terminal.multiple-type-nsap-record IN NSAP 0x47000580ffff0000003210999911112222333349
+test.non-terminal.multiple-type-nsap-record IN NSAP 0x47000580ffff000000321099991111222233334A
+test.non-terminal.multiple-type-nsap-record IN NSAP 0x47000580ffff000000321099991111222233334b
+test.non-terminal.multiple-type-nsap-record IN NSAP 0x47000580ffff000000321099991111222233334C
+test.non-terminal.multiple-type-nsap-record IN NSAP 0x47000580ffff000000321099991111222233334d
+test.non-terminal.multiple-type-nsap-record IN NSAP 0x47000580ffff000000321099991111222233334E
+test.non-terminal.multiple-type-nsap-record IN NSAP 0x47000580ffff000000321099991111222233334f
+test.non-terminal.multiple-type-nsap-record IN NSAP 0x47000580ffff0000003210999911112222333350
+test.non-terminal.multiple-type-nsap-record IN NSAP 0x47000580ffff0000003210999911112222333351
+test.non-terminal.multiple-type-nsap-record IN NSAP 0x47000580ffff0000003210999911112222333352
+test.non-terminal.multiple-type-nsap-record IN NSAP 0x47000580ffff0000003210999911112222333353
+
+
+test.non-terminal.A IN PX 10 ab.net2.it. O-ab.PRMD-net2.ADMDb.C-it.
+test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN PX 10 ab.net2.it. O-ab.PRMD-net2.ADMDb.C-it.
+test.non-terminal.multiple-type-px-record IN PX 10 ab.net2.it. O-ab.PRMD-net2.ADMDb.C-it.
+test.non-terminal.multiple-type-px-record IN PX 11 ab.net3.it. 1-ab.PRMD-net2.ADMDb.C-it.
+test.non-terminal.multiple-type-px-record IN PX 12 ab.net4.it. 2-ab.PRMD-net2.ADMDb.C-it.
+test.non-terminal.multiple-type-px-record IN PX 13 ab.net5.it. 3-ab.PRMD-net2.ADMDb.C-it.
+test.non-terminal.multiple-type-px-record IN PX 14 ab.net6.it. 4-ab.PRMD-net2.ADMDb.C-it.
+test.non-terminal.multiple-type-px-record IN PX 15 ab.net7.it. 5-ab.PRMD-net2.ADMDb.C-it.
+test.non-terminal.multiple-type-px-record IN PX 16 ab.net8.it. 6-ab.PRMD-net2.ADMDb.C-it.
+test.non-terminal.multiple-type-px-record IN PX 10 ab.net9.it. 7-ab.PRMD-net2.ADMDb.C-it.
+test.non-terminal.multiple-type-px-record IN PX 10 ab.net2.it. 8-ab.PRMD-net2.ADMDb.C-it.
+test.non-terminal.multiple-type-px-record IN PX 10 ab.net2.it. 9-ab.PRMD-net2.ADMDb.C-it.
+
+test.non-terminal.A IN LOC 32 7 19 S 116 2 25 E 10m
+test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN LOC 32 7 19 S 116 2 25 E 10m
+test.non-terminal.multiple-type-loc-record IN LOC 32 7 19 S 116 2 25 E 10m
+test.non-terminal.multiple-type-loc-record IN LOC 33 7 19 S 117 2 25 E 11m
+test.non-terminal.multiple-type-loc-record IN LOC 34 7 19 S 118 2 25 E 12m
+test.non-terminal.multiple-type-loc-record IN LOC 35 7 19 S 119 2 25 E 13m
+test.non-terminal.multiple-type-loc-record IN LOC 36 7 19 S 120 2 25 E 14m
+test.non-terminal.multiple-type-loc-record IN LOC 37 7 19 S 121 2 25 E 15m
+test.non-terminal.multiple-type-loc-record IN LOC 38 7 19 S 122 2 25 E 16m
+test.non-terminal.multiple-type-loc-record IN LOC 39 7 19 S 123 2 25 E 17m
+test.non-terminal.multiple-type-loc-record IN LOC 40 7 19 S 124 2 25 E 18m
+test.non-terminal.multiple-type-loc-record IN LOC 41 7 19 S 125 2 25 E 19m
+test.non-terminal.multiple-type-loc-record IN LOC 42 7 19 S 126 2 25 E 20m
+test.non-terminal.multiple-type-loc-record IN LOC 43 7 19 S 127 2 25 E 21m
+test.non-terminal.multiple-type-loc-record IN LOC 44 7 19 S 128 2 25 E 22m
+test.non-terminal.multiple-type-loc-record IN LOC 45 7 19 S 129 2 25 E 23m
+test.non-terminal.multiple-type-loc-record IN LOC 46 7 19 S 130 2 25 E 24m
+test.non-terminal.multiple-type-loc-record IN LOC 47 7 19 S 131 2 25 E 25m
+test.non-terminal.multiple-type-loc-record IN LOC 89 59 59.999 S 179 59 59.999 E 1000000m 1000m 1000m
+test.non-terminal.multiple-type-loc-record IN LOC 90 S 180 E 0.01 0.01 0.01
+
+test.non-terminal._http._tcp.a IN SRV 0 2 80 www.movie.edu.
+test.non-terminal.a IN SRV 0 2 80 www.movie.edu.
+test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN SRV 0 2 80 www.movie.edu.
+test.non-terminal.multiple-type-srv-record IN SRV 0 2 80 www.movie0.edu.
+test.non-terminal.multiple-type-srv-record IN SRV 1 3 80 www.movie1.edu.
+test.non-terminal.multiple-type-srv-record IN SRV 2 4 80 www.movie2.edu.
+test.non-terminal.multiple-type-srv-record IN SRV 3 5 80 www.movie3.edu.
+test.non-terminal.multiple-type-srv-record IN SRV 4 6 80 www.movie4.edu.
+test.non-terminal.multiple-type-srv-record IN SRV 5 7 80 www.movie5.edu.
+test.non-terminal.multiple-type-srv-record IN SRV 6 8 80 www.movie6.edu.
+test.non-terminal.multiple-type-srv-record IN SRV 7 9 80 www.movie7.edu.
+test.non-terminal.multiple-type-srv-record IN SRV 8 10 80 www.movie8.edu.
+test.non-terminal.multiple-type-srv-record IN SRV 9 11 80 www.movie9.edu.
+test.non-terminal.multiple-type-srv-record IN SRV 10 12 80 www.movie10.edu.
+test.non-terminal.multiple-type-srv-record IN SRV 11 13 80 www.movie11.edu.
+test.non-terminal.multiple-type-srv-record IN SRV 12 14 80 www.movie12.edu.
+
+test.non-terminal.a IN KX 20 kaku.google.com.
+test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN KX 20 kaku.google.com.
+test.non-terminal.multiple-type-kx-record IN KX 0 kaku0.google.com.
+test.non-terminal.multiple-type-kx-record IN KX 10 kaku1.google.com.
+test.non-terminal.multiple-type-kx-record IN KX 20 kaku2.google.com.
+test.non-terminal.multiple-type-kx-record IN KX 30 kaku3.google.com.
+test.non-terminal.multiple-type-kx-record IN KX 40 kaku4.google.com.
+test.non-terminal.multiple-type-kx-record IN KX 50 kaku5.google.com.
+test.non-terminal.multiple-type-kx-record IN KX 60 kaku6.google.com.
+test.non-terminal.multiple-type-kx-record IN KX 70 kaku7.google.com.
+test.non-terminal.multiple-type-kx-record IN KX 80 kaku8.google.com.
+test.non-terminal.multiple-type-kx-record IN KX 90 kaku9.google.com.
+test.non-terminal.multiple-type-kx-record IN KX 100 kaku10.google.com.
+test.non-terminal.multiple-type-kx-record IN KX 110 kaku11.google.com.
+test.non-terminal.multiple-type-kx-record IN KX 120 kaku12.google.com.
+test.non-terminal.multiple-type-kx-record IN KX 130 kaku13.google.com.
+
+test.non-terminal.A IN CERT 65534 65535 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgi
+ WCn/GxHhai6VAuHAoNUz4YoU1tVfSCSqQYn6//11U6Nl
+ d80jEeC8aTrO+KKmCaY= )
+test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN CERT 65534 65535 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgi
+ WCn/GxHhai6VAuHAoNUz4YoU1tVfSCSqQYn6//11U6Nl
+ d80jEeC8aTrO+KKmCaY= )
+test.non-terminal.multiple-type-cert-record IN CERT 65534 65535 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgi
+ WCn/GxHhai6VAuHAoNUz4YoU1tVfSCSqQYn6//11U6Nl
+ d80jEeC8aTrO+KKmCaY= )
+test.non-terminal.multiple-type-cert-record IN CERT 65533 65534 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgi
+ WCn/GxHhai6VAuHAoNUz4YoU1tVfSCSqQYn6//11U6Nl
+ d80jEeC8aTrO+KKmCaY= )
+test.non-terminal.multiple-type-cert-record IN CERT 65532 65533 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgi
+ WCn/GxHhai6VAuHAoNUz4YoU1tVfSCSqQYn6//11U6Nl
+ d80jEeC8aTrO+KKmCaY= )
+test.non-terminal.multiple-type-cert-record IN CERT 65531 65532 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgi
+ WCn/GxHhai6VAuHAoNUz4YoU1tVfSCSqQYn6//11U6Nl
+ d80jEeC8aTrO+KKmCaY= )
+test.non-terminal.multiple-type-cert-record IN CERT 65530 65531 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgi
+ WCn/GxHhai6VAuHAoNUz4YoU1tVfSCSqQYn6//11U6Nl
+ d80jEeC8aTrO+KKmCaY= )
+
+test.non-terminal.A IN APL 1:192.168.32.0/21 !1:192.168.38.0/28
+test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN APL 1:192.168.32.0/21 !1:192.168.38.0/28
+test.non-terminal.multiple-type-apl-record IN APL 1:192.168.32.15/14 !1:192.168.38.0/28
+test.non-terminal.multiple-type-apl-record IN APL 1:192.168.33.15/15 !1:192.168.39.0/28
+test.non-terminal.multiple-type-apl-record IN APL 1:192.168.34.15/16 !1:192.168.40.0/28
+test.non-terminal.multiple-type-apl-record IN APL 1:192.168.35.15/17 !1:192.168.41.0/28
+test.non-terminal.multiple-type-apl-record IN APL 1:192.168.36.15/18 !1:192.168.42.0/28
+test.non-terminal.multiple-type-apl-record IN APL 1:192.168.37.15/19 !1:192.168.43.0/28
+test.non-terminal.multiple-type-apl-record IN APL 1:192.168.38.15/20 !1:192.168.44.0/28
+test.non-terminal.multiple-type-apl-record IN APL 1:192.168.39.15/21 !1:192.168.45.0/28
+test.non-terminal.multiple-type-apl-record IN APL 1:192.168.40.15/22 !1:192.168.46.0/28
+test.non-terminal.multiple-type-apl-record IN APL 1:192.168.41.15/23 !1:192.168.47.0/28
+test.non-terminal.multiple-type-apl-record IN APL 1:192.168.42.15/24 !1:192.168.48.0/28
+test.non-terminal.multiple-type-apl-record IN APL 1:192.168.43.15/25 !1:192.168.49.0/28
+test.non-terminal.multiple-type-apl-record IN APL 1:192.168.44.15/26 !1:192.168.50.0/28
+test.non-terminal.multiple-type-apl-record IN APL 1:192.168.45.15/27 !1:192.168.51.0/28
+test.non-terminal.multiple-type-apl-record IN APL 1:192.168.46.15/28 !1:192.168.52.0/28
+test.non-terminal.multiple-type-apl-record IN APL 1:192.168.47.15/29 !1:192.168.53.0/28
+test.non-terminal.multiple-type-apl-record IN APL 1:192.168.48.15/20 !1:192.168.54.0/28
+test.non-terminal.multiple-type-apl-record IN APL 1:224.0.0.0/4 2:FF00:0:0:AAAA:CCCC:BBBB:9999:5555/48
+test.non-terminal.multiple-type-apl-record IN APL 1:224.0.0.5/8 2:FF00::0/8
+test.non-terminal.multiple-type-apl-record IN APL 1:224.0.0.9/12 2:FF00::888f:0/24
+test.non-terminal.multiple-type-apl-record IN APL 1:224.0.0.13/16 2:FF00::7777/72
+
+test.non-terminal.A IN SSHFP 2 1 123456789abcdef67890123456789abcdef67890
+test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN SSHFP 2 1 123456789abcdef67890123456789abcdef67890
+test.non-terminal.multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef67890
+test.non-terminal.multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef67891
+test.non-terminal.multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef67892
+test.non-terminal.multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef67893
+test.non-terminal.multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef67894
+test.non-terminal.multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef67895
+test.non-terminal.multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef67896
+test.non-terminal.multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef67897
+test.non-terminal.multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef67898
+test.non-terminal.multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef67899
+test.non-terminal.multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef6789a
+test.non-terminal.multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef6789b
+test.non-terminal.multiple-type-sshfp-record IN SSHFP 2 1 123456789abcdef67890123456789abcdef6789c
+
+test.non-terminal.A IN DHCID ( AAIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN DHCID ( AAIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+test.non-terminal.multiple-type-dhcid-record IN DHCID ( AAIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+test.non-terminal.multiple-type-dhcid-record IN DHCID ( BBIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+test.non-terminal.multiple-type-dhcid-record IN DHCID ( CCIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+test.non-terminal.multiple-type-dhcid-record IN DHCID ( DDIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+test.non-terminal.multiple-type-dhcid-record IN DHCID ( EEIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+test.non-terminal.multiple-type-dhcid-record IN DHCID ( FFIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+test.non-terminal.multiple-type-dhcid-record IN DHCID ( GGIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+test.non-terminal.multiple-type-dhcid-record IN DHCID ( HHIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+test.non-terminal.multiple-type-dhcid-record IN DHCID ( IIIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+test.non-terminal.multiple-type-dhcid-record IN DHCID ( JJIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+test.non-terminal.multiple-type-dhcid-record IN DHCID ( KKIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA= )
+
+test.non-terminal.A IN SPF 'sfasf'
+test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IN SPF 'asdfghjkl;'
+test.non-terminal.multiple-type-spf-record IN SPF 'asdfghjkl;'
+test.non-terminal.multiple-type-spf-record IN SPF 'sina;'
+test.non-terminal.multiple-type-spf-record IN SPF 'cnnic;'
+test.non-terminal.multiple-type-spf-record IN SPF 'jkl;'
+test.non-terminal.multiple-type-spf-record IN SPF 'c=sina.com.'
+test.non-terminal.multiple-type-spf-record IN SPF 'fw=fff.com.cn.'
+test.non-terminal.multiple-type-spf-record IN SPF 'ibm;'
+test.non-terminal.multiple-type-spf-record IN SPF 'dell;'
+test.non-terminal.multiple-type-spf-record IN SPF 'google - microsoft;'
+test.non-terminal.multiple-type-spf-record IN SPF 'leibusi;'
+test.non-terminal.multiple-type-spf-record IN SPF "v=spf1"
+test.non-terminal.multiple-type-spf-record IN SPF "v=spf1 -all"
+test.non-terminal.multiple-type-spf-record IN SPF "v=spf1 ip4:192.168.0.1/16 -all "
+test.non-terminal.multiple-type-spf-record IN SPF "v=spf1 ip4:192.168.1.1/16 -all "
+test.non-terminal.multiple-type-spf-record IN SPF "v=spf1 ip4:192.168.2.1/16 -all "
+test.non-terminal.multiple-type-spf-record IN SPF "v=spf1 ip4:192.168.3.1/16 -all "
+test.non-terminal.multiple-type-spf-record IN SPF "v=spf1 ip4:192.168.4.1/16 -all "
+test.non-terminal.multiple-type-spf-record IN SPF "v=spf1 ip4:192.168.5.1/16 -all "
+test.non-terminal.multiple-type-spf-record IN SPF "v=spf1 ip4:192.168.6.1/16 -all "
+test.non-terminal.multiple-type-spf-record IN SPF "v=spf1 ip4:192.168.7.1/16 -all "
+
diff --git a/tools/query_cmp/zonefile/example.com.txt.signed b/tools/query_cmp/zonefile/example.com.txt.signed
new file mode 100644
index 0000000..a269535
--- /dev/null
+++ b/tools/query_cmp/zonefile/example.com.txt.signed
@@ -0,0 +1,6858 @@
+; File written on Wed Mar 9 15:16:51 2011
+; dnssec_signzone version 9.7.2-P2
+example.com. 86400 IN SOA NS1.example.com. root.example.com. (
+ 2010091701 ; serial
+ 3600 ; refresh (1 hour)
+ 900 ; retry (15 minutes)
+ 604800 ; expire (1 week)
+ 3600 ; minimum (1 hour)
+ )
+ 86400 RRSIG SOA 5 2 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ e192JzLhvELznlN3LpQfVh6L1ZYsL0maA39A
+ CN3hH6sorsleyLMX8imUmK88yCo/QaxLC+yx
+ sSe3wJT7W+Jv2dBQFb6HoEBYp0ESXvwoGz9k
+ IJOB2bEs9fwXmrnb/Km+T4HvS0yqUwCt+/06
+ yoCX/S95h4a6vexPpNZhhzVvpLw= )
+ 86400 NS NS1.example.com.
+ 86400 NS NS2.demo.example.com.
+ 86400 NS NS3.noexist.cn.
+ 86400 RRSIG NS 5 2 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ lxHd2KDisaKQgOO8Kc1eWr9PO+sWp4fUEWCb
+ +TUhy3iEvW+zLmrn+QUpN/dT4PM2t9kMtJRx
+ i1uB+tm6pD2sbCGaVTkW/k+mJeCBfLsQmlqK
+ qXIRX91AhRrFhJZtmK3yB/dT5zhdRxZGIviC
+ kL7BhU8e+RzIxli6bdJmkKFYcqA= )
+ 3600 NSEC a.example.com. NS SOA RRSIG NSEC DNSKEY
+ 3600 RRSIG NSEC 5 2 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ pU4PI8k+ay11yVQXuA8W6vjqGKod1wBIr20B
+ ZSK+nIAzpULXJ5CjcGxKSOkTglPDFQxY+UVY
+ ry4w6wJUF7tYNrGQYfRpOxgVLdv7NGNS+0fn
+ DXf9PsHj7V+5uacDo2peby01pmU5S6Ji0Wwt
+ iNxmbk1/GP7icCsFLGuO3jrPrlY= )
+ 86400 DNSKEY 256 3 5 (
+ AwEAAdCIGyYHX9ul1AYjflqR2dKMsCPoxt3+
+ nuUDCf2M9jxlY5H/ExPw7GcFAtNqbTN9fA50
+ d3zQ6z4wjR9T9kuEdfUgcRR5+RcgIkONZe9e
+ 0ULSOUgsVp5Jyx6avWBnI6RYGp3Vozs2HL7E
+ MobFrj5FWg4ipW9Cpbzgi+QR/ZM8bwEr
+ ) ; key id = 27366
+ 86400 DNSKEY 257 3 5 (
+ AwEAAZpJP70EU7QWkGo6r7oB1t/jYwt75b/G
+ qVS+a4KalZQK2WJul4dwQXoxg3byRKuYy6l8
+ 03UoFP8NtyTWPr8omGopeyZ0/0jN0QdbngoI
+ Bt2kC3i61fDGGoslIjnFK4ucWVXk+qROoqOu
+ 4ZFSOuULNItJl0j1Zb6bwCzhXx5Un0/E3Qnj
+ Xj2QTgmMDbZCRpa1Uv8XUc0VGluluB2YLXBT
+ 6BrN5YsVBK9TUNky0b9pUX8S7bfxXcyPd/9d
+ gJYkSZ6tShyctfmgRpeSa/BgYTOD2ymsQv6N
+ RdGk82LTHY37N8h1VDGIN/X+gfRZzm5VPCZS
+ CT+e/8sknTH5pctKwsQxnxc=
+ ) ; key id = 12133
+ 86400 RRSIG DNSKEY 5 2 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ NrkXeHhw2VCgU4KA8Pk8XBMisWb+RyQGSaAO
+ hk1Zkc0skthKEcCquu9z+zQ5G7lVc8zws8F2
+ 3dOdKEa0o/TFlmSH1XM5W3xMdHS+E0/gqEhK
+ y3qX8w9sj/eA0f6tNguQ/iCZtwKsLJsLxCYy
+ WPcg7sjsjKUO5tJ7EFsAFG8jdiw= )
+ 86400 RRSIG DNSKEY 5 2 86400 20110408061651 (
+ 20110309061651 12133 example.com.
+ WaHcL7AXsql6tPtnSudQT/wZnYNRKnMLSF5t
+ IcUgJaRGd8gZ/wfJR4lumwc+4NBDvyL8kNs+
+ FscFXQ1izXlPePvsCi4Tw6KYIj/wNoBNF52n
+ DprUpDIjGjXyZdQ2yWu57z8MQD4jx1xt5DkP
+ hRrdNPv3yeDIvY9/s1SsXscIY5SuEt5OpP93
+ 67Igc75uHxZFjBjQVaetf4zvwupafuRmlg/6
+ LmiGp0lGE9VTsG3PC0bCx2umzfv6LLX+Ibtk
+ XrEOc4S2YtJ5HbY43n9hH0Pg5eEOahDhlJSQ
+ tt7sw3NxgGMRbMYa+CGJ3GOBvHBhjNayCvxd
+ sMD+GHt4XBto4GCmQw== )
+_http._tcp.a.example.com. 86400 IN SRV 0 2 80 www.movie.edu.
+ 86400 RRSIG SRV 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ QcFXkDEyx+Hv6b3jN6+T9MHNGX5hPsGmqxCy
+ 7GHjbJ8wvz2AJHEb4YdLnaRrXO6fIotY4I07
+ 1ArIDlUPcF73VP6Hw5+U8vAeKc1Tye5L3920
+ lXNFkWmO1qif6qlvAeLwJEbb03fhNvUcSS4K
+ 6InXSaWu4Jqap7psqchJqgqxLrM= )
+ 3600 NSEC test.non-terminal._http._tcp.a.example.com. SRV RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ r5EXPMKrr5vRfjFvsgO79Bvd1UPVmP8TipWq
+ xly+WeQT7GkO3T9i3md3c7/JpJGy+cMErfzm
+ qkt70lmHkY3+e869hQE5F2YqOi7fZm/KRy/C
+ 28rw155VWfdWIZDcmXlPJA1EsK08B1/9Xio/
+ F28cMr7hN4ehtSy/kMDWIMFQ2hY= )
+test.non-terminal._http._tcp.a.example.com. 86400 IN SRV 0 2 80 www.movie.edu.
+ 86400 RRSIG SRV 5 7 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ CXIgvla4xVw4B+QRaARIeBupTwGwD4eZGrM/
+ v4urp7jGUrkPgqAJmk7Q4oAzN2szcWYFfawh
+ JRaMetY2HLocSDLvZDZcVWGvUM8RU1pu+SDD
+ u+h0Lwwb1AJghkCnpvudXR1K9cV0k5xStxXA
+ nJ5QYEvqKmvJ4Yo7hWfiq4RImfI= )
+ 3600 NSEC test.non-terminal.a.example.com. SRV RRSIG NSEC
+ 3600 RRSIG NSEC 5 7 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ OpgVpnelCCcv8mhJenxv/tFhTz85nT0X0NVa
+ HWJWpIuKzQQ3MwthdywY7Ugnm9FX+W4uWhyA
+ /VGzYHkoZz9Rf7Fm43lk6JO8lu9B3vC6lqZo
+ PBzYgvAWtjxKOrAuaDGPtHVhN31JHl0P0NUb
+ T1Bgqaa4rQUnYqQeWJdQs72Rnv4= )
+A2.example.com. 86400 IN A 192.168.1.12
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ CymhsyPRk+xv+OuaedapHOXJUf940neNT32N
+ DHyXirUBitJdbVzzilQBc7xVdbNSuwNcfNwC
+ PpwyAqFzmQ0JkzEpiyNxDHR/5weAkolKK5RT
+ 1Inne9XtZmf9z7Q1zDOBoXqLA8e4ZcnlQDhl
+ FsuxLTVp3XkuMJOszJVO1Gpi49A= )
+ 3600 NSEC test.non-terminal.A2.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ gfKvkjuJaKOuHyvrLX7YPbiEvz4W1hc962co
+ 7VrGrNa9qMAbW32zuLCirMefFbE/k19tJ6QJ
+ 4bmmi7m3NXGFbrTyk3vRTX+G75h4SneG/fzT
+ qGTCNzjCxYGSFIn2RKUNZmoIRa8yu4PAjnDf
+ KUgTsWBk4+JpAnvtjhLlP9otQpU= )
+test.non-terminal.A2.example.com. 86400 IN A 192.168.1.12
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ EFVi2Os1Vd/mEYv6HKVUeR+GeMHS9NuqHfSQ
+ M9LXZ0jpSRO9sdTqxg+tscacqmO/JOcGy1nM
+ 1mtSVnEWPj5KGdWOcoab2/JZSKaK+EnYQ9VP
+ OQbu8jMn8c0WL8L4QmWzbE1PQO/8nlHVCCwf
+ hzBtBmsn+btfAtD51h98phvU9B8= )
+ 3600 NSEC AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ I+nGXCfTaUS3sSFm6cVEvVJV5MxZ3BKkUV+z
+ 0JGZjxsNfrFJLh2lN0B4SyPVRIFri5cS7wPA
+ bhNJKILBelGpKo/nbsUuJTU56Dh6iRBqkI5F
+ HThZeRfcn3aSiBNU8FN2gl6Q++3ITwPbG/Cr
+ 0vZNVR3J767S67znc5m6IbhAHWo= )
+test.non-terminal.a.example.com. 86400 IN A 192.168.1.10
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ fZ2hxEo47ZfBk8yyZpkGlqkzopHpU2NUNsX2
+ OPL9fHbhjOs0KCKs1dLH3csTmXyc3bTZAk8O
+ CF5ZX4UHHP9CsOYZULDTdgi3H43tzb8+XrRn
+ flJnwl3sPUEooPfaeC+YYKYwvBCuoIeM3HOr
+ IFWJplCI+R321AoeCdiEKZE0HCY= )
+ 86400 WKS 218.241.108.4 6 23 25 53
+ 86400 RRSIG WKS 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ PTSaoyVOsTqxymccZOPbFEXJ2xhYiOYBoYAE
+ JiPJxb/vUNxPoJpQJlRwbvqylKhC0WmSSvkp
+ r1+8dCjvt3bOq/1f9vAurG1lQu1yoC7Dy5Mm
+ ybxMBqDjxH+XReiE14BiRAhPBrIOH1s+5Boh
+ WqkOFjwhr99l47eAOlxLSN/iIsM= )
+ 86400 PTR 1.1.226.159.cnnic.cn.
+ 86400 RRSIG PTR 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ OVlX74fHDc1A6uq7j/oTzC9BUNuPgGjxh6oS
+ T8XoH8NEQRAcUpd+7b4Usm5lI3mAVK2+0OtS
+ dt3jdfKXgMVAOeGA5iM7HZSgsUMxle2oB5ET
+ 5Nn1RpNOvGdMswuvEdlSc4GmSoGxTlB2MFkj
+ g3nBa0H3TTZCZSBRg+FGLIh9LRQ= )
+ 86400 HINFO "VAX-11/780" "UNIX"
+ 86400 RRSIG HINFO 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ y5U+AM4RKKDRgvetODc+KSA0sfIdBg9QPW+M
+ kPKkRhM1yE+bCn+/68+npVMPYOis16E1FYCd
+ qrrWaiEUSjO62RBeKLLEkgiMhstMUYXhxHue
+ daKWN1dKQ01D9jMQbtsmrHs6cl//xunWhej1
+ qQjY0lRtxv1GVky4xfQdom6LR1I= )
+ 86400 MINFO root.cnnic.cn. error.cnnic.cn.
+ 86400 RRSIG MINFO 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ H8krZdNDu6MbrnKUVk2+KQLQhvVgQBQ44Zqn
+ vF66Eek0huDgPqgeBOV8VNYrrNbKmWMqjstu
+ zZgC3fJRQ7Y/yYAulUkwQOEQ2ihBWmFQYIK0
+ JyWJEaFe5IKYe0j/nm9jbSQezv1AxfumUpfv
+ GDqpd9POZqo1lB5fglkXCdtvEHo= )
+ 86400 MX 10 mail.example.com.
+ 86400 RRSIG MX 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ lyq50HUzixKIl4Yl1LgPb1g8LWI7dG2mFhdU
+ 2a5Hw7t0Sm+NkZdmiV+xc0hyzAaMXAJj2FOy
+ sMOj/X/jolaFP3yMo5sC5IdIufioudbmmhSI
+ 62u+D5/EOb1ccDvnZvIzsEGaSJkF0ImeRSSp
+ g28NZiDsInPfT8BYGYoVE9aV8kc= )
+ 86400 TXT "ms-dos 3.0/6.0 ?" "google-app_,\;!@#$%^&*()[]{}=+|`~'<>,."
+ 86400 RRSIG TXT 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ytPnH7CKSUlhysvADRzna3JjFjv7qmsm+hcx
+ J2hUqu0DDpfDqE1OLqbXh+Egka4GO38T45IS
+ QfCkEB04wKJIsTVI5gHhJCclr0hPNWUtHudu
+ lVe107AVodRtRBu4mI6CQZko6/eOPDY5bA6s
+ 0ngLEv5paCGqhSMdScUzMTl5tDo= )
+ 86400 NSAP 0x47000580ffff0000003210999911112222333343
+ 86400 RRSIG NSAP 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ WCWGjMGQ0mLM9rJ8MrzW8Oh3ifigxg5L/bYA
+ 0OVoy6qHUHgwJKQLFPywBeK0MFvN69U6iYkC
+ rEspFiN6Dvpu0GvIonFHSNrlzK5R8AiNHo1m
+ 9WrdcljAti7pdIwlqJvzPJ0uxMZ+FbdVgXl1
+ FgigqOvzFk1hs+6MdFtgrcB4sEY= )
+ 86400 PX 10 ab.net2.it. O-ab.PRMD-net2.ADMDb.C-it.
+ 86400 RRSIG PX 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ZXO5G1J9CcoF6hGd+gZzD8T/nF1MIz5JqAEE
+ qIpDX72dfHEVginHhzm41aSS/R2krjwJKt6p
+ ny/2af/e9nq3PkKHDtZug5frLkf1pkJko4RF
+ u5Kj27gPKfKuxUIRRp095nk45MVk8B0+eiMb
+ rsNAdOO/g2/BLnxqpXj78BdCpjY= )
+ 86400 AAAA 2001:dc7::1
+ 86400 RRSIG AAAA 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ MnTVEK0eSa1lPIpYJ6O1laVlrs4OLvJXZzKj
+ awNcWQOZVpaPkPH33ktGGfpY+CdsvHaTRgv/
+ me9Zw0+dlq9Z8prGi/a6ip1gR6wkONY4Jo06
+ l5YHvDt7P/43wisGsc/dl+TRS3njH2ZOdipo
+ hsYPBQIQem/PS6IziuiY+jgk59M= )
+ 86400 LOC 32 7 19.000 S 116 2 25.000 E 10.00m 1m 10000m 10m
+ 86400 RRSIG LOC 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ iG0R8q8YpHJGRSjpopJzPEwflaKja+04lnX8
+ kEm99VZzqOniwmiNhMGZTovRq2XwnAT4TkTv
+ g2Uak5vhAZG7CfTSwlM6Iw7IJWtEtH5hqRFZ
+ pjvm/DVlSb/Id4gyqxggrgbI+39VinJ0XSXV
+ lx7hy3hwJ/QvU9Qa0TCbwpPkOrM= )
+ 86400 SRV 0 2 80 www.movie.edu.
+ 86400 RRSIG SRV 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ hCqwgDea7OtI2Hcxm7Apno/MT2h57VzxwvfU
+ Je1dOXkD2lQUzwY4EneOG5bbyybt5QaZ7gy1
+ WjwiS/mJGREj4LPpgefH+UDr445OjYEimO8t
+ 3y0mMkun6O/pUhH1siaE0NibNVUJhTkd4h2o
+ Qoen+g9qHy9sltBugqPlmnJorNQ= )
+ 86400 NAPTR 18 35 "Au" "siip+E2000U" "!^.*$!simmmp:information at cnnic.cn!" mb.example.com.
+ 86400 RRSIG NAPTR 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ aoJZOwZeZxhNLM9Mo1imybr9y0C7wTwiUNbe
+ pgjjYUC+gy83gq+bCH/K3dvr6spU/FleNOEg
+ GuM5VYW6UqAo/S7baLj/xrT+5F3W649E2LAK
+ 0l4q9PQhZOaMnj/+LNBDeqG2bqOYTcNjDFvb
+ fvzvCJZ8jmLzlwlVq37k+HsZuMs= )
+ 86400 KX 20 kaku.google.com.
+ 86400 RRSIG KX 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ OKmV0m/7w+qPNWdVE9PfjoTSffaECcKfraMT
+ ALmtgpJCXDa9UsRyUDmPdeMX90J65p6yyO57
+ Lgta+5x5qrslmJR8EyBdUHv8Stp+lnOOgI4r
+ niPkUN//MhzcC9NXX05S3bTEyYR/COpoqwKU
+ pGymTYS7rC/LmizMEcWa0/JstH0= )
+ 86400 CERT 65534 65535 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45Ik
+ skceFGgiWCn/GxHhai6VAuHAoNUz4YoU1tVf
+ SCSqQYn6//11U6Nld80jEeC8aTrO+KKmCaY= )
+ 86400 RRSIG CERT 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ QXp2HLZU535WhcxbJjkvbnTFv30VmEa5STm3
+ k1daniwZm0enyaFfZ0TnuxFCgGYBGnOo/E94
+ AUxQ/pvRBxbtaqLaDLKJ6bnTrhjT6onaffXZ
+ rgV4tXSBWSYrQR33fowzXwjbOWzhYT7RyI6z
+ vj/Tm33hr2hxjbChXZivR3SRx5c= )
+ 86400 DNAME sub1.cnnic.cn.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ jTN7VyQTJ040YKb75yXhTsOIa4Y4arJFKEp8
+ RFV2U3OT6e/BP8unmO9mYMTJqwdRkxA0ZBJx
+ viH400eZ/4OBntXHz+iTE+JsBwFo+KOQuZQb
+ WqTNJGUFyoSKttWw3c6T8SiExmGV48wXj+xO
+ dVtHIpNTrgFCOkSpg8Y8LuC3MRs= )
+ 86400 APL 1:192.168.32.0/21 !1:192.168.38.0/28
+ 86400 RRSIG APL 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ FSLqGFSxKyRNgAS8q0vyMJZpLvDPiB00DLC9
+ prD8SsIjRytdltqQQnpZWyE3d12OapOkC+6N
+ ONCvTBqDSb4GHXfDmqMeIStAc6ef9LeqNEMW
+ HkinGJgnvZTakSKWkdvauJw9mEhCvjVtT4ah
+ oRpTRR3cmakjM/mZaXwahejfj5g= )
+ 86400 SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7890 )
+ 86400 RRSIG SSHFP 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Js5Zk0o7ZllVXt0wLGGDtTzK0MFOa9vk8i71
+ ihCVh9En+z9+4ZeV4fWliO+4owS4G+H3z5qu
+ 8iQTPCx3VAAIJzSuAxxO8KR0Fg7PXsfcxQHR
+ YgZatXLuXmUf3rSUI79YCMknwVdL1jnK3P0H
+ 3VS7iAQZ6rnln6yoMOHfN8dHMIs= )
+ 3600 NSEC A2.example.com. A WKS PTR HINFO MINFO MX TXT NSAP PX AAAA LOC SRV NAPTR KX CERT DNAME APL SSHFP RRSIG NSEC DHCID SPF
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ pTbeGiHI1nPV2vKXOXMI+v/vXGZoiK12hveH
+ p6fnnffBdbkHn9ZMaNvdeUlsDy3zPVgra9On
+ LjDonIqej3Gw7heEatRG3KEez2e/WIY3+sIs
+ PD2IctkxPOoaJgb5+3WZDserCIm0qbHeVu3u
+ 4sSZxh1KPKpRKzES3Y5EBAkTShA= )
+ 86400 DHCID ( AAIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 48830 190 32
+ 86400 RRSIG DHCID 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ UP4csgLTkvDnicg2qF0NO8daixH1IWQJ9Xqp
+ OMos806bqSvKhyn/Egh6QVNe+UAmnRpSobEC
+ h6jKWcEVFjhM2EtbOUUlfjNaWwRrqlPIHhl1
+ urWsWm1x+kOrQcgd8jREbXtsq65kmlTTwZU7
+ 2PR18hHvCljIHbrCkZy3WC+mDk0= )
+ 86400 SPF "'sfasf'"
+ 86400 RRSIG SPF 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ g0zsyxQnbYfe9mcugFcY6u8aBmesbWr8+BfG
+ 7NN2gCDSON8zUhW3fC9XRSL7AfDm5gHYyQv8
+ a6yNwOVNSjK6jZgaiHLarVo+RZCp9Fxe/rcj
+ TajZEfALjJXuA10nJ6d7gfpQMfGzy24bpsKZ
+ lVUZa2xp5TGdZoQS/8YkS8j7RNg= )
+a.example.com. 86400 IN A 192.168.1.10
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ElzDQoY56Lqw1pcMpRU3mQIfvDVbal2ZGcHs
+ 9wJAWOHHKdHsFLUjW2S9ouw4Sh8/9orWdlsf
+ TjsOdLnwtbRS+dPAJW5LvFsnURtUAPzr0/fH
+ scBNgZQPeqQs79B+qudK62Ut8WP6ZtvvY6Go
+ 1NLlZN7svt2D6KONYflAPi5jbPg= )
+ 86400 WKS 218.241.108.4 6 23 25 53
+ 86400 RRSIG WKS 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ xX9GEZOOAhRdohwFTwzcFSYCV/GiTmAHx5uA
+ c7XSZ/+Tp7POJw4WAXNdYPBFb6rELOCdfjrj
+ MK79Nm6mQYp94BBd3CULyrvZCrPFOrEyXda+
+ LVCXrV1WAnedZPqyQqsCivoUBMDCHXgFA4EG
+ t4rZFFr9YRIkiD1XMD3eNYgrPXE= )
+ 86400 PTR 1.1.226.159.cnnic.cn.
+ 86400 RRSIG PTR 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ vYg08ocmOC1FF1Ws75r6TLX/3QpD5WA2/KEb
+ SnTtlEf7scvN4piy8XR4F40ujvGTVZqom/Zu
+ gt1CZ1RL38A+PdGsbUU03VBPxUHmY0DsMlxW
+ H9fVbFU3GxF3hfabOSYSRL7qU1xOmnz+a7R7
+ r2nL7YWDRJ1ogjA/G8+YKvQeWeo= )
+ 86400 HINFO "VAX-11/780" "UNIX"
+ 86400 RRSIG HINFO 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ vC57e5vliWEWZuqBL8U5NChvNxqJM+3xgem1
+ scN8zllo7wrScrlKDVwjVwbxDOs26iAcMkrw
+ C/iPV5cNh4JQwL4zjALWtwZWm9ndvprQjzex
+ 9HteKJj7YPWZC37BaUAhoC0z4E+RkW+1Ao6e
+ MP1HjSr6jL5VafrgqKApT8XWQxM= )
+ 86400 MINFO root.cnnic.cn. error.cnnic.cn.
+ 86400 RRSIG MINFO 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ePWNl3irfoaR9Vh5SfkL1nPi8kWqDLXhZUzo
+ Qqjs71fV3Pudc2iMLXLjO54VlikjnfKVwXLk
+ QVbjdGfVQne5EbgsSif44ulb6cIB/NDj3pwa
+ A2L7VARae55qHCdJ4VPHYOlHdvLkLd14U480
+ grKhu8jACjKhFbIzRo1ZNidRizE= )
+ 86400 MX 10 mail.example.com.
+ 86400 RRSIG MX 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ JlFRRzmvOeBaOETnpTrWAgTSYr8CkX8mhY9e
+ Cm7/RdfAn43o2TeZLvMYQcKsu5oBw3NfUWnw
+ UKr0Glsu10ca6029Z6y81m4+tRtmH7XYOPsC
+ vCPxMMyyTi3kszMwLky5Ac2IrPucZYszYf9f
+ a8fekbydJTBhnHqFM+9RjwmYbMs= )
+ 86400 TXT "ms-dos 3.0/6.0 ?" "google-app_,\;!@#$%^&*()[]{}=+|`~'<>,."
+ 86400 RRSIG TXT 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ uU8x5VUArAYXSK4D6ivpwJmvmu9kHTAPSFkk
+ 4Yph04dWDV5Ae+6KIy1QidHPiQPZ7dX6ZTIW
+ lPaGMD/yH4gg9xKTM0vaB/SmFQnZhb3GMEYu
+ Ucx9G45jm0BOQs0eEhK+juo+dCOYWdfUb7sl
+ GqOtB/DBkal9+voLqsJOdcgjEco= )
+ 86400 NSAP 0x47000580ffff0000003210999911112222333343
+ 86400 RRSIG NSAP 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ aA0ZJlKJW7iv0NFwmZEJmvaNJ71hI04MIhaf
+ KELGz5IgnIdqntxCHebCcgjW0fvGMF8FgtqU
+ NqBgjW2lXBiJGGxRIxgJXUmohREN7LlnGpNx
+ 816yK3SGTYrxecpub0nZeXb1mbZKHcb+W74a
+ opelKvJioG26vIC7MkxwkawsAW8= )
+ 86400 PX 10 ab.net2.it. O-ab.PRMD-net2.ADMDb.C-it.
+ 86400 RRSIG PX 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ uvJp85WdHc3ajrwC9vGedFEpQgQgXrEs77CD
+ sNo9wUyMaCjVHHxoslLsy+eOYY4BqIxapck1
+ pgwZ02osNrBNKjfvkXwP2ttA2GsG4Gutwgk8
+ B1fyZWe4prvQd3WEPkqkRTgQhc/nEQ6DKQ2N
+ vTyk4pUVHEX/CxIZIGE+kzBx6gk= )
+ 86400 AAAA 2001:dc7::1
+ 86400 RRSIG AAAA 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ QEq+y/E6z8UjAfmzaTSwjrdTpnv4kUmWbv5+
+ oDUybEVVKulj/kDpVb+tzBTRUfqUHuVQRe12
+ b6fChfcTZlBi01nEXkAbFUoo0RGCY9GFCf4M
+ wDSomX0LzZHBtlPVG3QQ8Z1vNSN0efrJ3SWT
+ Yu7bOpughjQ4dP3Sc0LGQN4lLbw= )
+ 86400 LOC 32 7 19.000 S 116 2 25.000 E 10.00m 1m 10000m 10m
+ 86400 RRSIG LOC 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Sp20GwyCuoEnQL31m29xkm5mjiEWKGNm7DGc
+ 04As336Y6BoSKsXUnliuyIMoZ1a5XrW/3Yxu
+ FrKk+XRSCafO6Fi9MxnrSdGBwgthwrEb2GgL
+ v6tAAHthmaDJCA5DAA+GZnMGj3bKIq1Lneez
+ xexMWbPbtFK1w6gqeygY8pgLMOQ= )
+ 86400 SRV 0 2 80 www.movie.edu.
+ 86400 RRSIG SRV 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ pqpYwqtFQBWB5F2plUrBE3D1VjdK5gr3qn0Q
+ VnYsGwCUo8LCpmxCpn009KgXf91RcSVZwRJ0
+ sexp50fh8Oo+so4M7C0sCSxe1XqhS/oEBBxK
+ z3tpM+ylYADwJMmMfMmflTM4je6FQIK5k8yO
+ dVYPJ2Y6Xkd3uuUDYIk4NOu1iyM= )
+ 86400 NAPTR 18 35 "Au" "siip+E2000U" "!^.*$!simmmp:information at cnnic.cn!" mb.example.com.
+ 86400 RRSIG NAPTR 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ OmJUFic+v8NWX0OxDm9U8+ZBtspVquQFXvee
+ iEhrPN8ms6/zKOqe71rhnS9da/9Gs+bDBSde
+ yARIDxYWRYSU5x2dR9nrWqWY+XIoqYI+vdqW
+ cg2HrHa5dCWzvI2MIcyp+A1m64g4pBF5xhUn
+ 9mOusmK7YLi22e472GXgtAWh2Nw= )
+ 86400 KX 20 kaku.google.com.
+ 86400 RRSIG KX 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ SBkT8DPqeIW8+qEVjgHRWJSdMqucv3bA/TBh
+ eNFVyp6u6VW0Dq2YRKIibVOqGYIAchFq5Ifp
+ YwqV8vZxskQQpmSgKKZhNYEtSoou3ORG3N27
+ ntyDCQY0f3j8+6N2xcI16TyhgDjP8WYKx2Mr
+ zWPyLHCfptWHL4OSKn4LmmxMeLQ= )
+ 86400 CERT 65534 65535 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45Ik
+ skceFGgiWCn/GxHhai6VAuHAoNUz4YoU1tVf
+ SCSqQYn6//11U6Nld80jEeC8aTrO+KKmCaY= )
+ 86400 RRSIG CERT 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ YqH31YUxUbrlLoyNCuHFLow01TqCqiflwGqK
+ nnjzEpHF5dbR8gkCHRp31UMed1WcoHxpoBeg
+ JfpD2yAqzyfATYaknu5s/l1zoYiOl+kU/pN7
+ PqquasRTNKzo9PSfD5NmXgLQ2I/hOjpxHNvy
+ NwT5VxCU5TKGIMZw1EA2Gfgw6pI= )
+ 86400 DNAME sub1.cnnic.cn.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ DXSCV9RKokxzfbsgvDXIRTpBvMpWK5FozrMY
+ giy7qDSoU3akrReo7O35psp2+8Rihvq5HyLJ
+ zAO0MMZXIyW2Bd2FxLfSxpLtAtDkdeQ1/waj
+ dDkK/dMkY5uz+rVFnt16/g2G7ShDyInc8Nlf
+ 4HH3nIU2YClg05mjeI3VtdRM5zM= )
+ 86400 APL 1:192.168.32.0/21 !1:192.168.38.0/28
+ 86400 RRSIG APL 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ If5+oBn2NU31TDxoKb6MusC5RFVX1hWah7OJ
+ oXHkP33tEU70Ovdh0n1JLPMjzdnedrspjYee
+ prQjpiW+/KaCfS7+xugXZ+45FWfzQm5Ocs+/
+ +iydvftx4RrwFLih0jUjVfBTodCpA1dLb0Z5
+ 9x5O8S1b6iAQZXyQLn8+0mCAN9w= )
+ 86400 SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7890 )
+ 86400 RRSIG SSHFP 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ PidCLCkvs9HUMw1w6bsUvdsT16a2mG2bQqhY
+ YqmUOnZ+cCntfnbcHFeQGHm2fGm7THqpPIL8
+ pwr0do+lV8Sf5YnWJer9p2KCFFsLpnZJUY5Z
+ UyRQkRm81dWPR2F7+huR8S78m9dEvoDisDDX
+ Fw5t3oSFLkco8N/vaDDThnp6dc0= )
+ 86400 IPSECKEY ( 10 1 2 192.0.2.3
+ AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6
+ BSGvgqt4AQ== )
+ 86400 RRSIG IPSECKEY 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ L8ztcLWUE8f53+4DMwE8nqQoJhVK6ywwamHZ
+ 2xltOoAzkZoYWxZsqvysxXlA8IxfG7nNYmPO
+ 0u0Ia3flUOQeI+xmAahxFCa5ztldTAfc2PkG
+ 7vMxa+qN/tubWZ77SWnxVml9xPBjPwtJ3kl8
+ tuRgiWwATeVXIinJGIr/Fl0r7Ik= )
+ 3600 NSEC _http._tcp.a.example.com. A WKS PTR HINFO MINFO MX TXT NSAP PX AAAA LOC SRV NAPTR KX CERT DNAME APL SSHFP IPSECKEY RRSIG NSEC DHCID SPF
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ w6YvWWARxQ761+8wUd+lcuW3KNibOGqCX2Kn
+ efA6I1OLq9KrAQY9KF5Qvn3u2xUBLt7p7ePl
+ cS/47WkRSysSJ18j1LnrAOyMKEUUBmZZq60J
+ P8j4Zvsspj5jjj6IwaU3EtNVravFmLzhku5s
+ /IbU1PvVvcaeGh7lnKs/0raKj+Q= )
+ 86400 DHCID ( AAIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 48830 190 32
+ 86400 RRSIG DHCID 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ BV2VsatEe1XAb3nUR68y0eg0HdgWzSMhfVJ9
+ w3rVj6Gccz/aJsLeBl+XFRqp8RzNvYVOkSTy
+ swWK4ddHJMng1SkdmR5e57/jSjjkqRtJ52us
+ AFgs+2/Up+0iAiaeyv9J/cW9EtXMxNJh0cKw
+ +OPdwi1Yy+kSCHS4qinfWHbRLF0= )
+ 86400 SPF "'sfasf'"
+ 86400 RRSIG SPF 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ GSHy+0Bwoe7ypHO4KBAMn2J3IoN60QR0mald
+ T8xdz0cBDR/T1EVTAeP0DAMEx+xW6E8NcOHJ
+ U3tnyR7yFmXEqMUl/2HKEZLxAQ9+sdJtVgy3
+ 9UzpygeXY43MYjPebSViPw/PUfQklXm8yyi/
+ VFGFnO8L+9zCaCwJpce5uGP+GRA= )
+test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com. 86400 IN A 192.168.1.10
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Q0zTGD3auYV/zpg18kfQlAugNsqdRqq0mVQs
+ ubZwjeVtUBjm2b96y6+h/BtxkPCKZbJrVGke
+ 44jTu0HCfLTuC8c0+OTpv6BXyi9XiFVfSl7Z
+ SnTM+mqfEDv3DlTmrGSmBuaCNnf+biMBUVdO
+ mCDpORNeLHJIwSApZsM9apJM0aM= )
+ 86400 WKS 218.241.108.5 6 23 25 53
+ 86400 RRSIG WKS 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ u4A5zuAlFFMfuVRSINxZKXIBM4Nm7okA9Wn1
+ 8kWv3K+Ec3xU82wxehQpk5qWagC4VCkNiEVw
+ WgDuvBsPcinueD+GdlNeVJ59wTKU6cqgj2nD
+ VqjB4EnSwadpqFuW+mMe8MJJYriJP+Tzolt2
+ kowEc9w15TYX3ITJNQqsRx9++Oc= )
+ 86400 PTR 2.1.226.159.cnnic.cn.
+ 86400 RRSIG PTR 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ k4DEnKmI20oKcU2oefuEhFI6axkTG+tnnl6O
+ rLKegw84qAqGT6GDKf7MCZrV1eGYR2PfjhPX
+ 9L+prQyWBKbqfPgWkzJ87mGwx8n9o9Q00URn
+ 4WDYgs7bSUyIPvzKvYHXkx+01kIhD+50BfHS
+ t69Z4Q6/PfTYwW7TfSOzuhLzPGs= )
+ 86400 HINFO "SHARP" "PC-1500 1983"
+ 86400 RRSIG HINFO 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ZCZilAKkXyQr9+hs/BlvS9zMdtpYNzbfx2dK
+ wznvSe/G63jthJufEA6N2K1rp7nWd9Z6Orob
+ dRZc1NfUIRlyD10/RQPSCFCxBg9OlHciTLQV
+ NW4KsS4kQanWTfC5DhZl6+dIy0GtNzedJdSX
+ V9PHPwJALlDBXcbsSLI3TkCrrDE= )
+ 86400 MINFO root63.cnnic.cn. error63.cnnic.cn.
+ 86400 RRSIG MINFO 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ f9NUDLDsNiu9icsi8YfmxhV02Fld7T4zptql
+ vipbGv3ovRWIOxOkFTXtz4dXVvnaZPy5IVFR
+ LbZWfFMmwsdDe/Z62BhGCfpva+e+jGpDso5X
+ t9r6JEnJKoY9d8RScTxYnh6EC6PYLxRVbdBN
+ cLaKVvZzJlI6eYdJtlBMGGr0jeU= )
+ 86400 MX 1 mail1.example.com.
+ 86400 RRSIG MX 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ QKs1t6oEUaG4p4icapLonCSxyNhwZl3DPsKm
+ KnIc5E39G1G3CNakvAPB+Ifatd/Rf/Z00Bo7
+ ChGSHeAx3fAKs4wpnM0DZNOf1D+2P94ZmIKi
+ nmadgIqAdejFWpZZP/GJq1nEyyfMlCKOIYdc
+ LMn2uM26K5SV/DrLgYU7mCiYKCk= )
+ 86400 TXT "kkkkkkkkkkkkkkkkkkkkkkkk"
+ 86400 RRSIG TXT 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Uenb1BTI/L347qz4Gxv0aZ1cHKGYIeAR/vtX
+ 7IVMEMys2aTdgVcShVmebZfpPPD/YIsEWvLF
+ u5LMbC4mSkzknkikmDCpI8sGPFHkWePxM5Re
+ gUMPPwd+3Vo42EPgrx5RuynPu93MJgN0EGuQ
+ pm6TS0xQ0XeCtjYpb30P1E/5K/4= )
+ 86400 NSAP 0x47000580ffff0000003210999911112222333344
+ 86400 RRSIG NSAP 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ a9jbOAcpAEnVMaLtCNrabbuBr65CzlhWfdBP
+ 5iG3nDi4R5UDg91u59emAHsad0CiKcryGo4R
+ GGjoTXkvirsw9huWxqNi1L6QKSU7b3kMRvBL
+ sG2RA/ivTo0rrwkWwuKDY7GFGVjfyIF4cBqK
+ tW70Iyql/rj9B8wLWRpVbLkgi9U= )
+ 86400 PX 10 ab.net2.it. O-ab.PRMD-net2.ADMDb.C-it.
+ 86400 RRSIG PX 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ krWoX+41uSgfMZaJP64PI1/z5nUHWgL0xGS9
+ uFUNJYhzv5MO6NFlwfs+10kXk/oHY8TwdvpC
+ ziFREwZUDYX3BWt80WZnch/zUA9tkldU505k
+ EjWHiDjyQ2NC15Dox+nAtkBz+XoINcepdBlr
+ uxCzzPwYgE4s23Sr0lnp4wQRTbY= )
+ 86400 AAAA 2001:dc7::2
+ 86400 RRSIG AAAA 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ PehLeS+MGsMJHjgJKPmptn/v2KA1yKDtTQ+P
+ sbK4QvaPz2S6H4tOBCYzvC0kwFoO0ZlReDQ6
+ IJBw86j7pQyHjspWsw3ut40210sIJjooAk/8
+ NGRUX1w2FKs1bxFLNj7CZia64dGsmTZdgCfR
+ UjHfmoLmuXMELzS6hWWvMWMnWvg= )
+ 86400 LOC 32 7 19.000 S 116 2 25.000 E 10.00m 1m 10000m 10m
+ 86400 RRSIG LOC 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ oV2omi7AMXSjzcjLSeSS5MeCdCed2vqrQGwy
+ HugFFpJyWn1pgrvFvKkLRlScLrL/naDe355i
+ /E7CxwtdYiBv5/n9sY4XA8j1aMCW9qoOb4Ei
+ 4PP24c2PwPrSP1FydcvoNQVuLd5ppDCC4aOB
+ fcb8mAJJ941nhSxihZTnrQeKwus= )
+ 86400 SRV 0 2 80 www.movie.edu.
+ 86400 RRSIG SRV 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ egtegXH6TootY47XJ4REvaZo9QQWOlcd7C/V
+ IDgfDu74QIPiDXtRNc/uXsNunBK2+R5bReoA
+ RPiO8Q+LxV9y63kJpY2Os6y3MQgjopO6WT8e
+ 814Jixx+5ObvLHee1Usac6dEH+4uUcPDugVL
+ PhQqKphpGPlFbdFEW6kCkDMBPxk= )
+ 86400 NAPTR 18 35 "Au" "siip+E2001U" "!^.*$!simmmp:information at cnnic.cn!" .
+ 86400 RRSIG NAPTR 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ kq7iyWWH6807fM9vOmP9nSGLjHU1VoEFHzGq
+ KYEDnqysgPbfdyQtr+omnG0gKxjDbQanJWUl
+ IG3b994/ruJeALSotx6hFdskQDQ4J+hU8Wuh
+ GrD0Zb6oZxME0hGn70ViJdAkc+qHMdSrH6e6
+ 7JazF0jmUhK1S7/EPvv68wPLcas= )
+ 86400 KX 20 kaku.google.com.
+ 86400 RRSIG KX 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ xVLr9xd5+UjL2g0Kir2DzHYzJSMMeg9X09DO
+ TutD4dDuCKVxUw81PRxPpps6Pdo++Bhh1Yd3
+ Nd9X5uM7kUBpmQeL2AY5zdOX8q6l/NZCW8/+
+ EXEnw6BOiQcT+eqyFAFEKBE6QfadbQ8eDCK9
+ ArRf4Ht/hctk+YVgW6bHh+WF4Zk= )
+ 86400 CERT 65534 65535 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45Ik
+ skceFGgiWCn/GxHhai6VAuHAoNUz4YoU1tVf
+ SCSqQYn6//11U6Nld80jEeC8aTrO+KKmCaY= )
+ 86400 RRSIG CERT 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ g1xXDzfVxOqpLVpaSoyD8ayuqHaJWJeC3q1Y
+ wuve/6oblmigWBJ8GpFUutNBF66xcBoGq47A
+ 5Wp3wTtFkh6uGPQCjGj165R8SRtwfNFMqEov
+ PkWQ3PjwzXuvvchAU90FpGAs6zbIfTpJ5CBY
+ f5A6NAjkWnMJcatsCgDZ03sAzRM= )
+ 86400 DNAME sub2.cnnic.cn.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ZGNJLjdUhhfQ0B4SJGACKtmFtXsJwbxeixB4
+ z1/6NW2cQmxRj04+oc3IVvIdysnCYIHgTJ6b
+ 249w4gxEg4kWXrwynH2Q2EALXDKXHtr5Sxv1
+ xypNN90HgeZIort0z0IHHf1KFGprVRpvhOoD
+ H7MKV3/IjxIG6hOfIkqRCORdAlg= )
+ 86400 APL 1:192.168.32.0/21 !1:192.168.38.0/28
+ 86400 RRSIG APL 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ vPoOy1Zm3riVKMtYRW3QhHhedDEleIUQwec8
+ 0vH2duS76faWAhPJ2OR5xyUo6rrNG8CyAirB
+ egV2nRb1m6yCvaOllaFkreftfh3gqtquy9Di
+ OTeGa2JUzx5ep0DZwLdTTEOMT8ZEy5HJI9a/
+ v/Gj55XfX1qpdTYcwNKk5fph044= )
+ 86400 SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7890 )
+ 86400 RRSIG SSHFP 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Bq0jac6ocgBfp1jVfoz0zuXUhZCInKuqRo6z
+ FME0kCDLlkdDdvmuzZ9wff+33IkUO0Zf6vgd
+ wp+Q7MOcFEQpQnAdJ2UWLFR3o1GA6VIycMLj
+ m5vVBHVafsGA5UVrUaPWQCBv0dFcywOxPhWq
+ N4ml4uyj2NxzKZDfVk71q/tl8FE= )
+ 3600 NSEC B1.example.com. A WKS PTR HINFO MINFO MX TXT NSAP PX AAAA LOC SRV NAPTR KX CERT DNAME APL SSHFP RRSIG NSEC DHCID SPF
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ MeXmHsliVtd/jfTmHHFMHMMx5IOU5upT6tfh
+ QvtLrHMgump6L7h4tPlWf7qu/RPORoK2ScHJ
+ 2WQ/vABTjpqRaPAZ3naf/C3NdvQNlxiF4QCt
+ qqozoDt/80SKBjCYSYYQUnPLVzuHlhEhVqa9
+ ZQiXMPDt81veOFBIfCzLipXres0= )
+ 86400 DHCID ( AAIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 48830 190 32
+ 86400 RRSIG DHCID 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Wb+zYKQqaL53cmm95v5TlojhNY10lBDrfm9B
+ uNu9IxNxwFFyoLKa1SX4f+vtwNlBJegUlGPa
+ DmSbyWEc99mJsrmF1Op5inC4zTxT+8YWc90c
+ 6S7poPNt3tm2E0RR4XJCq6X2yD20rUUE329G
+ oH1oTAn2kSaGTAn7M8tdLXnz92U= )
+ 86400 SPF "'asdfghjkl"
+ 86400 RRSIG SPF 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ o3Z3KK/4QQDSwRvOsMRyln15uzMKKi7z4lE4
+ AnMd2GIAJRUeSBNL7fEFf5QWX4XEMbZsZe4a
+ j1M+vM2Q+BkR72Qyd2Rgpo87JQ/hxjRFRetE
+ Y6sYfXJT0Ijm4TGk10PAsmS2M14CMhuOI15p
+ TbcAUkb7/KkpxQJ1NRkFbS/ecEE= )
+B1.example.com. 86400 IN CNAME A2.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ xMQqlscw/ifphV6hGrGaiEjfqEJCJ3Zh0eSd
+ VcSpVw7gH+MLraVt46XLoLdhEfAE0ZQy+AIn
+ xlZ+JkI5Hvn7esajI3K8RgJ3ojVEm6/wFmke
+ 8VazBgNTI6Zy36sy7Jf4LKrReDCOt9HpJWGw
+ sHqhrNiPg3KthOXDuBpoxKA1kMs= )
+ 3600 NSEC test.non-terminal.B1.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ vm+bqEPs23rL8rAuXudjU9nz/iadsrpRoJ59
+ ROTRA+k9Ekz6MlZ3pKT3bnQxbOq6v292qJeZ
+ 5QZDCf+yrxrJDvxtGzFTI8m0bq/jARGXNVbH
+ ukX9aYNNz3MoXfkQKroFF0xlngQ8MZ8qh+TG
+ t1xjI6GKU0MtdQ/iZ421DTCqwrU= )
+test.non-terminal.B1.example.com. 86400 IN CNAME A2.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ LFlxD9dqqHc/HMUDa+gSI0x2M3XzH0cgxe8q
+ WjGh9GvAnB9UP1fpvWM1iHtGJ1DAmQlpt1yj
+ F7HOwh+JOvqi78Gsl+kteE9wK/ByxJ/DCXhj
+ Sq772P22kYI7XTq03TdK5L5ndfxv5kSBBefj
+ BhSnulx4t1Ril1kGvq6TfFoww20= )
+ 3600 NSEC C.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ PN1EanRRN2EjhbwuS4j+icsaAlG8q2TquN1e
+ SDikRfzScbE+xv9UYObEKG64Ee0vmf7FbRhU
+ MT72kHNrBYgsoFS/eCn7xoB03UBZt48BPiKE
+ yR6BzCKSziPTpEGZNj+NNWdQVRPdbGU3MHAO
+ Jm0qec4CZOVOXkZG58TSGwdayDM= )
+test.non-terminal.C.example.com. 86400 IN CNAME A.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ YEuFEc9D8bozRPKXShr0B6O3HNAGT2KXMIQ4
+ 3QyyPQ8Qv7zV0ReUdwYukiVhSJ1Xstx7vk9k
+ uwtTtvEk+eqp5743sFnJO3gkoWtlTnfouG4j
+ Yk6JQoB7w0z+hgwsE+xKr1Z2bsnJ34otufNR
+ oejNWmnEwoSmRWg7xSI8lYrFjzE= )
+ 3600 NSEC C0.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ w07IQQxLsnQ8W+B47Fz2QoxFKWrclBl4+Lzz
+ NZ5Lp8u7XOiLiHPHXp/5938JPpUEb1ldcANE
+ vKBz5fhNFNriSYa/WfV/JTGRv9UnilPepv9Y
+ cas6TNMdz/y3QUazB1bzkwnbKLoMklubRVPN
+ QgBLndRN/hSqaZ/2ePNE95kfZck= )
+C0.example.com. 86400 IN CNAME C1.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ eSc7WW63CbLiH+2kG9YcP/f1E3zNPSFy2CDe
+ dTeZ/FsyoxsOVVEKBUcaIgndTtJNUCk26GPR
+ 9dwLYxsEvdZZ1tKbfHlkqlmGAu4nzdetGLtK
+ uOpMdFboNEgh8AXB2phRn0EJNsuhHQFBmX9W
+ pjN01eJksOOSv/znnrBReFObbaY= )
+ 3600 NSEC test.non-terminal.C0.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ pZtzNxFYvEv34K+8Gi6fwr5SOAEDsshZ13tM
+ tW9Sr0oM3Ea9AAjfKd66eYbLF6nq/FOYQRfp
+ t56NX2zYtT019mX1KbEouoAJCrkcmnns4aTc
+ unQE9yGMk8moKXwRH+rQSflemTHO9aeD1SVv
+ It8kxXfalR3otJIrr1HdYvXPVv4= )
+test.non-terminal.C0.example.com. 86400 IN CNAME C1.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ szsFYsg8E77ew6WNUuLIqnDrGz1l6OuxP5TM
+ woVGsDwGc7E6gbzbcXMTNPKSSDLa7dchjKv7
+ Kd+ORNcCVBu8qtos7/TfpSsH0hbea0k2E7EO
+ U3QeZ8EsNCd3MSXBLpn1016/+EUGML5U3dRs
+ kmcWyT/iM86rpz6Gby4KPIcULlU= )
+ 3600 NSEC C1.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ UJxr9cwrOEfFo3dd32fV5YJ3FM4TqyqEBeBk
+ WKU+Z7Uc2x6+U5EO2GDY0Qj8jVEwVugZ53V2
+ hwh+85CuwfbFX5LkCLbmSOH3jte5SdHAdayL
+ s1iDNJ7hCji86n8bIZzmBsxlRgC9swfwO0vk
+ YjHGuigrb/Cv4XnYnr4PuTnBgP0= )
+C1.example.com. 86400 IN CNAME C2.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ KZy5KO3IZZ/9PbyHj8DEas8yJW9bJTcyFbb/
+ fC3kk6iBhkmcKfdK3fF1M6ARf7DC0uoQfEcz
+ RSoaVn2Eb5EMEEriPSFvUk5GxDObLM0fhLS3
+ E/H13bdXR4v4swxkV+0PBQQiu1GEK0WRoXVm
+ C6dF3pM4JYEtRgqc/RxY82s+Mks= )
+ 3600 NSEC test.non-terminal.C1.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ KJNedKMxaPWxtwSKthu6+vanXp4Sc5vMvgxs
+ UObrVIhoxTUvcy+pOD7x0/bQtQYUILfwO4X9
+ HXElIDqA/XENZKjb+PQoD/Yz0G/63mBAHYEi
+ VSdUGCmbdNJ8LTkr/mJSLBmdP3xo23Fv+uIZ
+ lkErdo/LHUT1n2Y5tmfyvmUvwAw= )
+test.non-terminal.C1.example.com. 86400 IN CNAME C2.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ h3NccjYD8iWBjbbKf58ksZtm9a4FJxWqcLsl
+ RUytSY27B5mC+R6Pyf4s/pzYPIGioubmnYAO
+ kU0of8wQ5r0HA7Fuwm1OU3xVJVVOtRBb5OhS
+ bShf6S4uanb6oYgModWWdkuo3fFP5uQIT06n
+ 6/kC13Q6XCprmhjzfuQB4j0T1Rc= )
+ 3600 NSEC C10.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ rjjq6NZ1RSwBrNgpNAFbsgi6RCLQ4Os8DhQ0
+ NblY+u/XuzVC0QvRERNY+mUFsKP6BpKcjFSn
+ mZnwUB33qEh4F4kVwaFPToSYSOQLlODWClEy
+ gM6+2xZ5eJzLj3tnZ3PipI/hY1DdOAhuvCZi
+ 8fJIDi52+nH+CoddYKn/V9LUgrE= )
+C10.example.com. 86400 IN CNAME C11.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ QfKnR859+8/BBOKUnTxi7LKj6Pf7hzYFUNV9
+ xuNJaIHrWGAWixW8zcgd2EfEk9ec47UHP3TS
+ +opYiujwFRLbOcU56Qn8dffBU43fWSaQ74ra
+ tKqgq7U8qpMc3567CqdZKINqMQQaJSpw6Gu0
+ kHbc2X01ZEJFecUQuGzv73sXrzw= )
+ 3600 NSEC test.non-terminal.C10.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ g5GR8P3cLs7xX4R5imA1qoklOXvj7bcyj5FX
+ xz6qcnKudO+iivT5+Tp8wbxv9RXzgurndozI
+ q/g/PiSt+NWV4R4A+kqhCuZuBQ1QZfRPGqAz
+ PSCpQ4pko8jJC0qAMGZ9SdM1R0s1aMEaIcg5
+ YMQd7U9zDVgWXOW7q1L54eLuwX8= )
+test.non-terminal.C10.example.com. 86400 IN CNAME C11.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ afPyrqIU9RdgUUrraxxzvqY3b1PWPI1AhZpv
+ W/u8BU9UzBGlEyGSIO42D8qmwgJ3KPiNy/2M
+ 55orqBYqKtjWHjuxZHpwRTvz+r4q/v0AEyV/
+ pPNHZg0Nw5J47CulFYiYhw0j+xKf0oLzXXCD
+ ndgvR8m79JZy1crI2LJqRTwQKiY= )
+ 3600 NSEC C11.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ r0Af/Nk6Kvnx1egV4d1uIKR2Wz3AjGbpuXSF
+ DcYZvIK0OqpT3eLbpHOWi1+hWsqf1lBsXQaC
+ si+rBLnEMlJfTQbvLHJ2z28/1CTFu4cb+wMm
+ 37P2Ss6sJhv9iTz392llnoQ97kkpmUxMKdeC
+ fOsehff6le3ZMpNhVBROdLoeXaQ= )
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com. 86400 IN A 192.168.1.10
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ CNvJP68kKf1Th5pvbU08zEWfDsY3mKbom/fy
+ gOJhbQ7SvZhWom9e5eNj4B+tsnoUGM5DheoC
+ RWdTMtaj7dyGGdM8HvyReVgb2841VcpaDPmV
+ RnniANnePU7rZeN89BUqat5lrOu2At5pVnz1
+ BBqMxzobM9isuJzFYpZUsn3QO6Y= )
+ 86400 WKS 218.241.108.5 6 23 25 53
+ 86400 RRSIG WKS 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ kxFeJoJ6fkNBZ/wzqK1CEK0eOQK+R9SBi6eW
+ cFii6EJRcAlwoD+zneCAoXpcBoqOFGxbVCQB
+ F+P7qXStE40WvDn6KyrLpFoqJYRBzSC430ov
+ KT/2OVhkJrzypYAm91zoxo4EC2iPT4BYyyv7
+ axx7ABNnDcnuPA3ox6heXG3Fenk= )
+ 86400 PTR 2.1.226.159.cnnic.cn.
+ 86400 RRSIG PTR 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Xh4hhbpAtHKUg4JiUx5Lnp2i8GBbjrDnLY1z
+ Ga7Y0rJfzqK3BETsyjjJyvkjQSXiGju0+I38
+ mwc34rZTVxmx6wFd9V9oK74T9nPodQdmqOYu
+ dEMdEk1rfMCA7pvj9pbiMpGOZRHdZ4KT2mMc
+ MrQtVRJh3kFhuLhRDAT9Xa3/NE8= )
+ 86400 HINFO "SHARP" "PC-1500 1983"
+ 86400 RRSIG HINFO 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ fuakGfnFU5L6F+novql1ep/d03IiLQGNwvew
+ GvVuNpVKjTWmUi5DIpBJT9MkPjk2mdo1FKWO
+ gRBvkLU82/6dyA9wjzq3vbinVvD3f5+iUPqu
+ uvDXgzlQaT8k5bVkNHtwCfJXbjw4Vc4/8omi
+ gkTnl8Jdf6VmCShXrZ2Y6TK5uzY= )
+ 86400 MINFO root63.cnnic.cn. error63.cnnic.cn.
+ 86400 RRSIG MINFO 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ WJylyrzRUPDYqF36lOX6BM57HWvzzE/2dXJY
+ xSua252Pk1UZrN9yiDJRttQTmqkU3DxtE1KB
+ vOkCsdOc8R3dr8BsgN8m2PQAvCQY8cuqDG31
+ le4yKF9DE0BcdXbu3Ic5bp3huSY4iuaiutvA
+ fuovrtzelaUUvhkZYA9+0EHy4JQ= )
+ 86400 MX 1 mail1.example.com.
+ 86400 RRSIG MX 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ dRQ0vpIrS+qhzSOnmbiiJqdyOLCTjlp2LdV+
+ dSTcplTwtRRYcW9/MUoDzh2kfEk5m3loSrH5
+ 7HrsMlt8d2chhCJo/tF4radCDBTZuK7i+OEv
+ P17QFhd6DMw5S9dEM/o5j1ijUZv7/QgsbjbF
+ 6Unv34bQSidfUqi0JoC5O+VuGLk= )
+ 86400 TXT "kkkkkkkkkkkkkkkkkkkkkkkk"
+ 86400 RRSIG TXT 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ziSZV9Y3JQ7zh3h50cymTtW0tzJE3i9CLO0c
+ ofJJaHBP1Mx82MMRDMS4tNejRpY/vYUFwrrb
+ y7H6vUTWJFHH4DhqNQrqndZbqxLatuUtkmEH
+ raIs2zUYMIgS2aT96E23+kTmPIXDGvIQ0SVG
+ d8vDsm0wnpz9OL0R/1pv17hRIg8= )
+ 86400 NSAP 0x47000580ffff0000003210999911112222333344
+ 86400 RRSIG NSAP 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Eyj3aQnd4lBNfUtxZpPlEFFTZUYGiBrnX25r
+ PHgK55h5M226SWWtyv/JYtJjcMntHqq7fbON
+ r/8NKCO6dAZra5LYtdRLVO6t7lJBxsWHI6ce
+ cDTVE3PWxk1niK9LBCwdckOwONp635Iukmbt
+ sdfEadu9Aw9BMmOT83QUJyjW3f4= )
+ 86400 PX 10 ab.net2.it. O-ab.PRMD-net2.ADMDb.C-it.
+ 86400 RRSIG PX 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ TEIjyOUWJ6OaOHnRSus3ytt+p5R/t0PnPJwd
+ TyfYrLfXaA2z9G4L7OWcT3z7wf8g55WVR28p
+ PmXiTBNL6LFQH+1ASX+YaDZNx6Dc2b7bOKql
+ 5dIccxMLWi/jiWEaPp/y58Pz9t/qOF9ZNGVg
+ +w+Rul+6HaX6Dc53uokFKc2xtKA= )
+ 86400 AAAA 2001:dc7::2
+ 86400 RRSIG AAAA 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ sqigB9U+/ncUGao2Eai2Ykkyx8cZfbPcWy5l
+ 9771JB4coWudFuK6gj9dXowjgHtN+1VulzQ0
+ vSUM0GIZjGcJe8hXrQsOOClQls75z5bVYVTR
+ 0Mu1t5nXhPtCD1mgzyzStHtC4jiXmyAw3K2U
+ G1UJFlHYzZyBYQMLx0qLC+gRS+M= )
+ 86400 LOC 32 7 19.000 S 116 2 25.000 E 10.00m 1m 10000m 10m
+ 86400 RRSIG LOC 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ wM51Zvyo9rTgJ3GokcU+AKxZGiDQDuMGuo/V
+ P/sa9nlHSoNIL885Qzbdn91Ur0NFReQAo+9m
+ s60Jk8S0eCafQrlKit9/fPBMZuO/7HDnkavG
+ QiIe1GvIZPQwqaj0z31MpMG7TqF3wi/c0NlY
+ qz8VfjrkNoEEZGIzJFJ/EWghLK8= )
+ 86400 SRV 0 2 80 www.movie.edu.
+ 86400 RRSIG SRV 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ XAb5QB77kd8LUWKP6k8DshtBvKSR1n6HtS4t
+ qSic2+Cek9sldt3h9KAy5gL3LwzWUVRHprJC
+ KthF2ZTlA79uoRLbiBpA5lnmanDArO9+Csz9
+ FMj2zRG7bQIpichZIJbGBgzsidnE6cuCsrXQ
+ j8RqPdPYuBL8hBIdKpW+24YhXEw= )
+ 86400 NAPTR 18 35 "Au" "siip+E2001U" "!^.*$!simmmp:information at cnnic.cn!" .
+ 86400 RRSIG NAPTR 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ iv9JeJd/Z/4ASBeZj7yWIPxL4SnvEGJQuONm
+ hqvmxr7QtvltBhlGZnYZj8rBixrc8A9lubjK
+ W3Li4/QCF5CJ/ivoeTLQzn1Ca/hMpPLMJ4/N
+ WfQoeOzn4n+4fVIrsVfbdVM7rJV6+d2nHQaE
+ 79uwSTwm1pja2jkMtVo2/9AgYw0= )
+ 86400 KX 20 kaku.google.com.
+ 86400 RRSIG KX 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ qPQPZDruP4UD7ORY7dw3hdWHVD8MllW/DEj4
+ WYi3F4eYolclA7u/9cebt8UJii8cigY+24TI
+ sbfRIIqvkhOg+UjBtiUQsj7x0XxQXEbim571
+ aj2HLvBHO6I991c6ndatShQ3d0jYNyE1qhCD
+ v9i1SkmjfuSRVWiIdpQLUO9qz40= )
+ 86400 CERT 65534 65535 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45Ik
+ skceFGgiWCn/GxHhai6VAuHAoNUz4YoU1tVf
+ SCSqQYn6//11U6Nld80jEeC8aTrO+KKmCaY= )
+ 86400 RRSIG CERT 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ YM+IPkTYsPTqNajmdirxCd7NRCB82AtDIYgc
+ qn6vCRGM/2v6vb+tciYnRl85uoAGysS+bmiF
+ lqB4OGCydIVhS4KTMXwDPPf1d91nqy8BWz7Y
+ ei+B2qhTnSGQu96sSBdJ2ceU6E4/6/u6LY5a
+ lAVt8Vk0B2WjTAjUi0VIDqhL3HU= )
+ 86400 DNAME sub2.cnnic.cn.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ SBDS/nWt3HswZJxW2jRGzCsYgxCBofEeuhbq
+ QmNSGR2bHojp59AYZR00B3aAOdA0RGhdZKuU
+ yLCqNdFyDmasGtdc7CP1Bd6Ey0hVCM9wbLV8
+ QaOWo/vgsWcNFMAAxR7YqUfiRaTJLV+IouDH
+ uHodkILrgsOqpXvdGaZLe3wTQPI= )
+ 86400 APL 1:192.168.32.0/21 !1:192.168.38.0/28
+ 86400 RRSIG APL 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ VEqPOVp4Nc02haMJeh4YTHDoVGmuTt6cz1fo
+ Lp89B62/L1KGFHXE6FrB01fLcwT43FbOHVLA
+ zi4szJ9YBC+rqSbVBwm1lo/TskBTA0VLrbEP
+ 9iEYpPtqn03I1upG44cdfcXyNKx3fZGEOeaw
+ TJL9dff4O08LCvJlKj8DkpZ4Jgs= )
+ 86400 SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7890 )
+ 86400 RRSIG SSHFP 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ oyelf6+jY+6hoW4151v7TP+9er86PVXpd48R
+ m0o0pxU4ICOR4fvc55BVrseXAzI9gGCgX5Xd
+ bRIVuLP9+8qxQ+lGJHNn6y5916awS+RPVWeh
+ dAJvOF+xnNjSiO2JXfGuM5jXrawr4/mrwzK+
+ YKGzMSsqeqDA+V1NOYvfzM9CamQ= )
+ 86400 IPSECKEY ( 10 1 2 192.0.2.3
+ AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6
+ BSGvgqt4AQ== )
+ 86400 RRSIG IPSECKEY 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ZDlc09VMM2ctWqF6pLelK7xOKjQl3KRb1pk0
+ W7tmrHh7TZb+0KkwkNl3LxRA75/xLPqlU/ts
+ iV8zEh7gM7XEv6t98+eqRo9XwIJKeKRo9Dbi
+ F+2EP5q2B/Ja/T9g1aYx84CIe4pNV5lwxFTc
+ RYCAnMs9p+w6di+bVFUkxT9MISs= )
+ 3600 NSEC test.non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com. A WKS PTR HINFO MINFO MX TXT NSAP PX AAAA LOC SRV NAPTR KX CERT DNAME APL SSHFP IPSECKEY RRSIG NSEC DHCID SPF
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ zrLyk32zZZwqj4EUGGH03gVAyksBeBYAQMpp
+ yH3MGvQniG4o+VvCw6WR4TgmErskBhhOZ/Ky
+ GtFqN2Uorcl8bJnMYVgQHRC14cPXEYzIRdz7
+ R3/GkEiyoYKrgsbPzLU9HTZoa6l/0Gr6thzs
+ ruZZwhavLR9Y66O5Q/PU/4S0oeU= )
+ 86400 DHCID ( AAIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 48830 190 32
+ 86400 RRSIG DHCID 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ u7CgSI0G8k62LtPdEPwhu7y+TMIpxVM3IO6T
+ ZhbPR2/6rMez4b5GdNbLkXs5K4mxz3Q5JiUM
+ SNSq+l83GXl3n2qKQzgfKCAyK+4E5/lI799h
+ VPnMjdSjQpUr3SBPqYKVb2mT3zXrYxksp6IT
+ b9m6FzNlGWCC90yY1d+nGT3x8bU= )
+ 86400 SPF "'asdfghjkl"
+ 86400 RRSIG SPF 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ CqVJZgqFQKjUOGfIzuMvoSlSzKhwP7l4kQX4
+ ayUrpMnqaHyQfHJxni/tfa9OwvxExfnY/B/c
+ vh98DFNmAc8FOPAMH6PLiZfxVzDX5Sgi0RrZ
+ +GYDccb7rAP7FsUAcsFreLyKFUTCycVQ7Rj4
+ OK48YTA5EG2cKpFc5dxq6+//RHg= )
+C.example.com. 86400 IN CNAME A.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ JeFX32cJ7aBtb4rUwhcOjmtn5/bG0yEJhyt0
+ n2xJPs2SMZyBvsVJP/9sAhpIu8zSXo1l5Cyo
+ aI6zwonJmnmyHU76jgXjSq0aom6cu6paxzEW
+ fhTbGGfCQ7NsPKgZr+TGNC+cfM8my4+yythX
+ +YDqKajBegulcAsHzEgYWmUoVx4= )
+ 3600 NSEC test.non-terminal.C.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ JqmFzLtyfWfcHMKC5k+5Jrf4DqXCg8PBpq7I
+ wv7ifztFYfg5VhXnp28hrE8QqSfLYv17CzNc
+ TH3hDhqAldwsjPG0vyhQB67zGkOYVk0FbfWW
+ GiY7sP59aKv3ZI27ZhJmf6uA8WotkD2QjCYc
+ XV8x7qTErkf/vi1UiGgMsS3WtuI= )
+C12.example.com. 86400 IN CNAME C13.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ydvCKZnNj+3eaicVopOYSqklt++EOi9eKEcY
+ rD5KZM3trEPRM9RAQuVx1U6/JOnvX7EkgMEx
+ x6FvA4mIS86H87N6R//CSc3ngOy7QU7sSZ2Z
+ f/x7WbOaqCfjYRsxeKkzuIGati5yraxhowkm
+ OHR9XwB0d4ZlX68mOFXuI+ENGXs= )
+ 3600 NSEC test.non-terminal.C12.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ iq36ylDsI3HYqZc2Fu762yVwg7eUm0SMceM+
+ x8xOWdDvR9Yt/hbZDGKLRHGby0TEZgWkERbV
+ CWbcCZWyOdyhB/b/ZSkjL9vM8S9fIODqOPXa
+ azbwjgV2T/kJeJSoxA+ocJLdRZynsBpHpk0Z
+ 6NKTtvCIwPDP5W39S511mXl22kA= )
+test.non-terminal.C12.example.com. 86400 IN CNAME C13.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ wOnjiR6iShlEBNMYQBZMFRPlOvLnd5kn4TqU
+ 01AwGBdIRUm4dSpmIT8LQc1/xiE7QzyfXdkr
+ UsFtSRGaPG0NsUTRz8tIecfsLZNssJUDyg0h
+ puEiTnampZMmHW2NYnPHq5gkKLWeDuan7hZi
+ JRgMAWApVJyYDmE8rY5pbcrFnoE= )
+ 3600 NSEC C13.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ g8p7p9I+6D1fN6mj20dNRAyb1G8Thg7rCZXZ
+ xmgkdEu48imlNVR9sgX3aO6GL9v7BUNc7Vt4
+ 3tyx8y2nSdkM1aGTYpt2DfaiTtYDMlNbPONb
+ 9/i+3LpzDWzczCAdCxWNHtoCDcPi1w+Q76AL
+ DPtARgFO08OeAVtfkSdJu8+a0Gc= )
+C13.example.com. 86400 IN CNAME C14.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ SDz4/RI39SKfiE3EJ9RRn6FfLw8ZPB9DzE4V
+ a0VOrTiYS3KxvJqkBEUwFH2oJfnkc8b5HMpj
+ ECC0ifDLrwsRctXfpw39EEiwQ7n4bccBj9L5
+ 9fhNvBYn+qIWRILSFj3cA3qL6gvPRNTGZHQA
+ ENgwtF5/b6bHIpDb0UFzvIK4L7w= )
+ 3600 NSEC test.non-terminal.C13.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ QoBrwTsEMKvZrWVWOjLO2gJ+X2G6pxwZZMGT
+ /m72nrpeIiYNL10V3/3Chtw0bDVfzUapOdfk
+ weM/i8qpYWxpznWbd+c03tXTqqi5gCIVfRcN
+ 3k5nQxX2nS2mC3oBcmI8BzMi7wX/boNTczGd
+ EmqbnrGnn4qn2vz2tduiwW804io= )
+test.non-terminal.C13.example.com. 86400 IN CNAME C14.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ z8p6Mh7YjvAjBOZhi04dAP/phrBoWSavdj8/
+ RHBgzyOyeG6hRvmmaZPx0GPcHEDI0xMv+H3L
+ tdoMlrMKF3U74u93xsf3B3SAmE65oSISunYC
+ 9R/UNE772S+ga6FU8ufjY0/EFFjctj13RiKk
+ 9Kndb0e5RdWXKApB0N/haIe3fPM= )
+ 3600 NSEC C14.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Na8tko+ZwvXp0z4figIvFX5tqflE99k1RYtb
+ RkhDzZze1S1+nLS+c+NgKrty2PowiWNgTGbP
+ EB6SgLn0NkF/I5a7pl8lrXcgg34leuhinFT7
+ pBD+3ampYx8LGt/2uBfUg6clrnbOkIxsf8aS
+ GVQyRV2z9cRN9DfKBmtkSBoP8zU= )
+C14.example.com. 86400 IN CNAME C15.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ hlmobxbczJOv/RjwIvLccuRRdIxZ4IJghtlR
+ 5dTJ4YLeu9IwCo4eZlLoR3uXRv7hqbIS8mhr
+ n8eqcWnTaFRWJ4G1dRwx8d5YaN5ATgxnH4g7
+ CDTOZAAY8/cS7Ybr+abPVLay20y2Iheq6eOK
+ +dWRCJpgVnEM4zUHrS3XOOVkx2U= )
+ 3600 NSEC test.non-terminal.C14.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ m0JRA/8wf4QtKtI7BGBw31uebJCj+5RQLKx9
+ sBvdjCL1yK9n6kp0OuapzxJUcC3kL/jb47MC
+ CyJtKcc65Ocoj4jGds8Kp7yNrDjIAb7WJmds
+ HnpQcgNyGgQHqkiEuAPwhulHjdIV+NKcPXec
+ 4FnRRErGq8DYg5qPXIguPmeyvwI= )
+test.non-terminal.C14.example.com. 86400 IN CNAME C15.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ QQ5yqUlmn9mgtmacEw9xEQMAh8Ecr92SWROk
+ cVrWavhQfSsSDSmM4ftlHjLHFZiJ7YZxa3F/
+ 13IHGcHesFaKNicknyzJNvqHJvkVvDkLDnt/
+ uos7G/+WDskV8QOZ/OkVWZwYuNlw40z0ex5Y
+ 3miSs89/A192AgVGK11YinQPL2o= )
+ 3600 NSEC C15.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Ly5nI7uorIvY3o8mcDgVRQQnxiFLAZjYRlIB
+ aVD/ldd2iSy8AG2hfocWXHhLbXzO3CTjXjax
+ 36TwLR41UpuqXURTG0Qzfyq0WPej4irAwdac
+ O0JV6gc9JJHFKOQ2kWFN05cBKJyjk/h/3y3B
+ gfv4icRVezRM21p5oy9zKSSP7fM= )
+C15.example.com. 86400 IN CNAME C16.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ xvrk7027MrYKIUHknMmn5TX9F2LMRE1n7Ujb
+ VM1e0OwWWrlnInqvRqs64P1mTdast3q7KzOU
+ n6WSNvIyJtVkJLFnFL2dtm+lsUpkh9tJKyzE
+ DyNPn5PVPya85Yo+P+LQd08k/RhCPgSpe2IO
+ 4GIPCZWVnnNBZQeMgLbIEMm5yHs= )
+ 3600 NSEC test.non-terminal.C15.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Vx6oWYWNXU8lvZbcdFpR2gZlfdabwOz131U3
+ fuQ25ftTekNfDn896eXhwRi2II8LyraUvWDm
+ Bo6PqzqlDdeHyExHYywZ7wqoGZP8afrqLMNQ
+ pLnv9U+ZyXnYoot4A7uhYm6d3ho1yTyneXn+
+ CWWZOcw/ZRON+xWMwFjNXZZPabY= )
+C11.example.com. 86400 IN CNAME C12.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ VY2iUA8etZcNv4qMVtrvN6U+PO6irU2pET/o
+ rufaMqlq7TMryp9mdd/1Ef235TqjSGDT7NqL
+ VAMvtgVvsHTuFCeWIMuDkVEe7KXjdRrYK9a8
+ WohgExsI26dPMy0R/JGtPmeTTSIiS00SjVk9
+ wdCQjSbZ0xl/T07rZZ9fu8BaVvY= )
+ 3600 NSEC test.non-terminal.C11.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ QUm2o5cNBZNmZe0sJ8kS8sgUJga4HXerSgxv
+ WKx0ofCTl7N1J8tNYH9U5KmeZ7fu+lk537aU
+ bmB8CftQX2GxjA8pIxpaEn+Ublf6FIcMtsWM
+ F0MPf9ZXPgbL+Q15RLVX3KbMuXTLuFogUYPL
+ BetQ8cYF77EK7iNKwcMRoKCvIDc= )
+test.non-terminal.C11.example.com. 86400 IN CNAME C12.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ OHWsmRgm1zSThs8F7BZWYghWHBR0kQsj5FIr
+ CP03dzgXwz2UNFYRLcZM9YYc4f8xCQh5IO/9
+ mu8oj+py6zIqbsUsSymsUomT3+JR8UoZ3aeq
+ 2t/YJ7I6LDowZF+KOp02QgOJAl+sEe0ah9vw
+ MbOnwBYlHv40GE80gjsCmzOezuA= )
+ 3600 NSEC C12.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ HefpT1HMMFFsQFpMlqTZ6v9ZtFw8IdSoHVBJ
+ nRnJujLODn4N20eWEbIN8FLlSY4apd/mnE6/
+ dKqSgT7zFTVzGf2KE6iXlnC4xOWZ37LqOS1y
+ JsfQCe3Ryw/l/bbVynhMq64pEL6yCeX6HXt0
+ MFDq3x/9yU7A+DWAS3cEDLBN/Qs= )
+test.non-terminal.C16.example.com. 86400 IN CNAME C17.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Lotbl0F3UliW5IPKJL9SOuYXkqouvoaFmblQ
+ KD091v192vQqUDadt1V2KS8TehyIvoc2XF6n
+ lluDceffB5DRYdGhmC0hEtEilkPaik86lKoU
+ Bx3dSn6K70L+hArtRM7nPTSBY3kEmqcC8jN1
+ JiLR6KRIw5HbFcwHvcQTjdEtlto= )
+ 3600 NSEC C17.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ lkK8Fo2AlF4KnoOPBWV74/8KErQ/6A5qecft
+ Fop4nBvpejfm/M5Y/ABExo7wTyd4E3ZKoMVw
+ ueGQJ/YpuuhPxZOnl8EQFIobNJc7VGZMBwuk
+ UJpVBesp284nVI3bBenuutFZiZk1pQTou1dX
+ m0ei7lYhiavsG4eBSZgZu5nwcUU= )
+C17.example.com. 86400 IN CNAME C18.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ HM2B4S1E3fDwYps9fmPTvONEumtH5mYW+mFK
+ s7W1Kk+E5igkwk4T+eF5BxmGrq2Bq2XIC81S
+ 8USbaYiKzgGuZiiVRg36EotVq98AGFFdgxKU
+ GBy6qjpZBuXNIMZKudsKLOiAK0Sf83xbPw6p
+ BTqhxAlgJsOhu++dDjo1IKhlMQk= )
+ 3600 NSEC test.non-terminal.C17.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ t3N8fQf6TkQW6CIYqao2sYsDGst7YTz6EwIy
+ RGuUz4opWh0S98zCflxkwZ/aIyiaZ8My4502
+ +8LWZ/mXF3E/M5ZjZwnCOk4OdvYcnf/hGBRO
+ +OpAlaWTpj5Bnqr4yqKgo8sayo3sGd8GHO2M
+ KxBXHkRBs29zEoxcWpcRLfr4Bu4= )
+test.non-terminal.C17.example.com. 86400 IN CNAME C18.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ zwLtl1GpP83GN0jN9Gbg/GU3MESgLafA8ttI
+ z+/SgZewG0d3vJc31g/QAGZBhtfAwwgwJlbS
+ 46i05026B7gBpQtdK4RG3l5gM/s4e+mg4xF9
+ i4n5reqqxfmATmTT8u3OlL4aCxfsmUlgSQor
+ WaBoy5mTRh2PuV/2hSkpCGVaY5E= )
+ 3600 NSEC C18.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ tLTNHgrQVp+b/hZLlsUT3nUopRPNqkWfrKa/
+ xO5+Bdpw1VTo05kmGagKmwfMrH0wtOiyjhZE
+ yEkSpAfolVojPw4oDRp4eK+toWwecnkXb4H2
+ E0EWnJJ0BJy1DZeB/qQRQowzE33kQ4KYAjJn
+ 2mmNHFH09qcgq/AFOIsBAYKDVcw= )
+C18.example.com. 86400 IN CNAME C19.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ KoMMbFb+ylh3p1s6JMPBkc5csxvEKd/Z+pLh
+ 3sfb9ImkqqBMnwBQ3sCb4HTenqC8nUJGp2UZ
+ pK/KblgXDTJpt+pC6Mu19TiBmTUZTfJtcetx
+ Z6Me8cjXw5e7/jGToKWE+E+b8sK6amH89Y8g
+ MmAG4bjG797YgIHAE1GgIhYnPR0= )
+ 3600 NSEC test.non-terminal.C18.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Jt2JVG/TPDhXrRtt8x7aYeCBZyr1GprcmlkW
+ SHwdatCkYnckrs4k9xJqKag4EneiDO8sVy29
+ J0WrZDweOasI6LQq5Uh433TrfunUqFRoj7Yp
+ 0Q200jlZpuvHvY0nGXBQeXSWNURNrGZ2Lmt5
+ vTXt/Iu19dWk3DmUijKR1/LqRA0= )
+test.non-terminal.C18.example.com. 86400 IN CNAME C19.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ XLoGu1RuEmIXDuxkqGeIgd5CVX8Z6xc1Bu+i
+ zrgboAj2BHbUmnxPht874ydyMgVD8gbzkGa6
+ Zsh+jG9SILdk37U2HptBQYW1Umj+HvIM6E7q
+ TFVUMe1/OLj619V/HqCXUTjW61MhiHTolPcF
+ 6XLEv+n4xwMY/Or9X5UELmV+1EM= )
+ 3600 NSEC C19.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ oIzaSmiBiPOKv2gsFyD0m2tGyNNzqmoHPUVs
+ idIenLp1uMuGOnz/uhsdsm6t/EFvkU4R43sa
+ tYeCKhJwRKPlA4mMjmPm3NzBgLPrd95Wlj27
+ PupY++Lh4EV9Br61jmWKxQeVnP9hxHaOmOp8
+ Y7OQvVAjvx9iQqCUIkck1BKLB20= )
+C19.example.com. 86400 IN CNAME C20.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ k1mkYGbVDvKjvrQdcnYxqbpJfAQWJISo34Gz
+ IlBrRYiba5f5cWPoN8oMJ843DwoXlSK/OPzE
+ JnnIkfuf5KbOP/3W655dhBLutsT5G38YZcTN
+ E2thTk3R7uYAJWrOfGCSC+csRlpHklVwurSg
+ YUBuN/wE1oi/Cc3y1c2+bZq4AZ8= )
+ 3600 NSEC test.non-terminal.C19.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ FTop6JDiTZ3GtheHGkIV6/tXXjZcCr8CPDYN
+ UZ1pfbc/RFX11X6TZ83H609AMn1oWOcTUKHG
+ SfYLh/amBnesJp9KnGbUrhsHRSK/kV4PTDB6
+ YWdYVDtG1oKzhhcVXL4XmWUd+iIvvVqnk8T9
+ soD8e9GOvmA/GfUkWKkMnEICNTM= )
+test.non-terminal.C19.example.com. 86400 IN CNAME C20.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ enAAqg9puOt2xaStJb64WyKdl6G8HBKR5Gz2
+ W8TdA0RoQzwA4BC3XSfdRgeUkSzOibJdvNKd
+ l4xreSSAzg6G1tBsoAHtNscK9ef9QjrjVQZ1
+ vyN5jJxcxXX/UBOmYfJ5B9ZbqKHnb4DK/2t7
+ agFAzUuTsVKTsYi0MXSdPXknYMU= )
+ 3600 NSEC C2.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ HMkTP0BU2mdNcvqgllQ/ic+nmiI6538k5Bsy
+ vazQu5d8y4yPPMVY9AqdJxgFeRu8YRJOSir+
+ nWTuxWN2I2jYM914Y/3j02cyHyZEOwXVYJ0O
+ Lm6AWBLBhfIOk3d9ZBtnutcWAmKcXRUNkCoN
+ FTaEsRuSyVwAIPrarivykS1jVj8= )
+test.non-terminal.C15.example.com. 86400 IN CNAME C16.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ cjZHkWghypr9G7e8uOddKw6ytvFR8CeMu94n
+ NPKy7LrZV8j6QFqynwM05QIKslV6/QsrzEXV
+ eM/GEi3IOwlAvbQEa9+2kbfs7AylzuFmyFK1
+ ynh7nl+RW9HjDwCuRm1FnTuZ/y8jv3j7upAv
+ 2tM49y+plw7R4JWKB3fZfu2YuaY= )
+ 3600 NSEC C16.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ vX+0BrR270LUJA6xoUCEcE5rb7fUDb0ltRBw
+ AerhoGqRfoS2yqwjjwmHjs4udrLsj+RIFmzC
+ Vbr3UxrAm7bGpVH/HqZl8BhJwKHDb/FaubMe
+ FcGgaYIgk/tn+pbv1DSeTKxQNQm/vM2lHwgS
+ k4MilTSLAe72SJ4mPfvZXFsMf3g= )
+C16.example.com. 86400 IN CNAME C17.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ qsA6SUZ8gTgWy2VoliH9MzqCedp0A7mNUs3U
+ Q9+Uk43DKN78+0FGm3Q4HlBRBKmXZqMeJyLq
+ GiqzMb+kQxhNbPgsvDbtIeRPfftcmhHRJLKW
+ QBsBK2+Be6/1oP0Sm2HjEwVEh9x3TatyIPOL
+ 5Dre2U4ZJ7ZQWeuYUO/JH+SCydY= )
+ 3600 NSEC test.non-terminal.C16.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ ayyG42+mcw7rwv4PWFUQSZ4L9pG4RXcrGzBH
+ 44VkGJ9WRhfdCpClU5i6WkgkfVe4ibm2eXo+
+ KTNDnbM2KQBTTgEiTmxr9DCBeZs+GeYLHMbD
+ GgDYzfGArXkNBRdpHt5QznpU0SXfnca9o4NX
+ dkYS9hGPnuy+2nTi/BW/ZgxXvY4= )
+C20.example.com. 86400 IN CNAME C21.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ q4g+4O6Lyv8wKtzUoGz5ENQk1b1z2kKJmQ9l
+ 11LUkcfVZjvl5X82YBCJ1YP2tGkWuw5xRcCw
+ 0NtfuFWJLlz3i8jpkXs9DMK/a4/X0VACHsES
+ vDckUJwzjcFyowiBA8kFINElTNNxpSuLpX9p
+ eLypUHHAbwDsmMkd0jz/vXIvdDk= )
+ 3600 NSEC test.non-terminal.C20.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ IcKJz0EM6mMQGc5qQ5dk3jLP+DzCJlz5Qa24
+ k1wwvuN+RJ4I39rMDL/i4syQoMAN78EZE4Sv
+ 66a70MdaPv+AZOTguWbFSSXNHBXW5BUJanMM
+ +Qpgf53jZ66sF2n2v9t4GEIfm6frBjnRveDT
+ iOU4JIdX6eJtM86jGtqheTrgRew= )
+test.non-terminal.C20.example.com. 86400 IN CNAME C21.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ D3fsqLSsTxpQ4cC5IJVVKPyjwhoLEF7xj7bh
+ Bh2h4j6Xl/KP8sHfm7Yd+A0Gxz7noBCKfP2t
+ 2YRmFw5k0niIndF2SR2w11vSWCPxEj+H6rmC
+ JMjf0iRf9rA9HBDXzk3vIFZHVZPHs3B7yeXs
+ GVWKsHJujtuCSFATNOg4STckDsc= )
+ 3600 NSEC C21.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ YiY6Jble2NqfWdokFvKFW4tQ0CJCq7XyvicN
+ DO65NuR4xfcC5k1h9J/CPxPbCa8+rDuyFp72
+ L0d7ZYIYWoM0ZsanuLHqlAwg5bDDt48tc0oz
+ ZYKvP4iAw17tJ3O21H8u541HOVwWRF5Tlwu6
+ OlPVENGjxDafkZgHo1yfeAxfP7w= )
+C21.example.com. 86400 IN CNAME C22.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ dJ7gGAPeLC1rGaxG0R7lg3u0DoGwvRHQO4kX
+ DcqwWmG6q8BImKSYKrD9Wwdb1iPUJKTR68Mt
+ czYJE23fLWKWCifefkSRFx1Ff9M17Z4M5zH0
+ LNYsQ/6AJP+76oJXG7bx16vZuvPXWWxrUQZO
+ pcLdExCW0FxLaVbGQMgCNEdunW4= )
+ 3600 NSEC test.non-terminal.C21.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ rlSJ6AY5BSOY4f22caJQRbbMTp0r/tBQCp1z
+ Fy1r10KPygh5H1EdsyUreEUyaDDjG4NLE2Dv
+ HqGKvoE77WYbqBI5m5eoVMsxKfp/WnCbUpuI
+ exzlYpeAUSTEDOcpmwGqIhGLcVv/sVaeQRp6
+ sdsAhkeGOlzbVeuD7RiNS5yFUjo= )
+test.non-terminal.C21.example.com. 86400 IN CNAME C22.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ FmKXcpj6HAdwgsoTR09fVo7a5NkY1cuSFSWr
+ FS6IrPdiP8oDM4kOlP55FmlowttXzl9/X2nc
+ uS1CrQCehRFg/+lC7BivvrrPBYK0SITtd5jy
+ 0OESphgETllNINqh7MbUi7QGEMW7GQlCZpAh
+ iRBpttRhgvJP7GNj8JmB2/+0acg= )
+ 3600 NSEC C22.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ z2AH/FZiUXFzdp5qc9/W8VjFlG7ZKnR98mt4
+ 3rjD9OphTxn9AQlmIFh/u7ajd8h5pI4n3yXW
+ pBIIU6IskNAOTsuOQEHlaoUPJExC3YFOaf2U
+ OouvqNaUuHiE+iGLxUjAi5w8TEkOgHV85ogC
+ yXkec/COhgmzlaio/WtttXYhVA4= )
+C22.example.com. 86400 IN CNAME C23.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ d0pPwKiMl/Bzz5CEYJNxcn/y+SRwhWC3kFHG
+ xaO8dN8uJTtUpGgHGKEMuf4Ao7CbzHUElwaR
+ wINGv0/M0OEqNBy97ZBn1BA3auhVVREucykU
+ /40J3ANNNUqBPtQtodHkoy3bI93MwVO2QLoJ
+ WFXy15HQDvY5b/I0ckblx3dPYAU= )
+ 3600 NSEC test.non-terminal.C22.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ jzZYz5wBV+mnTfubFCSEq3GSLnVU6mEMNoT2
+ jd7xiOSQO1oP2QkuIfF/Ezpg9uSTPtjW6N1I
+ UNQg/6A9Et0xEEkrr3CSc60IHKdJxR+JyANp
+ zO2GmfR7XgFBOeVSOlQYYwGSUvKg7KxNjr9Z
+ U7/yGg3ajiO9nXijiovasjy1dfg= )
+test.non-terminal.C22.example.com. 86400 IN CNAME C23.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ rRWV4phWhoPhmdbUMnmHYJQ5547AJKUVz3mC
+ b0dsrfnFNhXmqPBRdYEDjW1XpbjMlPtd93Cs
+ xnBgpDjZWjPbcolIEhxategjesg3hMTQW7Bx
+ jfOUBJtTVDVok61mYvE/S9WCiXYnKGwpIlMB
+ z/y5jYnlQx9/funI/fwGJG/PGNE= )
+ 3600 NSEC C23.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ aVmG/m+uz3RjMgb6J8NxicDTIW10znm7ml2t
+ bowN2abPf4vda/gEqvJ6d8Aps57eitzWxAtx
+ hzyntAk0ksrNe5Yfn3b5i2fAxHa2r6gno4Vl
+ SerXbceSU05nMbcKfFWgZvJC+ejE3X5WivwE
+ T6V8dMsUsbJbHMxNQ/MrF0b/KCQ= )
+C23.example.com. 86400 IN CNAME C24.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ bLE+a7u73Ijwk+WaRbat7Ag/KsXP8lXcAzj4
+ rJwY3WtTRTJqlfZ9+pVxyWqP7rDKl+rADTKD
+ uFW0xVksNJB/ilmhnfo06EEIke1e4Y+7nYfq
+ 13vUR273fTyMXdc6420Mq0iRPMeIj9/uDEhK
+ BtoUOhh6woC2EaW9voPPI0yj+u0= )
+ 3600 NSEC test.non-terminal.C23.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ htCIng073i73nHFSbMT8i7WMUIksfl6e4/WC
+ 6VVBfsFJf+PAQtkNMgT8cr6C9m+6Mny1vUIz
+ hEIqGCUMis+AuvW65t37mf6oSYNsCaGKGaE6
+ 1oTLeRdrj+wt3OEPLuYVFFZjGB6f6hyg4lvL
+ RoEJX2WZfefNyb+rMs+tU3/Oy4s= )
+C2.example.com. 86400 IN CNAME C3.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ kDrNGh4/FUMAF+2ye8ARKEkmDBxxadg/bETX
+ t0QYC9YDWzI6lGsEtLBDN3ZJzAaZUac9FgU2
+ N+1yrrvJ/iCbQEwuylqGH/CExBUtFAF1ZEsr
+ GIuuoGuwXG8nnTgVzGyWc9vW4s8u1SNaNjS9
+ LHvGGM/B4UIXk0h/I46y8c5pwDo= )
+ 3600 NSEC test.non-terminal.C2.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ CFQkWfGMyaEB0orFpQEzOW8C0ecGOFiwv2DJ
+ ZrtgppkNQ22BUymk67inwyCE6/u/tOPgS0uc
+ +R9NymZ1h13J9RH+c+WevHNBkwMa8IqsI0Pl
+ LKqRDQXcJJG/MwERMP6UMmb4Wz9rU7r/DhN5
+ 7dlXK0mkP6C9jBj66tvIEYluJJg= )
+test.non-terminal.C23.example.com. 86400 IN CNAME C24.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ hkJQ0Ywvm3KiZgSboYZkxyB111oyYwITWLTo
+ Wo+oDpFbk1GTqkmqpUDPJjrSDew9DUr8S1AY
+ uWjEsulDMIyrYXIcNYNKPKs4AssZ8GSqQRoj
+ n+46k6a7FJQiV5XERF1Hk3aRMqR0bRhZ2MQG
+ 7iYaee8aTxDbmp7rRdE0P4O2C3Y= )
+ 3600 NSEC C24.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ VBaNTeTbLKnJs4/RRgRfhYMapIVINw6S7eT3
+ V2YjZwJDzGOvO/nEutzuuVno1KphWPEVC8OG
+ 6Um9szauRT2WTaBcCChZPc4zk0VWjO6b42bl
+ ntgrKZFJfZLKBTDcB3VD8njuhtx66ehLVzlV
+ zhCZbKrnbZ/OOAxhnxWTfVWpe9k= )
+test.non-terminal.C2.example.com. 86400 IN CNAME C3.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Klk2lGfcXAEYBqpgDP+5Z2ynqO/o6v3JYRcp
+ T/+GGCy6wiq4XuoB6Ure+qo419aqzvc3jIcO
+ 5qC6UoRACYzqnJi3VGixxaV1G5Abwj1n3ZQ5
+ QNK8TzQYGqLfokwJKZVSxLfD1v2OBb4Mvn9c
+ gfcBtl24Ze0H2rA3mrrTRFitoXk= )
+ 3600 NSEC C20.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ HIycCOnTJkJ0839MwneKccOlUB1GtAv6ZXVl
+ x/VQOWkA1TnRt9OTEuliQx/DJTh9guj5Tys5
+ aOL2KabztzbxOdxGH88sjtoXQqlOu2KEj8Bp
+ mh7rrT/+F0DM9OQy/q0ifeORu82oJX6Fpg9C
+ KdRmNJ8hHkwOIJxYjGWSzJ9jNBg= )
+test.non-terminal.C24.example.com. 86400 IN CNAME C25.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Czmz5uU/4n/H/aq/Fwr+VWWdt7U9nkIVrE0N
+ 7pKIa/rNFBgmR9IYaeSLfxQ8NxrJl5fSxuXv
+ A+rGKEDeqJxorrgq1OtazjyZBOJm1OEHJCDo
+ ZxX0i3GPxVT+Zb1+bdiPB6Cbw8tbtLSxsb0A
+ uW+212VEA/xDv7GUlSvsrIoUFkE= )
+ 3600 NSEC C3.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Cd+pBopnixnDuHMHwuY1zD6uWhvy80VQ/UYk
+ i5vd5hN07O0LtNC14JbQD7GATxf6KxnV+tom
+ sK0vo+uA6Wnt+Qo+FoRN6/5srI78d3paUaxK
+ o0R9X5jg+U66ahLDxGW8O8ox1Om68m235ofN
+ apDCHjM9XNlMHGqfqQinUmXsuEE= )
+C3.example.com. 86400 IN CNAME C4.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ORfJIaFI/tGBHur1ocpNzDvmQBlO8aVhSllq
+ GSvj8S151MdlUYeTI9yiYzD4hpAuLDv0pTbM
+ iMJ7197eL+cCoDynTqaucPoESOWxMw+RxcTQ
+ 820KIrYgwD7rziDqmnK+N9CCLI0BHy/nzHmi
+ 7gEPRj/4bTZktdsvpTZC+PV6gX8= )
+ 3600 NSEC test.non-terminal.C3.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ xFnTbPQYvJ9t/i3ODFPnIO2BLdXI/kzuO753
+ CQ71ss0J3KNMhhS9SFCtChX4RhWIAhi+O5C+
+ 7P+L7FrAFcENI5AwYlE/Lm+Vqf3xsDKwMW/f
+ HJvpRnDueJPEtUNF1a2hjT9MLQXJb3yIXi3o
+ +c5wicLZE2WI+0tKicA6opLauGw= )
+test.non-terminal.C3.example.com. 86400 IN CNAME C4.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ NcXIcilgrWIGQI6T++wpWj3Vnu0z39Vm6qbh
+ FPFm1gFk3S6cmz03rNsCJhOgu8y/Tto1G4+P
+ XOdzJmxrXUTQbHeWNnx4c4bbUIkuRwNXiIBc
+ QgW180LAhsfezm+5AjhwgrEX6s4WikNq4d51
+ sptd8qI0ijOiCcZMR590HTkAA6Y= )
+ 3600 NSEC C30.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ VPeffKas0zgidVeRLbKPfT3wD/tvB8r6XReh
+ Rkikc+NAAQxUg+AEKC5tNU0aoGdgdoCD4T6K
+ r12ODG4fZkfE1/SiZ34TADpvhn0PvTjrhxgw
+ FbgPPBfUh0Awin/Z8+rjBxBA3OGqzRP7GPLb
+ s3tD/COb2ooBgf/rBZ6EB/8Bz70= )
+test.non-terminal.C30.example.com. 86400 IN CNAME C31.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ jw35unduyitnUCo/8qjjlT36iC8fL0P2Hcm9
+ 4/zubFGVC6yQlsf1P3DeTIbdBhj/3JjTEpY6
+ YUuyZlLWL+az0dvtPkl2jbIs1m4wG0qOv0jO
+ 8Q+MqWwoZ8dpCplK3vnlj7F/05TokEoDx/BJ
+ 8Jx7Qg1Q2okgZQsYGxxQqOXDiHE= )
+ 3600 NSEC C31.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ hcQLdxXw+uXejfACrSBSJmws57Ci3fw3woxv
+ +CG7zI4U1rPqNpyMMxGYjDYSEC80+nWFCKzR
+ GYZD3THGw8NynuMWiGZtu7DOFdNNSOLnqIJG
+ 18sqlRa3eGuy53BtBCps8LW7dzfuhVC7duPA
+ oBV3sKxs+1HN+IMjWLVlyPSLAn0= )
+C31.example.com. 86400 IN CNAME C32.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ GGl6maOnsNFhokQQuSb0Ck87IPPluz8cUj7B
+ R1YO9CFnJHfvNXEAq7wxCKlmIPjk99IYGoXs
+ Tye3fryV3QVDQe2f0IlvpRs8sIjjZaEU4V8H
+ XZeED0qM415txff3l0Qdg3UdL0xf6WwWDuOs
+ Z50zdYe0SM1qzJAHxO46q9b1UhU= )
+ 3600 NSEC test.non-terminal.C31.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ wvlFSmXb5OkMvxyJhb2UELMzsMC2XMeByum3
+ XmTf22cPWVBL3HKllq6U8pdQhnfhMcUOnoRw
+ bnHRfW9xcyyGIGTK+lvrN/JuzzkmrgFo45dd
+ L6kWT+CpO0SzFIST7Af8EmDvJHI6/M55yogF
+ U9eXLkj39EBYNgxmCFftn9wUvZY= )
+test.non-terminal.C31.example.com. 86400 IN CNAME C32.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ XSJZfqQ77v4x6mxmhAw/U80wuuoRcdoitAyR
+ vzKcw+F1wSr++h0R8RAUZAfma9IPYn1NHMAQ
+ IArJNwBDrBpJCApzlaumwVUEG7HrgmFZcgZc
+ Z8ejXwi1A39xelRoOd31gcGMXpkPco6mJtJu
+ avAE0xXKeASA4eEPm2SMtZwJHi0= )
+ 3600 NSEC C32.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ j24n7vF4UFd+DTHb7wVJA08Y0IpWR6oxhDBf
+ XBwUUsGQGTxBWSCqlY1xkrZuuL3ALxVJrSTH
+ UUwVoRcP6jCj7nxyS+GlxUWugyCRC08DbWCV
+ hKztNB2Zw510sZLYQxDZR1OyMaz9QvjCyvUY
+ VEkTKjmJFMMgMiG5dgg5Rao/wkU= )
+C32.example.com. 86400 IN CNAME C33.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ i2xzsyFQG6YcMxBeCx9gqm+D+4U5uPau3VMq
+ LYO2PVnmiatCuzZ8CMbjoWpmkccZ/NuIGo+B
+ eHT81oQEuJ67HEoqqjptEdcaD5roHDjdYQM0
+ VW8xihhvrWevSvFAf3TJvNtx0ExC5dgBxVLD
+ oqLmMfRLC54d8/EkT121lt4JcwE= )
+ 3600 NSEC test.non-terminal.C32.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ wIo0ME2jtQSjmcAc4tFcslj3wYWtMSvxM5Yj
+ jFuZCoY77ymekfyKJihzkKUwNK097/vgGgaG
+ tz7BTa5YYbPVAOfpXKlTMyTCK88Dz4z4omDZ
+ bL5Xqi2JsCy+ShspDV45MIjoySeljHUIzjj9
+ uxUzx74CA60CbeOOwxHOdOaC4II= )
+C24.example.com. 86400 IN CNAME C25.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ gYBVp1OcHWe4LPdhDSFevDGOwvWbgPdzsEIQ
+ RZrkeF8NOSKfn8dzVrQZRYK5Gd8EhCRdL0O7
+ fuWtRu52L+mUI3/E5COBdkPn5VEvnevEgTlD
+ zyNx4kTCKUatkclfolpiMmqpmgb1yFJfe5tQ
+ s79tl1E4d+WbADMn7lIgbCug9aw= )
+ 3600 NSEC test.non-terminal.C24.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ SOxr/8bXKZ2PNb1YkRcguxddLhHI3Xh1+o1e
+ 8LFR2YgCRA3bNespLCfjs/DM4PLs0eDUzlhz
+ 1XskwOkWW0pd1pKZ48gw81395lV/hEbl6JJO
+ ZXHBGcT0dUyv7BwQIlK8SuJCWNeNewRE1hgr
+ yz835L1Ko3PLV13NcXp68B/rqQY= )
+C30.example.com. 86400 IN CNAME C31.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ vxCyho6UPn6+5gDMLOd0zmGpX7ED5VlXzn4h
+ BYzZ/IGkjS2BwcFu5jChY2hWx1jCVY6y+C26
+ OO13EZKaHuPWGxTylSTCNa0Wdk/FXy/srpHu
+ LAf81EAonAnAnA92YUWaiJ84YOjKAbGTK0to
+ bkO6pkXpansUqCYJACFyNoSMjCc= )
+ 3600 NSEC test.non-terminal.C30.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ auPELGv/GyAaTK5t6pf+nnWsokGem8HL2mYS
+ iKLMc3ZOGcPsk0rXQmy+ZlzFmxkk8ngF+cER
+ GdZHYxvMMdcJ5eSvrj3YoFAddsaUSQF6x18b
+ pEjaNR7Zz2CkKK8Ypv2vhdxe1XmlhV3JugYm
+ 7qDSKFVZ9C9PVZcFaMK44O3F9uQ= )
+test.non-terminal.C33.example.com. 86400 IN CNAME C34.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ l9XLuVwibT3kXc8zJQjY1gODdslxwCuDw+th
+ AaE9cy81zOfeQPUOyktmpmKMAiHHpMThAdoo
+ kclMMat83pl9j2DXKtxF6Uw6mp6Z/so6Gpf1
+ zRnqnZs0kJPLn832GgrMBFiGVxFqK5y6AS/v
+ ZtOrztOAoVWFxn8XOQW3g7DJ3rM= )
+ 3600 NSEC C34.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ o83bvjC8XhVPLMKInfawkI8xjdOWLREsraOp
+ s7QNkWkC/UKZ7vjr+21V0zupS7DywkQ0Emds
+ wrHoUEE4a3lx/MOlzwbGggsRtJMh+Msx+KbC
+ PGD0ADeqzDibR/GEbsqlicsPbN6bBJSMJAtg
+ hHmsFytnX1ybsmNN0ZAhnXr9wfo= )
+C34.example.com. 86400 IN CNAME C35.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ gC0+tgCyO3wyru/vzEejh1WTjRF7hnyp3PFL
+ TbNko7au3dHNmE3jrOX/IHN4E/t0EaqM1Cfq
+ znI+phrcSyjH/joNLFxjWo94pef1uJ2g4noM
+ DvKTyBLfImQcSATLDNXTDDaSkDhSg/yFR1qN
+ sbfllYSzcFLvhXQWoVsRfnHB0UI= )
+ 3600 NSEC test.non-terminal.C34.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ ZSgGLRY270uVjBx8w720q4ZMfxhG9hNctL1t
+ mZT2AoUGp7EiUEam6XbOXAsqsuBu0MkJqYbc
+ k5XZs7upPnIpwXf1zroF1yaRP3eNRj16/D10
+ cSxWf4CZ1rfmawxfKw0GyzLsaBZKLlq8XYI9
+ XgnkDdZYuEFI5bEhCJOLiI4J0hA= )
+test.non-terminal.C34.example.com. 86400 IN CNAME C35.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ NZosaFeYVy8lnQXgyb2NbQqINWjjqnMUrREV
+ 6LGp1bdoQy1+qtKpy9H6xGdDYeBxMCKhwIib
+ ZyKDj6TgG7x1rZ/GCXXMbcfH8txDaa7RlHlb
+ z6dr4v2ZdsKsdhFG3PVAlkESRMsu5CJuSEMo
+ gSrGiNnj06mYqYEVyUSlfI8+ZEg= )
+ 3600 NSEC C35.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ NzEV8w/88q4ERTDiKRXVxzUWcvg0a6bTvGAs
+ 2vwWaoNtcPfy9U1EQyJfC4k7tfaoMGR0o4b+
+ GLbnflDpS9wRgNxbZA1cxvynh2gEvFanq3JC
+ gaqslersgKviH4fuRLmWeSRA6y9Pq9qq8y+9
+ wilw0/1hLj123SV8uUyhl/jZezE= )
+C35.example.com. 86400 IN CNAME C36.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ EvBJOfv+jFIjrknKU7VV3Wq1qXAfG6SnpOkM
+ f7+I+uK+kzdd65RubuPXfccFiiRero5l1upL
+ xLNao5B56AvJruxqgE8BNsid5wFRRmkhKJMk
+ WwPhwp9sZWrNuplSf/kX/TgPrGclUBiEv+CA
+ orZcgkEFmClsgA4hGq4kJtJP6Ro= )
+ 3600 NSEC test.non-terminal.C35.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ i5QQPM0qG1rT8xWdx1QJHBYnmBBNZCVt+V3V
+ n+XG1UtDoEMFBAELuXoEjDPT/Kyau5rlLP6Z
+ Gltcl69c1fyglHLguY8CdyuPJHJ9XbarxQeo
+ ImJzamI6X4AB0S0kjw74L+rTx5STC4uDXFtF
+ iOi4wiJ+rVsegIpLzJumr0K1FNc= )
+test.non-terminal.C35.example.com. 86400 IN CNAME C36.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ MLXJpaqizl8qstAUaR3QkSDfl/TQisMzC5QS
+ 3oMbQkyte3BdI8s1fAKHGtRZPv+OUmT/UFdx
+ uxrzka8JebOlJ1cJ/vdx6pd0M/zlGkn6s0eX
+ 8AszjuZs1/c/TM3chLLVZeDFOqo7BOMCmG4y
+ 2SZb7R0G/AH5y0y+ha2URh63OAo= )
+ 3600 NSEC C36.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ bUoJf9G3DOPWZw9kQgH1yCd5/72avRoatYzo
+ MN3EwobQJZQXuQnPuXWAPRsm/ANBkmM6+LHQ
+ vgJ1Gz2UDtQHbis5HXwH0jUuJ95Fv+GhLn2D
+ udEkyvU58XvTa7BoZATVqwoLkaTkWyd5hEML
+ caOcV4HJHDbmTkKG4wl6tY5Z9p8= )
+C36.example.com. 86400 IN CNAME C37.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ J62s/WL8A6SulvprsP/qMcA4vPFSQ8h2dpZG
+ MxsmOpJ4x7FqLRV+0Fh9ciVPG3L7O5hHulDp
+ 5zr/06hsLoOiPbnvnKhN+zAvtyXDVS+PILXd
+ i9C1O6Mao1tKTzZog5aNkqpSEVt4E/9jHwA+
+ TS2tEvTSCGjwJ6G+jBxJs6xOvtE= )
+ 3600 NSEC test.non-terminal.C36.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Ypj/z27uzSZGZcLkGNbGwOe0Ezkx6RGggxe0
+ GmMkFxT9OvjPFgkRO/icpJZaGhJ6X2suo92i
+ i+igDOUYSqOkMZ5hY4YZvy2OkJ/RuHN1Ll0h
+ E7lQctKQ9X/w/KXVJk2biCdTbhYrsnUz0NXz
+ q08k1n+f0sUvn02eyzqd8a4It8s= )
+test.non-terminal.C36.example.com. 86400 IN CNAME C37.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ni0UNWDF115kUidL4E/bXxStuW7a5dVq4K4N
+ VgvYoZSColMl6FrSAPY6x8YgtGH5pALMePvg
+ 590V5l38jnMM+WwkcK6namX9W9QXApwc4uF3
+ 6F4nqyK1NFNmlbQzvi+DZwbbvExd93LcUvLr
+ jyNy54BGZfvUlNa+wTCsDaqmYrY= )
+ 3600 NSEC C37.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ LRStYbub6UIPA/aHLr4/Oty2bSiaoyZr3JW3
+ Mrp4oEaUXJF4ANn7Ca68GCLDKeU5aM/hQV1K
+ gh8Ms/Fll4Bf54/2z6YcZr0WU09aL8xSxwCC
+ tn/qZNtzxzAxJbCFwZcJtlGP9vsG03d+qUys
+ vfb7yOuZsxudhXAOt+SGl4FGPa8= )
+test.non-terminal.C32.example.com. 86400 IN CNAME C33.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ oX/R+pBjcH524Znqm/m1yDmPpjaQze2mtQd/
+ /Abd3Slt66b2crTO+fWz9SQ7zfJQzmtaMcgm
+ lbHf70ggM3i/DcC0ATFBCQJvuX7yoFcNLhze
+ 20x1ft0XDAQkbtQweT8/H0l6nwg3PraZ7Svx
+ 0rt9lkKj/FZ5KcLnHtWN9Lrl5sY= )
+ 3600 NSEC C33.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ ceYE7iiMcQsT7eXJ5QKH3mHzIGWUBTt0smFr
+ p1Jca9UUxfn2loS6q0hTKsNy4b8LNodhLj6I
+ 5MeWhjYeL8W9kXRudYFa0BcoEjVXtC5vb4qD
+ IR8rICG5zWmKvGDOrf4fFE6I7yGtNa7tpMO4
+ cds9eCUae/eKDe5geRZ0jHaAIn8= )
+C37.example.com. 86400 IN CNAME C38.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ HB+SVyFK98BpF2Isk+hS/mHgsZAHPKBAXslz
+ 8vlq86yyVEV0Ns3rRSjtzc8HcrcZNoikNTaM
+ Zp7p+qCOO288kHbOqDY5O/qHgHa/CTapaEcv
+ Fkrpgo6LKPeIg+uHZM+I+CEaB7W3nyti3vCY
+ I7z1xecNt/9+BSMghEX8EkbUeI0= )
+ 3600 NSEC test.non-terminal.C37.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ wZ0D6paF53u/yRQuJrvDCqgAKFe+eo+KRTSj
+ pnZG8Vxgvt9rtG3Cm17ftIuuuEjdm84A97Xo
+ FSnLKEOwjQoV7nKZa5dYJ9Ay6/EKKMw8q9JZ
+ lXZZ4gzJLRuy+cEVJ9waKeE0F9s9d4sGk/s1
+ yEmPdXIe2wJ472uRMIg1M1o8BIY= )
+C33.example.com. 86400 IN CNAME C34.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ dVYcj/YiNH/bwwUEd8i0nweQw3xSvN32/+sx
+ 0Z0zhoMhIOvYpjZbsE52D3jJG4EDcREumEQP
+ Ye2I2CPcBWCJEr/Z44sjEmX3Z7ltHdlYxIc8
+ tEyLZvgzT6PJAoU5/wB8SIpHIFV/lzE2S+96
+ RJE8rp0JzB/1EnhaGGqjbrxrJfQ= )
+ 3600 NSEC test.non-terminal.C33.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ JhjpFtrCwQtDofrZUxcocJr6k4JtNTkQvP/P
+ xOpRxnQz3E/9dY8hUogtKZC0HJVGAuTBwTie
+ +2Qu/PfDxwc3EEWtbcjflDJCbpY5oy5LKr5l
+ 6BUdDaGrWKf115WsJspVROrp2fNfZeVRD0Si
+ 4ixv9JQ3f5QMcbE8FMX3Igpklbg= )
+test.non-terminal.C37.example.com. 86400 IN CNAME C38.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ YgdM1snnCkbeQw5Q2YWqIp8dI7BsSabEIk8y
+ qZkuwfidM2tPTnBJlt9Ry9wg3Q9aHogPu7GA
+ QSBCM0NfsDrtncsxGzX40bIDStT1dIsr6BJE
+ jzijiBlyldXRdPX0rWnluf2d93rTMh+ZVE47
+ llnMs2sjtM4eRqBsBDcZoR6f04U= )
+ 3600 NSEC C38.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ G+Q88jVXynkL8sfXsIuzllJ9FTtXb2o74zZJ
+ 5gTlxVVarNwO0lYTpGqgbZ6K58RXE9krNz0o
+ qIKsigz1wA8ZDJ/emQcsWyIw8Gdf507sydn8
+ 3N9xFLvGivBCsuMUQeN42gOBNhmmncajTsFp
+ ywtNJBu+GXAADduGQAmo0Tjp4lQ= )
+test.non-terminal.C38.example.com. 86400 IN CNAME C39.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Dc5ZnZoMZ2Lk7xIXFPu9JQAzr94TdmYsosFB
+ Bkm9bBMb+ZV8g9GKXTXYpKD22N5J50g5w7EP
+ gXbs4SKUQ3aYlQE6rJzcEucGtYAaTWaO8cPE
+ tOzvXcn/RCeif7GuPUlh14M6PDAForLcoasC
+ le4O6IjOF0v3136T0HqVTK9VdV4= )
+ 3600 NSEC C39.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ ztZlnI1vVUKhtR16eZNhWkJIUU57ue7Am2Vi
+ IhkGV2NER65r8CU2RB0w9StqinasQlDnj1l0
+ 2kuFpn+/RkxZQ3NjXgpPLoCFS9P/ffPAeN6c
+ sLxbpV85RDZxa4x4QaZwp7Mxu1lnI6kM41L1
+ bTjwM85A3A/AZfgMIzxQ5YFMRHg= )
+test.non-terminal.C39.example.com. 86400 IN CNAME C40.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ EpkJIeFKf50ZZwAe5JGnIuIlCGNNL6D6oJax
+ 6FPa2N4GvC1Ppfs/eixEC/IKiclTUWmh0oBk
+ zZff7s8joTD47cPkQ+a6eY+6pNpn29h8vEkA
+ uhRgWKi07XR/FUVfCEY0h/fGCgKgDoEfxbsD
+ OGAlbRFnEHoimdzxnUU/suYZogw= )
+ 3600 NSEC C4.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ pOEucUBeuxkb7uvaJH/FyVxu4sqGM6GsI4+J
+ ltaKcwu1ucEp1GHCrUFmSFP1y8pAPJlq+yg2
+ IcnHy2BcRz6QlByKRO+iRwMn7HU9+GflrcK9
+ 3vbDhWFzkkT1kI9KflVUtgvxbwoIyN8R9kxL
+ t1+2l1crLIrs1fiKxKSbpLtL01I= )
+C4.example.com. 86400 IN CNAME C5.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ xlPwlgE5cuXCKPFYnA51jNLUz3QgnhjkzB2V
+ jH/xQEU0osobcTq8oqNS65dPps8xMdU4LkZ6
+ fJlXgTUfQ92tx0BAQiVJcmGnOp5rb/eiompJ
+ eGwzkZj89i80lD1GiehfvsCN1zdIIdZDQiUy
+ XHJv2QbF72crF6OcM7DoZfK5wCg= )
+ 3600 NSEC test.non-terminal.C4.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ DCX2xmdfjVSQ+34Iyqze0HAVWR1UlJQ6bvQm
+ hueDYIjRqjtog+7xLKsD0XyFGkYokNMm/gDs
+ eMTX0rfM/MEjhGjSG1Jqf4uyz7aLwcogDWII
+ k/9hiu1aabJ/2M5uNUYR7VD0ndkC4aGvBePl
+ 0d4nGMe3LXXhcpSUfHEblbj39Ys= )
+test.non-terminal.C4.example.com. 86400 IN CNAME C5.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ JAHcZiOe20fnNheDf4LJDcUZxgHTBRxmxYAc
+ FbRN8Lh3rMrF53p22OE8sMwy7nqnq5Dn7X91
+ ay2HzyDvDv6izvkaNxl81WEX8cklUmFRTa+c
+ orgs7FVzxajnOwC/TH+hKMk3aQGodra+B1fb
+ gPpugnaaAnTTzPq4HH5Z5/Z1dxQ= )
+ 3600 NSEC C40.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Q62qdAcJM+OQ1e658d/5D7PhjWEzGD1U8kVw
+ 0dyqBjHTmD2dGT8fuN0jTRzXSLo67v24i1XV
+ 35tPrVlEO1TNc3hrvlqyteXtYo8OKC9g1hiJ
+ CueAiedTlhGVLNOVCz1N0gD+XmlZfFVmMQsb
+ WP2an9mtc06wf7OqOPbdRVBYey8= )
+C39.example.com. 86400 IN CNAME C40.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ab2D01aHm4cPobTq3k4FzbYstK+aop5Z2fbI
+ 7ljP5p/7Cvp659QuU1B4bqkKjS2wx8IHIlpy
+ hZCYk7/ic/nbGp7oAnEENhExurbdFQQJU3Dg
+ dDuzvzPEayQYIXy/zqPLAXZcTfHuAWwjuSlT
+ 5M4O25sq00aSGrLjeGo+2zVlIrw= )
+ 3600 NSEC test.non-terminal.C39.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ k4qZMnzndAT3rPPZO7hRURZpEcQupg+b1v7M
+ YFQ8Zp1br7A9e/jNdQziDONB6y4x8khxTGSL
+ lbgJuq4BHwvigd9n9PZYlNqvGBLd4XdUihBw
+ nwRe5fV1S6dJj2mbQiZtGvuK8udFf/XCzSUx
+ uMRSAJmYJyH9+06FjdNt8hpL3dg= )
+C38.example.com. 86400 IN CNAME C39.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ MCE23pfK6/YRsNynpFofte/Q5/LgXzw6Irfj
+ qDKHaA9Vs7KAFq51v6Dtbo57OemiRlnebGwi
+ gpmqdzlapPbcuSh2zEgSUdZcnzjd8YSDb9Ay
+ 6Rme/4qxhUR7CMCUhVvOAH093neTrgNgRVcu
+ IaKpeVYiAW/45G0rOwL5/saBtbw= )
+ 3600 NSEC test.non-terminal.C38.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ iYlWNucYfq3tYnqjGtPu4qRWdXwGpHGlGVsG
+ aVnnb5F3V5191PocNAlY1K/ORxR3JxwBYi6H
+ UjZYrEvK+1UuLRjYTLdJWg66gp4kY1tpTl7I
+ YHIrQ1WFPWWqDXlPDR93bFCJ8oV+WSyknuyF
+ Iat1WCkT2f2KbJkCWUlOmS7HQ2o= )
+C41.example.com. 86400 IN CNAME C42.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ bSuvVTFqytT4NtNkEsLDcO2xvgpmaEZOED23
+ wCpEFTjkZQT3qS8cnowGshWGIT57v1YTH6S4
+ uA92zvBOHsgT6RljRkLlkdseRBN8I+EJcOUU
+ 1KTvRO90FQjpuxDVAkt4BrYvV5JtOpKMFC1c
+ NceY2aLJNOR5Z2dFJPALBykhIH8= )
+ 3600 NSEC test.non-terminal.C41.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ QypweRP8qWSerm9LvRqNWSXyfc6uJmAlgBr+
+ lc9YY1+JYHCsa8QgolF7vkZnBn/Ck5/vFvt9
+ ZZxer6kb/D5b3gT321hS1JosX/YUU7oiJp5d
+ Fgbt+6DLwB/sqAF9NmbY4s3W6VaWYg+Bl6Yb
+ VesIf5gMAezJtPkCBbkcjr8eq+E= )
+C40.example.com. 86400 IN CNAME C41.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Ol8L9Sy5CbpadEvyeVhsfxSCRTxOynPPCGei
+ tSNazmU3Jr+aDidycVCvbIZj5lX3RYOIF3QW
+ s8by2rvv2P8ceFjNk91Vn3rZeZASOZHMRjql
+ K0Cxv40Kd2qF9N6v+3JCNk3DqNsTNHb0HlhL
+ LgEHOo6mKaIafgDDZAc/FiUiAUQ= )
+ 3600 NSEC test.non-terminal.C40.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ s6zkrFyugb37qm28cvzQEuRdrTqv5lyIknE0
+ 1Sa4alTuP08hyaJQ2jvLjIJCxNekonJAFvM/
+ yGoBxr8UstaKkLVYo4f3wZ3BH69rcHR0CA2B
+ JGJPFjbFBevQrWJTkbyT/0viBEOvs9kqJXZL
+ VqukkkcpZw0KyWEjjH5NC8CGLc8= )
+C42.example.com. 86400 IN CNAME C43.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ZxaQ98LVaS9NvP+w36TC5WhcsHuzPVbRB6Y0
+ DjeARYJL1hGgUEK7XNFN6LqkXZlDZdXIxDHE
+ fp4lJCplId/k7z/0GCioZ2136nch6aZN18xu
+ enr5jpnzDxaYioJz1BFU7ybRnEB1XhiknREM
+ 8/+jdF987gCIk7wEur7vllgujMo= )
+ 3600 NSEC test.non-terminal.C42.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ O75FzIadBOmR0C7qdlCOeCkEMx/jJiI+b21J
+ ZPbxI46LEnbrTjPsBdU6a4g5lHurSINJel4y
+ Ya5khpxigAjtsunmOiHr3NrR8efr/Bz0JKKN
+ bSRZZCmoymIiGGM3AtbSN/n8bGMyz+C1W2Mx
+ taLB6Z75uxTH7RSaKoR/BNRLRkE= )
+test.non-terminal.C42.example.com. 86400 IN CNAME C43.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ oXYGbtjYBTpMxLiuDZ8N48trN3jUzcWSDQXj
+ 1+lfNtaJYBv0+50duql1uW3DVtNE9B9VSJen
+ KEinAe6aUti81vZb4ZMGO4L4V8E2cfmLeQNK
+ fGh2NLFb+oNiJMPk966I7WOEjCohYi8ELfCo
+ HH6wBOZqDB3E/FdTJJ7mAnUjJtQ= )
+ 3600 NSEC C43.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ oqkkYLvd3e7/4WJ8pkUqohpM1aCOOsIYRved
+ h/7F3fnEDIM7SviE68wP90ch1UZkn81T0iWU
+ meUJoesWhTBpA2mM29teJvNamEh8tFUcfT5x
+ ZE6t4fwNpNUiOU51UJu7p2rVIZ0kzQ1c+AsQ
+ G3YEcuSmOEJV6/p4uGIqvfbXP04= )
+C43.example.com. 86400 IN CNAME C44.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ RzZDlADhgkcbBMlcRF+b9Jobh6Udvs0ks9Mi
+ vstPki65zmQW9gZWUasgUMIRAXz5+623b9IF
+ WDivqFm4pUYq1iiweW41YGbL6oR70em1zH46
+ w8q486jUNlWbZGFSOT4ltIopwlYUQSAyJPfE
+ IxD7JzMSfpJ25hnpL6TG3YlmCKw= )
+ 3600 NSEC test.non-terminal.C43.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ bw/Z22tfd3MPJYoXsPIrKzWgl1osKGAPjJsN
+ Ls6KnXsQOfR1rv/REwq7Kb3Tna8QRq6wL1sg
+ 4K6ZTIKT7vj9vAJDB5ovY0pVeJTpCjdqJO3R
+ l/UXpUZiaxwmAtWUH8dBV/fvuJz+eZElM4WN
+ PO9Ob2GQq5z3tRcfP75HpZjMnDY= )
+test.non-terminal.C43.example.com. 86400 IN CNAME C44.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ F+3JubBGS2XBVUWbhVFb1aW3zreH07h8huCJ
+ 9qtyo1070x3k/h/8UPZb6l/eAr1WwqT0WPn/
+ 1BRhSJskwLfHJLz23YnKf2SFY9H3mdGZgZcm
+ +IELmPJaExn1hNsHlLeq+e1Nel0JmerFx91h
+ bPMZdLGuuYleMP6/1Ns/SuSy5JQ= )
+ 3600 NSEC C44.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ e639nuGt5Dbl/dmpRdXqekvtbfPD6To6SQJD
+ 9VXZaMRHsX5TXhw2b7XOyexG8hMpDOf2QMIb
+ DIWrxE0XqfETV7akV8I270jwjRiIbFYDEgdl
+ COtNJBYhZuzNSznzt7iT7fU6HlswUnFQYDSN
+ ipsToO4Bv7gnHjpmGtCJVR5xwTE= )
+test.non-terminal.C40.example.com. 86400 IN CNAME C41.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ TaV4mzo70lt3aY+oa1tTFBWBMhRVoc70WCHq
+ NMUOJRoQRdrPhZPADX2ZogSTi+exMisSt+Np
+ 2rKkkS01teSjd52Y3kM40lNyZ+ZURzPBJ+qi
+ LONsmE/9pUWX/NZ2xPohgqx/FNITIqgl+7hr
+ uozte8zWDe5rxVOO3YSHXSUM6wQ= )
+ 3600 NSEC C41.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ QNcQZqfrJJZ9ND0RKXdbcBjVE0szVlf+DCln
+ oIXbEg70K9RBtx7+kowL7UxSER6sDCq93ztk
+ wZWgPrskMZpSoXcSRSZyGVPtNC8Va/jUvX12
+ Lh4U0S2kRdpYHPw0ijcSagTWclMttngSMviX
+ iIV3YnTdVV0FBsHJ4ZyTT3yMNJ4= )
+test.non-terminal.C41.example.com. 86400 IN CNAME C42.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ O4uILstkjzBIKDcvGNTjEduKZHQcR3oBJlfy
+ ACXDaTFyShj4LtQHCbgm8bJVEcTxNTwyRAeH
+ MtbwmzAZ5L5hCiy+DBYvzBDdwucmFrkPV3iu
+ tfeV1V99NEEVFVjJGqtEyl2eHb+s6Ube+NKE
+ vW2E4gFG64sZaLTkemQuxqF2bOM= )
+ 3600 NSEC C42.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ GpGTUeRPOOweU8o5XDLCgO02Z/D1oRmXg4te
+ ajEf425NpmDNo9x2FS8K+jm6i4280sAyobk2
+ Zuq5hrA++vPzqdZtX1JNXl2u3xGMMEhb6FbL
+ /DnjUtDIH6H0pp675mVokj6MGG5k0H2TthyE
+ pvJ9ZR0CBb+RsROGuFKfCjH3x9U= )
+C45.example.com. 86400 IN CNAME C46.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ oEOm+BV0/vojmQfvSN4K41s7bKnJE1Z3B3Ic
+ dQj5cOL+AIZchO4DiDwVpgaMI8ks4rEjjaAA
+ AiOJ5LceWNva2YtCU4NtQQhKoTN1g5g9ZYy+
+ 1Y+B0szCi42ZuRm5kjp/l+dtgYHfuHD1ZvIA
+ qSuooxE7MwsCZn+jiT4WVHzhIQc= )
+ 3600 NSEC test.non-terminal.C45.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ EnMq6VpLuTKEXl3rinyCDTb7GcflpPIKOYkr
+ MaqZSul7MJc+Ro9e43CFTvL+M8QyZ2XPrdx9
+ Ln4as0gnza3N185srCdBMOIZh9GZjTYJaV4F
+ 4fqIkm43r3ORebu4Y0/J4GjV46TEtOFaUv0d
+ InbqXvzxhXDnAW6HLqIkKDKJqSc= )
+test.non-terminal.C45.example.com. 86400 IN CNAME C46.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ P9fzyX/6o9pbuCZmQOWLrY0LwMk0MPnG3syV
+ zWLAlrl+7VptGu4Yg6fLSeJmGyc/OM6xJ0np
+ PPL7+taPfSaWyblDLW9SAQqe0WOzJV37Hj4V
+ BIZfVUfUT7sICFSxi9gUnR8607/wrWFvIn38
+ 5pbym/Bb/cGj79b0gSkdzZyk1lU= )
+ 3600 NSEC C46.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Sx776XCx7j4qqUYZN3dmzKU78U9O45iQq4zt
+ 5RT8K/8zZRjVSk5/PTPJsifOnHVpfcCD54ZT
+ WG4RqkeDinH46jUk1p62x504+4gllJvprJhd
+ 5sc76X5gzeSqJc9rvWHpFjqVQz2DLtAQwZza
+ uXuMtBtzzVBjWi3QRgrmDZCLK10= )
+C46.example.com. 86400 IN CNAME C47.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ V6SYuepLYiac1xs2cB+uAXa+HaxyqiIFu4ju
+ +f4xYdouR2TXfW8Zf2LFM+vh0X3cE8S64I27
+ TJd7Ddnhate2FCvBSHkylRaC8L79ENIU2U4Z
+ T3CyF4fT7WHShKzgoqmpyzi1K+2lYfFqe75w
+ WQvSDmDZTTlnrTrUatmyTWiUrjA= )
+ 3600 NSEC test.non-terminal.C46.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ oEsrxq/nWiqkbSVr3FDwAtktF1ywiqg3eg0p
+ DzNlVsffOW9HOuOoyhzkQ7ZfpLP6wRq1sWLO
+ R9T40PnSw4Cnmv6Q1p4m6ekUJ76sdOsMw6Fi
+ L+f7ZOKumceVKKxRReJddjPigWITmAPCZ4zP
+ +/2TihnruNI0I1g4nCRrM2dzuXU= )
+test.non-terminal.C46.example.com. 86400 IN CNAME C47.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ giiqTT4lruXdmDYKZPOaxVn2pk8XymS/aIyp
+ aHlRfV5uGAKofzmMAbbPE0VYHBDZaJWilGOa
+ UnqybuF1uiHIx8u2HpOPCV0TV0LUpDVCVC/R
+ EF+Gz6Ppp31R4/v1fQLUmWpuscuic+t8QcnK
+ US769b/ioMhRDDEhNa1u3OMFA1w= )
+ 3600 NSEC C47.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ jpDaUkBcopAD480T3rt3VlsbbwqL7opc4YCi
+ FzY1StUu3emj4D8jr3NfWBVMWNE350tOQQZV
+ IrZtUhTWuv6YMPUbV5Q1/lt3ICVLDueRSXWv
+ MovnC2EBBVHzI9qom1PPIgNxU2Sh48Y7iTtI
+ UEn+g+mzQeCRTV0F71bjU/Ioxj0= )
+C47.example.com. 86400 IN CNAME C48.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ TJzeQuCUrzmTEHZ8QSzrMh6z/GFOX7g71Sx0
+ zB0rngSYY923lKS1PxMx93+i0XcW8q/1w9+d
+ ReM+qUIIJCaa7yEDZI1qplBVXYKbEdOO7uKc
+ pPlN9jTN6SyEMfGIKRK3nHfuFPVWN2WCy6Xr
+ fTlqW+ctq3dGpHplxffV4N0jyY0= )
+ 3600 NSEC test.non-terminal.C47.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ e5UJH3Myw0x8JReinOHQ/x29hgSS3YZMKiX7
+ BvHJmhsDuNiElFEvAfVqZijU8IS3TwqQRJq0
+ qefqNtnW6jY38GsyQ7B9fJjcnC+KIVnNtrOA
+ q8xTcGjILf2ZtYtT8uUvQ7CIldh8xWFmt5XL
+ ePxUnWXbQzZBVUj6hgg+qGCjuUU= )
+test.non-terminal.C47.example.com. 86400 IN CNAME C48.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ DlRuPxygmP5m/dHI/LLFwmnYBpgbnbcyE91F
+ 8D0A2lENUsny3OGjtwR0F3Z06JK+PsX+tEmK
+ sTwix5i67R9rAuMef4+BXEVYnsCSayWx+cSh
+ QXAHI+2OxOt0zy2dtAjid6FwAsfUqg+JmsJT
+ k4d0ddJ2DEiQdjSu8oiNpyN6sWQ= )
+ 3600 NSEC C48.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ YOmrIVOWSLCphgFPU6VlghU/+1Rd78yKkL/C
+ I4iHB9Ts/dmymVWdDH4f6R0s+NtUj98RxoWi
+ wnJ4mxSi95ZJvxRqAgf5al5Q/23hTM+IIBA1
+ uc+6lWXMk51xhEjAovENFBd1VPHG9U9dhooo
+ MQgDm1RVBsJ6R7X/MUvUuJ7CXec= )
+C48.example.com. 86400 IN CNAME C49.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ mstE8tIJelsNslY+HEk8T+S88IF96MEctQ4I
+ 96/Dg6qJ6aj1pRgId3Y8GgXgrHKDqmdrzgJM
+ g//rYXCL0nctFXZevrXLG63ZXVgcAJ381/tU
+ ulP5VfaFRYGN65Yje/NzHPQaWuMshnODbjQj
+ sV8SQWNkB+7jZFIFlMCQH+B0CJU= )
+ 3600 NSEC test.non-terminal.C48.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Jq5at4SpvTRt0XIEGr+F9EynvMUMDRvwpi3Z
+ 0dtq3525j/bEiDiXJsH8CPsrrrAonIFFKcYU
+ 2RbtS3SiRbrHmOWuXHRlyinEdZsFlzM9jc0R
+ g9+1kNwnOV4SvrNdQQbm9MYqHwIjWwUi5k5Z
+ VDfsTkaBVCOH+qxqNzv/p0vGqfQ= )
+test.non-terminal.C48.example.com. 86400 IN CNAME C49.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ CNI+oxTaXWMQGarEpaZiY2G5mrUwMsmC9e1k
+ xV8HxEpt1STVrohXagCdBJIqaf3MWj0NN3Vi
+ suC3fXtJ72OfkxJtKe0PRk4AjbCZyeB+C0a1
+ R7QHl3RIFll9NEUTGtz7P0dodWV336YkDZ5y
+ fzEtrecwyeX8+hOZ/iv1vFcX2vI= )
+ 3600 NSEC C49.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ TrOIztZBcvyT93kbLDtfBTQFsxBpytWAjUCO
+ FPc6xb82vd0qq1tkjkY7GXzbb4cX1V+2FYmR
+ gBLHLal9TlIrdJVOTQdHQKwnHo6aadGd1ayi
+ QsJvZ/400WCDPVvE8pQEK8MKWR18r5YpWa5L
+ cQQKgKlvQFozX6CzJ6ItlJYq5FI= )
+C44.example.com. 86400 IN CNAME C45.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ BfFkRZHcn+j8Mxe1Xg4vRkBl6YdAyeJUo4cO
+ 3+K8dlLr/dL1C2xZQmwOePkhG5udeMMG/PJN
+ 469UTII+woyX6tHfXYoP0wmsRLruu+wv++0C
+ zlkcTXdrR7KYyZZ1+sm+VeQl12n3f3aXLQq3
+ 36LpQALyvtHBZ1Ccph7zk1h+Aog= )
+ 3600 NSEC test.non-terminal.C44.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ gCTROnakx0cguzal+4is88aIT3szhqm0PlD4
+ 2gSCSNthro2YyEA1x9anQ5t3d+M+iebLokyN
+ RpDqY2WLyqknI9iPFSpVYilMl7G+JWBt5o3D
+ 0tB8nhVlA4B83VqnQsQIU4Cdz04JrhHo7Qq6
+ bPO+uU1EFiSC0q9lTqcAKvbeikc= )
+test.non-terminal.C44.example.com. 86400 IN CNAME C45.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ tLav4jfnrXhG9RDhgXfFdV6PzZs+HdjxV5gs
+ arEP/L2RLnahWcpcAGDvtzBYNTr7mYIkr9+I
+ M9nLtKNtyWT4THtPTJFjizLh+HaC49J5AVSH
+ Y7cM6m1uwhqvPBDj4LINsR/xz8SvQx2MZMnW
+ AIN8+KlDog+VxggDtMuMxBVevsU= )
+ 3600 NSEC C45.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Gw6d74fziYMXchEMuCKvBbgUbHFYCytfTpcz
+ msEU+7EWjncgPWkTHwHejkjbmYDL8v6dByOu
+ hB890KlGkINTXp7nD8T9B4efttoE7OgnIqYC
+ S6mpqhzMg9Bf2Cd+e7s1Ok5siREZNO1AZIG2
+ izAqkLq4l1j1ug415YIOUWcyKuE= )
+C5.example.com. 86400 IN CNAME C6.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ H0KhqMgZZNHLAYQg2x4EWkrfLjhZo2M64nOq
+ mLZNgDr2ubtlCvc1RmchGLwzglEicA6D/lfn
+ u/+etbbJHfNq/6ERPzRwje341l+OZ2TKXp8z
+ IbtOd8m7m1KVTOcdsQPjqLzjpoM5/DZTJqbQ
+ nK7sSKJuT5tVLUcfQ293zEXMIVA= )
+ 3600 NSEC test.non-terminal.C5.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ XBzbnJBPjiNe0aqf9i++JBNkVgfKzJSOWxbK
+ WdGBAE+1oqrwkngVCADRBhCVIqQMUKfJtaYV
+ R6yncIT6CNR78idmVGCZ5Da1yJGQYL3HsF7s
+ gMuTkBp9cO6xFuFkOqsRfc8lN+oeas5Z1msV
+ Deh04viwZMfoKgFWpL2MtC0ohd0= )
+test.non-terminal.C5.example.com. 86400 IN CNAME C6.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ FDq6kVPWy+nYGNwmgV6roNqzHyyh4HI/R4zU
+ VDNIdTqR+ItRvhHjh3g7gc9II6TLPDhgefAi
+ 7sehznPvCn7h1I0YixtoDrflj+IQ/iYxJLTA
+ h9bVLUfmpfuBCxmD4KZYbSnVeVdVHvtepruL
+ tg6/YvVbtfRRcroVpXlTr6kGJgk= )
+ 3600 NSEC C50.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ ecs97WZFw5MGHB+zUvO6jyKZ+ysP1+agTLNB
+ hjBirXZwOowbmC/CekUcWvuCPkSIpCRzYBFR
+ b6kY3Q25wikZKjwW8tPR0qYKBR+0UzFVXjG/
+ ZHyk+4s1Osn7t/ly4yu7FmihAldhAzyZrMDX
+ P/Q0R0tewwQbKlHqtxos6mVPyGw= )
+C50.example.com. 86400 IN CNAME C51.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ oiIkJXCUD53GZK7WEyfSi26asLcAG/XTWXY1
+ mKkz1iUvJNYfu/P2AM0wYutS5tzPUb4ZB4Y6
+ ODti0WQy2ycW4bRvPUZI4Yjh+eHWCAi4slPd
+ cQoQ5GSx/ddGy8ryRgggQH3mfSSZcylw2MDv
+ CJkcNqmG8jbyC6W8295lHx7Btb4= )
+ 3600 NSEC test.non-terminal.C50.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ ngPIRnRpksfj6eLSAWH4srqirM0+0wTbpBr1
+ 1TF1FjLCvjEQ5ZmB3f6vrZAQaTmrQIa8jVpY
+ 5gTPB8hpnLOnkgA68Z3oSLlbAQ678XaoOHEx
+ EBaiQhryl5krfDhMgNqD2U/5804u4lDveiv3
+ ZSB/SQVmDepFS5ZmmVIhwDqn5+U= )
+test.non-terminal.C50.example.com. 86400 IN CNAME C51.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ tKZzKPoJekvNQK7D1l0aa3b4zKh4u/X3GY01
+ wpLZzlto3YiDMINWJN3E0/KdFojFEPzGHrYp
+ SHkcuypmdthaKfOS73qqiXulW4MyC/c87zlo
+ epBmzf7mcpaJicDdYuuYXcVrJg1w2wYWcQJf
+ 7cb48UeY395LnG0O3nG7w3VJ4fs= )
+ 3600 NSEC C51.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ PeiickCPthoAdhf83mJ8wIgJz/dp8q8RnsqQ
+ 2GHWnrRgVly2PRPcCfw/eLLjxF/QzM841bcS
+ ts/awWM6vQBXlYp7g1+Nyn2gEazc8/Uxdz80
+ 3DU5RB650jkOetG2D0BMDCQhwMqYW055Crkl
+ zwEGhuuk3u8gWdqnYV+/MjKCA64= )
+C51.example.com. 86400 IN CNAME A.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ uYXTGlmDyvUA8cur8NjK9SfKU3rd6/hgM5vk
+ fZ+8cpYtolMH0cno/miTU5vIFYrIDzWM0vYM
+ VToNDGRdDTpr6R0zozJ1/tdFbuuyUAkkf4DO
+ 5UGwQ+yxr79dGiiblPM4xA9+dxHq0/VPwT3P
+ ydGYJ2amf4uow/tiqkyEHqp+FvU= )
+ 3600 NSEC test.non-terminal.C51.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ nAJDYw8PW8PucLWxBiM6tRqVp9E1PFyUQZBE
+ msVtpk8dlsx/1Lro1BtWAYYLjq5p4Sz23220
+ ntbtjkvGTQ8JhPbCYI+MlZPGqhUQnyXKkDaJ
+ SMVBcfP8H1J/qB6BFapOGHj4X0DzwV9yw3rf
+ owwNiYRuY3CQ/huDquMLpGDr5z0= )
+test.non-terminal.C51.example.com. 86400 IN CNAME A.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ USwIlYP0qfA6t4qTDiYeOQ/eIKyNRkcj4fxs
+ GVwGf+3z1dPfwlJn6aDaDtSag3gSNqOVYc5E
+ 6EdDE/g8hkGLMQe14qDzXulCTpG8eeuGhFJg
+ zYA7JECxj7a3whIIyogLV1vLeb4ps3jOatQG
+ 8sFmcsbybikTOKFbZekJ7ZLSgkw= )
+ 3600 NSEC C6.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ vPoy5ruzXlnKfKolW5Prtr5b9seVOiQ0Jd1X
+ Z323gO0MYyPbR+QmedhbMas7UT6tQdSAqyk/
+ BBb60ZcCXGLLqE2QtSUJSjo/ggGSgKcKiEd5
+ APQbiitXL3LSdqW9swQO1WQYcZcvfrKo6RUl
+ +56K9UBDsBU8ZvMCurGPwwMH3js= )
+C6.example.com. 86400 IN CNAME C7.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ U3WdoX39xgpI6TU2FpTQ4ukCRbpqwYD9Jtu+
+ WBFSUqieidiYWBA1kQMuBKKdr23JFc9xUMx8
+ 2H6dDDadKK56Bs/lc6lB+GVFHP2g4cgkQRzY
+ 5hl2GLhV8NV7j9h4qZ/RxfCAzRaN2aTS2+oy
+ OiQu4yCjj4XlavN5yoZkwcU0DHQ= )
+ 3600 NSEC test.non-terminal.C6.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ mytT+aw2B+FSYEdT/fHfNIbkuRFXE1Sg77K9
+ 0fxuBk/EtXC24ESHFGezdSvc+c0kzujU6DKj
+ 4ZK0WEGuoPF4NF8MPU2pzzwIuv0QzaCpm1g2
+ qsCZaEJd0e3BggYwUx/SNnmOPP5nWvVmH71c
+ I9Lj1//Y5djz3ticeLSVAT7kTyA= )
+test.non-terminal.C6.example.com. 86400 IN CNAME C7.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ CYLp5AzdlO5+RZTj4UIZ9YqnXM7vXtttEPq0
+ rnXRZjn68xrN6o4X6qhY7C2lswlz7d//e59O
+ nxoJQrwsB6EDbphecQd/kWDMYA9Ss1FLRU3x
+ 0lfONg2eaclZMexNuiNgR4tiF5dpytoCWRLk
+ eeyk5JP4tC6KzkzYmqGQuHDimXw= )
+ 3600 NSEC C7.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ K8D/dJf24FcM3T6ywA7yN3RvKNKjZHSkVZtQ
+ oQtEbJXF1UaTm2C3B5Z2X4r9P6B6nZvtd5ur
+ P7RikH0oKn2zqDPfYrOaO7SZJf7QQtCmaiaB
+ /uXusM9wSxT4Fsgc5CZyFHfkMMsTKO/3oHuT
+ PBNHiVu5g8yKn3E5X6UZiSXoj1A= )
+C49.example.com. 86400 IN CNAME C50.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ xYTSz+cEvrlbVeS5HFTLad8VVOvNldTgZeqX
+ egmtynhDx6stG5rGdaD51zdmi24smEYo8BPQ
+ jtCU8moyFKbnIAscv6V/re4KGP4YPyRzmPUI
+ ihoNAUSaP5jksxUmS3+DWD8PaSfA74L+PVZr
+ SOsZM+cGzGnVQ5/Ejp1lUWn2y6A= )
+ 3600 NSEC test.non-terminal.C49.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ EJEqqBgAtQNULlby/XYv4/G7fly7PAJ/+F5t
+ hhydTQW+ey8By32q3emn0Anquww5BKz5qIni
+ cfZ9z/lKvuO3syuE+VPMlber4/bipZOEIuZB
+ GjzPlJbTr4bCt7V88fTCLKLKVSzPr33o33K6
+ 7l9tsW8LvqgIKFKolYLGaOMqgkw= )
+test.non-terminal.C49.example.com. 86400 IN CNAME C50.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ZhPb7s9CoPsBWUq+IGnga13wYRqk0BYjpnpp
+ bsKai4kgQM1zUXDF1nu+wn0jEL6kPz7kcxkk
+ hWRD21AHli8FKJix0sKI15sHHbl4J/NUgtU2
+ tZNqulcYgmBhIblKUK5IAz4RWITAP5LN0yN5
+ ToLSPY+jIplvhESXHDkpaQl+eCY= )
+ 3600 NSEC C5.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ ywRHS4r57DkU7gj/UFVoQMRmbZbyxRaLwjeu
+ FqN2gFrQCkmGTMRNul5HfOfsPI9x43a6Nugs
+ 0TqKVYBB2/06/5QBz4minnNHkQ1uJH3FD5z9
+ PEeaXVpZu9MFLw2a8jK/xpSg++x3SO/F537O
+ n1ogyfuaserb7IvI2yx3ly4CSEs= )
+C8.example.com. 86400 IN CNAME C9.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ JQhBCOWrOMe9jGuLF+f/paJ40YYPIVV8uqDk
+ Hc575+FNz5JvqVNkgAx1bJvd8gPtCaF/FR3Y
+ WhXkOOcAtPMjhrY7T/XLvLvgdn8aTgn6fZ8u
+ 6caWLoNeT3OKLPitIDnESe34VLWCQ/UlCgSp
+ YRHFKwNrhQ7+OmOeGpgLT/9HiDA= )
+ 3600 NSEC test.non-terminal.C8.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ QcnC1ITlSYRwTkOo1OH9HEctrQOvxdrN6tQr
+ HTOBRUzyXRo2Y1h3C26jOYRJByr7qXKNawjN
+ Ter6n6IADEPWRYV7Zg0Vt4+qwJuMQjqfuSY7
+ 1O22AohxORNNWwTN0xY/VZ32ijaQSt2o7BhB
+ WihKVAfpESOYX1jtQ8W6F5zFDSw= )
+test.non-terminal.C8.example.com. 86400 IN CNAME C9.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ kdd1XSlB+0KJnqo7un4RkRkv6+K7gOH+s6fV
+ FK0vycWI2O+q2FADBbmwv8q8kOv9vd/QsO76
+ lNXgXRMzklgxBBY8XRHQ2yY1ZGW0RabQtKFF
+ YGI3gcyKrkZ4YztYLrUIuylC/aPHQpJ1f3g9
+ dTakqNvJHenZyR4di5CTRoC6mAA= )
+ 3600 NSEC C9.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ G0si7vZjW87SMbVguQyB3akDnM9gAbIXks11
+ BwwvPFkKqdUxMP2Qs3IrzIKfhvQ4tADv7Voi
+ XRB/soteQwhjyYhPB0v78JfwCW+QwpDvxDRz
+ rSGeyv6eVB3gvBVcrM4RHzl6nFj5fmNUzmoK
+ CFdIfGPUeX6JLUO3W+xKURG1Nao= )
+C9.example.com. 86400 IN CNAME C10.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ LGxxUe4DNITcidfQR650xyr1DVBp0D/rUCDG
+ u2oTV0Xb5ouVH0gwgXhgEsJvcOrEgk4MiHy4
+ jhw4XAC/gmQ4meR4TmmRwsas7LaNbW2QKItU
+ DsWMw+YZEOZ7KhLgmWZyQpYleXffL+8uKUrP
+ fOdwL8Ww9OBF4ETlnju+rdEc1VQ= )
+ 3600 NSEC test.non-terminal.C9.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Lvswqag0N0AEJ3kFXHQrM2Kz5wUFVcq4zDQV
+ ZtcJ/iIb2QPDPG5yT3pxU5HIoZ1gjOeXfNCv
+ lJ7pyvtRpW8bGQj0HLd2gOuUEh70+qo2aekv
+ 8QJazPnS5CBPjWZvtSGmP8QAuj9OdHirnLRm
+ uKwac+IOo3oZfWGq+s8as5Fyoww= )
+test.non-terminal.C9.example.com. 86400 IN CNAME C10.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ D4ky0PqnI0bp2ktdwXEZ80xYFkMGcLLANsIr
+ LqZvATEMOjuVzbUjJMdNLKfLmBlmGgRr5sVf
+ 6gaXA9/eo3JcPH8zMVqmyvY6gD7TJcXtwaQM
+ RP3jbZkSiGCtWMICKLj907KJmgDnMXDQCVtt
+ RYbOGuYLCbHVL5rYJMRlCESUNTQ= )
+ 3600 NSEC CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ EuEUuQ4r43JFOIPkECbzhAcYpaGriljm6pDj
+ rJy1KVDR/wxXTH8f/uQ2u+BtcxpjyyYcG5Kj
+ k71Rt2WC1Flsn6eE+2yKL/n8LQOetoq4waAF
+ 6c/lndg5DHzk7Y7GyI5wzbXdA091dyDblaS3
+ +AhdIja5AST2+Z+969qqDcf0/oc= )
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com. 86400 IN CNAME AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ C7doptCNcuiuKJ2GrVAt7Qy+5LCN7FZi1E2C
+ Vqs66YPNUOb72yqT+ecRaNhHLiHIqwbMN/+o
+ E9S4wfs9q2CwVwvyocJTKPyN0K0yddn6qcnP
+ BRHrUgKJISxNMcYJVSwdK5+hBUbgUpObWt+3
+ EOlwPcpUrKHfKm5XzllM0DLK9KE= )
+ 3600 NSEC test.non-terminal.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ iDV4P8UjilQqgiPtMpHLM8o+HRinfsZh5zqP
+ /4O8JDb6f8qVsqe0DV/h0sxVOjfV34Xf995y
+ xI/Unu4aG6YKrZOjuXxd2LWvyuKMsPGXMoxg
+ gRS6OnFdCQ7+KTHOOed6QVkCZIB6w7FdkKOn
+ KSn8QQnuL33RFPkPDeCWdZaEGXs= )
+test.non-terminal.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com. 86400 IN CNAME AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ pd+sc//VDkJp1+BlbFho303VkO93Xt4X5Qgt
+ ONFE+VKy7RQZO6/1rZhrLjg40ksy/z0XJR8a
+ /jcF1Er2uyNOvPnTwkrhlgn+QlvbCv8I0PX+
+ kbFpfCEBLJf2LIrVm5hVUj90b8eMJPVs+NEQ
+ W0SjcTleg1I65tbc/EWrR0pKvck= )
+ 3600 NSEC cname-point-to-multiple-type-a-record.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ OGTyOmiqHSbO4VTI1ud+uSjCMaCNTFU4htwX
+ QaOxwgZp7vRuwXWmm4/bcULrEGO0ApbfO/dB
+ Qjqht4tCubrfohjTCKgrdtnW1oTDCX0WEbny
+ Z7FiyfkiWGWVPkkeR5Yp/jbvLNfpq3d1gwuf
+ Gan+0OJn6SOHXSidukU0OUmxvVA= )
+cname-point-to-multiple-type-a-record.example.com. 86400 IN CNAME multiple-type-a-record.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ HRwBdthTRu9uCH0bRVbhESMAMklWD++Ays3w
+ px+IJ5BNFUncLiN4tOF4B0/7fYoMnUA4Abvg
+ +Ge4La3iDNmEZf+39jVpg1rd7q4xpGk9Z4+K
+ IL2gGxfDKbPv47GBhyr+p3KliUMgSiXmM87j
+ 0N23b36G+/pMplZU7WHaQRIYjjk= )
+ 3600 NSEC test.non-terminal.cname-point-to-multiple-type-a-record.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ erY9Qx8ZeDbt5bKHRc9AUDbHCMZh8z4ojg6R
+ alodTp9OnabVliXc2ISy8jadyQy0JCt2ESFC
+ sxL44/MysCk/R+Nwxy8iwME3BaPjURwzwERV
+ NXoi6sw9nNZiecI9gMelVzH2BsNNf942/zsc
+ xJvymebJO+5Tu2eEGbWS423gU4o= )
+C7.example.com. 86400 IN CNAME C8.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ InFwe62Y4wTPpTE/YwJvm1ZgdmRLfF3TSmk6
+ mIgPYhBicymtPKdgnwV12GYKOdhbz/5Zvr69
+ AneCf2nM3amgUkgBe6aD8U599MIu9ksuLkfA
+ NoKdaIt3XQHFzGar+mvf83xnJNSTm8VvHQAf
+ h9KkrBB+N98zYsq8YclkJxgrwBI= )
+ 3600 NSEC test.non-terminal.C7.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ weOiGDryL0M7nv1pju83+o+SsE6Jmsi8+Fdf
+ PO7dXTqCbCQdANicrF3dgRqK3QkHcVzKgf40
+ R3UFoG8aX3fyYKlEInCpfO7dOADGnzbtZ5v+
+ L9qgHC4yIvJgIcBAVx2/xOVol7BcWyUYkDQN
+ g+C01TRDP7ogAHJUjwPLaHarXbk= )
+test.non-terminal.C7.example.com. 86400 IN CNAME C8.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ hH80bLwy2ntrP7ZHkkkvUf/S/vQWx4SYNlyX
+ /KihAsyT6wGxDsQ2RH/iIMTzsHUdLcDMf4gm
+ dqg3BgJSMnM53xbmjjJroTdM1lz4TcE+doiC
+ KO+ikqNOS81WnjV8l7ivqcJEJwGPb4TXoOos
+ FTQHBIIT2sVTRnGYcG+BYx0xLLc= )
+ 3600 NSEC C8.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ t8/6dGfb90qFvsKF76Jv1K3tHNt2pIFw9iX2
+ fvM/GRn5zJqALRpDJX1CTQTSTitHgPkGn34q
+ 54rrssOha4mfnd8E4VSL6FNP7+R3fXadB9pZ
+ Krozgbq4MJBFFSI/OlYucFSpK0rxXuDZZxlX
+ dQi68ViBp3Ghx9B02YbuHP4Rtbo= )
+test.d0.example.com. 86400 IN A 192.168.1.2
+ 86400 RRSIG A 5 4 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ d7amEXl2t7Fltx2oqQzhgIXUGF4zpU3PGJ06
+ K2qZPJ5PwzQtrpAiywNKFuk2F4sGInSjPNwg
+ SBWiL0h9DDKNwc9iKtlPEcSZ1q6nz/9+V0IG
+ d0nF7EJhDGAsC0Is0/ljZLfJcliKz+NeZy+7
+ H+q28Aywpu5mEv/fd0o6vjgbuFY= )
+ 3600 NSEC test.non-terminal.test.d0.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 4 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ eD4bO3QmM8GdweXtZ9tXTexxJMIEY53S7meD
+ VLkmpXZsFYpHXJsbWiEJ58yf2pfl+XvcSTbx
+ xMaqaCih/8wWY9XTH45FUUf5MMZpZNSWo/es
+ gMxc9h05pL8zb6P3EdCYSvHqpnWESiKxOuR/
+ Kmc2Gwa9e8dmiuDp4x+/RARlaNE= )
+test.non-terminal.d0.example.com. 86400 IN A 192.168.1.4
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ YeKJu3vDpMw9BcUtEWqm1BpKfRfUW18Rd13k
+ j0Cg2TgdcnaGmDwwXUdksrGkB5L/eeSlOkx9
+ OJUjnNM3LmoaDkN5OK80vqiQZf/JxTyySyYi
+ wo9b7pPr+jADB2PdXZ1bJcPClfD297B2//3+
+ BZVRHL6FN0FaPlToapzZvmsaPhk= )
+ 86400 DNAME sub.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ bAcOYw3hxMzXkRwMEzJ/ABMEEdNmg/LDozxR
+ 3zElZoY65UP/wkZuCeP1pIvguEc8iGZWeg2x
+ b08B6BjFfvIg1A57v/FAoOXFpAPpw4o4pa9e
+ XbyA/BKuM2jRvkj2EBFV5rf2M5pTT1GF1ttJ
+ DdVxM2zb4XfI/WVJURIlb+6ucug= )
+ 3600 NSEC test.d0.example.com. A DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ uexyxqwdJTN2si0SJjP0Rk96XS29y1jJauEn
+ /xcPSP1oJJapU6L5SzFu7Z8orT8CB4ALw91Z
+ YdPQm2epXRYomyj3Kq5R5zXGjwS6gIv3B+1J
+ mp+zHclVRsYY7QLDQAyOHkK+NA74seHPgD0b
+ YefqdzOI3QOSkQJNvUqTISAriaU= )
+test.non-terminal.test.d0.example.com. 86400 IN A 192.168.1.2
+ 86400 RRSIG A 5 6 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ QYOdM+npbMtsFSB+JeoR5JXk29yxjAcq6IoX
+ sqGKkKkyToC98o50/XH8bAxFj0q15r0TvuEO
+ e1G7dIJM00fF+/fBYIOJcXJ47Qu7xASzBYA7
+ chF3hB94cvNV7kABKFNA5E1+DFSwFIfFmClK
+ JLe2E5+SGwZfQFaSb2b6tjJaMj4= )
+ 3600 NSEC d1.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 6 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ EJQmAI7vp33hdzMgolypa9+qbqyxIspqIwYH
+ iCgs0TFxPQpXc1lY9SMhZX+8VoSZEArwgTsf
+ Mx0UkrlMC6sXi7A79Rdwmd3r4BrK4bdMrBKu
+ IrVLv7MCRUzUkHdVHYAbi2+3IA2l+/6En6Jm
+ msRMZCOJNR72sLqs60bURgXI8CM= )
+d1.example.com. 86400 IN A 192.168.1.5
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ sBA6L5PbxANfhF5YNHD8QHVPrjQGaymqnXlA
+ nIEN3w4wWf27y/+slfvyGDg0dL07+NkmJnMM
+ 7GXYljy7m+i5TDVzrVjvUyw5r6ML+/jXD6cF
+ DhUcozPWBPn/tGHQJm8W5ZYW7yyzeaBQZwT7
+ IJkYZ0bINEQ05apv2gd4GHnYmak= )
+ 86400 DNAME sub2.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ M6Dy+pDGgna7f8jB+DbPEz203TGCYYZijbYw
+ TlTw62kUbRUPrJbL/fQkE0rU9Pc3GJEtX4Yl
+ nhye2+iPZIelnQblQcF9Zcg8mCWx/P2HT8UH
+ B2xDuH7HN0yuvHSXWVebEdlR4xhGAyXSCRkP
+ rM4giGRyMaKuwl85WFdrDeyL/tU= )
+ 3600 NSEC test.non-terminal.d1.example.com. A DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ R6E/AnwSdFbKYMf0khvZ5GlmWhtzbkTkoirv
+ 0whLSIhHvM24jUt3ZbtcIn6xi+hcnBs0MSO0
+ wnsoJhGvM37cJH/sdYrwkC/W9jajToJuydhG
+ fe7jwv0jw3WcyeG2BCoktpx2ooaFciCxrU2T
+ 2ncR/dKM29LQzVULPBP4rgcXtkk= )
+test.non-terminal.d1.example.com. 86400 IN A 192.168.1.5
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ EITEKYUvoytFHIeie+a+hKTi4T24/CCMV65M
+ qG52AKrHK9x+LQ79FMFcSAmMgh3z2DDQ9dzy
+ jy8KxUVuC67AsXNcoGEehtup1GEmTAMV6BlD
+ vAYdgupQjuhcgZRix2HXDkxpW+fy4wqjbJz/
+ 3KeUWWIglCLBipPPjNwckD7zmvE= )
+ 86400 DNAME sub2.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Ati6eUZSBzXnqy+TQPkqhqdMngsYJSZo5vxx
+ JSMieiy5+vSptViQanXzkEGJeYMYg90TcpBm
+ fUGj/p5vvK5OtNZvawM1sXR3mLBBRSibUO5D
+ RhmzNWuJ2vGCZn7/CEDZ9X75Yq4cbg7A3+AU
+ g6RATYnQ2WptsSukGV/LBL/qBQQ= )
+ 3600 NSEC test.d1.example.com. A DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ q5n4L+3en23tfTmj4ZmQvBq1KTB4KL//Ipjl
+ IrIHk71WV1jjnVHFzr9/baas33nDMgnCsAWi
+ x+wmB9tPRfHqdJrbW0f4LGBM6cTvc574RYTK
+ 36CWvPmTy2GwaY5BTZEzqililQjOJWpzGJG1
+ jaWb26cNeZdOGmTviCsbMkk4d8s= )
+test.non-terminal.cname-point-to-multiple-type-a-record.example.com. 86400 IN CNAME multiple-type-a-record.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ s2YVJouV6wX0PRwEl2QHeHk6nFLNxNhdrxgC
+ HcfpI2RHamYHK0eaZfiuEUfXMRcht9Lds04Q
+ qpv03hEl95MxRhH8PqRuXBDf5QY8Sym+WEL3
+ /g+UgoSSpJZ3FAdFCa4iOx4x9Ms6WH9E9n1h
+ KMr7L5AhXVMexoY5a3VEhmGzPx0= )
+ 3600 NSEC d0.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ UAxKCgnQ4DK144UA7qjlFZJsqbbZCPEa1YRE
+ 5rdt2j1oxYstEFrfYIJlm0SDqQ3MZxSnwsQW
+ oW51G65Asb15F2lhYeEf4b+haXDa+dYW7xPL
+ S38QEKfPlUjb5Tp+Bzv5TT1phE0nalPWgz/7
+ FH3beyLu+Evk7YxyL0qJHf+F04w= )
+d10.example.com. 86400 IN DNAME d11.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ N8yrn1MJ0KvV68ZB8FQIYFbmH4WQgRqjuolh
+ QU5PGbdNHPHftS9OtqIRmJ67TtX353V2HYrk
+ j11gfQDOJhXAPkmpbcocNE99270xPJlNgvoX
+ 85v6T6K7MT4k+AlKwNPdiutjHlrJnVqr/lvy
+ NszBTro5qZuKvt90xguql5trIH8= )
+ 3600 NSEC test.non-terminal.d10.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ xU/8mB/Wj7cpidggEOGleDIolVYXx4pLjUhR
+ HM4AV8TtH/A4/mlxPbdOP6ZQ58O6yt5ax7VX
+ LxYVf466byp/zbBxgQFiXoCYfGmSFR5szdxw
+ 6REV1VMQlQEiERXJrr8OkNhf3mF75TufD5Oy
+ VqLwVXCrNlDk8wNhs4KbiQa1LVQ= )
+d0.example.com. 86400 IN A 192.168.1.4
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ oQ88aQZo4/NrYU3CLYAs0dZ/nky/sab5qMMI
+ QhlAQ1Cke24EhXg1qDKqDs2VxmlXU4G737Pg
+ i16mMrZh4pJpTcnbk48MKJxN750OsLjuPseu
+ mzsjUuJF3qRxnCxgVzJeM6BkLjN3ws9Nt2KG
+ YppKHvg/vAdm6AcKMhS/LKVWvJY= )
+ 86400 DNAME sub.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ VUYk+8Cc9GVU6urdV9NQ8sO7J2LHdEhN5QP8
+ k1TCiibxXulrhn2EDKhoEqfYHJkChZovlNDH
+ RlfNoiYvXCjpm8En/5G2hmpL+DdSbUKJO0fC
+ wOgzfoS3u3AUCgUBVTA8U5OBPHzoctp7/J6q
+ jhRxjVhz02mLNXh43dELM9dQeQA= )
+ 3600 NSEC test.non-terminal.d0.example.com. A DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ kY8OOpMJfUPQ6rfHeOhtE5DNKqXDKrXbIcXc
+ E8NA/M3c9Wpw00d/VEzSqPP1+mNXX9fJoaOe
+ ukWZjsCkv5QJMBTjYQVt1UzQmDbVt4Un/nJW
+ eA39f/ZXzUm04xVm+EOhSN8SV9It7w1RMX94
+ t9S8xI87nZi9+SeI/+49jeb6j78= )
+test.non-terminal.d10.example.com. 86400 IN DNAME d11.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ maQTzVPNfa+5C9Rsp3VWjNuQ4FuRjJ9SnIDj
+ xWv4KeMekO1qZBhgwME7OwViVlTpbIZje5lG
+ o/NoHwb8GhQLn3tsh1VpnAuD7hifsnQX1tyv
+ LVYee2VZ4H0N5N+qtfdoZvmuAghbxDOybLJX
+ eZZddeEx+vDMjK0rNiEtn/P5Os8= )
+ 3600 NSEC d11.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ oSGx7H72TvxwlepMMJeG6Dhy+QERBE+6iDDU
+ ufYYmwVT5QbTW3cETV2ZEmhztVSXU+8QnyfQ
+ dnSWeCPSBtE8wy9F11ID8JL19H6GhsIM51Hd
+ yYwphYDjakzemv6AZIpH67p6O/FOnLIDwJFs
+ /N3uOriCS15WJE1XjcxSbJwHrZw= )
+d11.example.com. 86400 IN DNAME d12.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ pQcnUhuzKnyV1dz/VU8TfsAZ+nPhbqVrPco2
+ MTbDaPSLCvZS0ulKr9Xd+7b7QFtTxNiX9Sm6
+ fMzVImTeJs9B3f52yIww83fnHMBNMC4kGgaQ
+ HuiNuuarYYx/r1fEXl32lo641DimcwzkdvXI
+ hJdRHFMLc4cc7G9mur7Jz6E/2u0= )
+ 3600 NSEC test.non-terminal.d11.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ sFRbkTOCCwr4q6uaRJgXv/CuFG4soo2KX3ry
+ KhannLCoaIj3ubwBlCODhEBfEVLvfkGUjoPs
+ 6DsXaJZAgtKuienXGHF+N6xruqAivCAuerF8
+ UK1pI9WKRaGMop9ZhzUtPdTSYho+2b9oCVQ8
+ fJ5zJuCTWCOJUl1pVQf3cYpCIJs= )
+test.non-terminal.d11.example.com. 86400 IN DNAME d12.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ZCsTTfwiwj0ZEbYFvRLUFrCbV3Cf4/vv4Cm3
+ ruCXQgW3FNwbBTors3SmPdGj/iZt7XJCezKU
+ IojMdcKvD2mYZz9GxcA1wEGa9H5bDT888Oyj
+ 9Lg7PNdx2zF+13t6Sx8VqS3c7A5cStnxQVXb
+ 9lqDxeGEI2cDsqc1lb5ZgqxkpoM= )
+ 3600 NSEC d12.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ OJG1fogGzZ1j2y/5n8dIwl0YmcPXDLN02lqe
+ b3/YkF+CXHhbCKxhNT1YWM0q1Ex97SMSsKm+
+ HtgO9Lt3bIxMTkz0NyffspS7YkQYh7LBS2E8
+ KhwEXgX1G/FPeC4F5d+7kPdoIWaztLtE6Lr3
+ UlbN0LlRTaPC7fey9X6n3K+8DPA= )
+d12.example.com. 86400 IN DNAME d13.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ lz7yCcwp7T5q+EEuvANyZGkTu3aksTx4xPz1
+ DabQhnaJTagbLobu00sKMsCEHEQ/m6HNXJ2c
+ Rak4p2JS6T2GIOyDSurRiWbiMmwHEb/wuOOX
+ Q1JKM8zwrSzkZ43sp6OStotN6NpTSRFOxTyS
+ cWGl/O7YP1JTms1SmvEui9oY1TY= )
+ 3600 NSEC test.non-terminal.d12.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ XF2aBu99ZxNwTtBXg2vlhcYJgo1p5JU03JvW
+ iCnjEVUt3W0Tveh0qvjuM18y6bK2PMbmSW/i
+ aiJWf6A+f/LkcmrkIFWSOOO5OMISy1ew1XtI
+ zHQOvVQQN20q0zrVpJPUjheYoTyBDXG0NAt3
+ JVxWsrxdNwuX0rfk6IAvlZQyGEA= )
+test.non-terminal.d12.example.com. 86400 IN DNAME d13.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ RVwECJFNIUFt+LUau5wq7zH5I8wESLQOj4mx
+ QRAunw5SVIr/KNyyFA8QAtKn+H0gefywZyjk
+ PyYmDKIbIPu8hnBBcrkPOztKUzvIzV/MParQ
+ DnlLlXDw2JQVE6HE97MPw7mPtnb8Bf+4ti0L
+ QKDQ7dhU5A2TsW5VMlgZAOWKQdg= )
+ 3600 NSEC d13.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ XOx2kjlmwt/F7sNwR70hKcWNOuxLBO+sG6Ec
+ fQoZy5dq+U7DUk5opqHBnTgLTpElu5xpt4yB
+ UdLrZ6Yw9RgYWyualSjRl8KlarQfb2G+UzoC
+ K7yj35zj3zVq39dz7EMB5J7JxmMFIsNjHdsY
+ RWA+UVOZFvDkG8rUpWrUs5yKVnU= )
+d13.example.com. 86400 IN DNAME d14.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ jtsqmXsjCvfCRTfoUM+slQHIuAUNWawsExt0
+ kM5CcGfN1pZ+ZZtDPbU+JEp3A0WrVyRhXghu
+ QYHm0aRxJgeKoqyOuw6IEpzE5BuPj+VEJopp
+ 1Q8ie+Bcl+NBr4RvWhje4v7df4WQ1ViqeUey
+ +DT/n5l5BCLR9E1mz5OhQaobHSM= )
+ 3600 NSEC test.non-terminal.d13.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ vugIOlfbCi3BSPxGVKivU3W/lxneaodwLxFU
+ qI6MPkrerZSa1keH9RQpomM/pTbttE2iYeCg
+ yna0JeheXgZDUDMb/Ck57IVFUy4HyJzWOC2m
+ ZoPq7TktRPJLcuKD7iYTQKNO2FnWztQT4j4z
+ WpqisRrvcnPAmPqWYKYqxOVKW2A= )
+test.d1.example.com. 86400 IN A 192.168.1.3
+ 86400 RRSIG A 5 4 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ NpI0Q1mX4EZwg5pWP9qVCEYFUbmJ/PUoTIC0
+ mnkw1qvsJZnSQScZNogcC1HSQ6fcLQEWmwWP
+ 992edBYI8rCHku0jFm5FG2C7rro0eZFYGs8A
+ irix6jJO2YQfyxlWjl+WW1T8GSvB1NctlNf3
+ Zbpg590SaPcTOx/3B862E99rjJU= )
+ 3600 NSEC test.non-terminal.test.d1.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 4 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ F6m1X0oeLpcz8Oksun80lQQn/frSOkK6isrl
+ q7u/lO+JaLEhmpRPcFVz0zjO0yX6gVFG2pOA
+ /UuqiIPpGsUui2uDPPPiVFF1kasI0tS4jBeO
+ 50QfJX08DjOyHAxxMcZJSrInFBFfW+Yp0jL0
+ S3/yPXpz4ziNdJpP5C4u/tgKoM0= )
+test.non-terminal.test.d1.example.com. 86400 IN A 192.168.1.3
+ 86400 RRSIG A 5 6 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ KMVn/uUWxGkIRnzcsfNadUu2Xirgh2p1Zjm6
+ TSyGtOUTf1Y5JImsHOmlJbbg1JH1bzBVOvGi
+ P31QZAKn7XdkZQVcnMfEzK/KjYhinYeWCAxY
+ 2UrQrsdakduooGDRKcYFNrs6ZWazwLA/QwnQ
+ CAp18msA0xlYvwWwVAnKi+54Kt8= )
+ 3600 NSEC d10.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 6 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Ka9/TNblKzcJYDkV90jalAvXZcNDQbnr1aXZ
+ 1yeHGNtBFvO+RAJgq1nE0BV5tT8BVD1KC7iQ
+ mR2ejl7i+06aJS16sn60kwT9fRr9/Mkk7WRU
+ k375Xej29lM3+JgWTyWcP1iHVhzYOpuPomsd
+ N/HORL0HS5ymMvXlk0UetLQQQQQ= )
+test.non-terminal.d14.example.com. 86400 IN DNAME d15.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ QH/eV7byBiJKnouQxYqhFJz1DNCS4Uy8kvDV
+ 9zohKkVlqxEq3HzE2RdG+2DpqJPJhpkMdhnb
+ wWmxsquHv0P4d9HhS3AIrNiXiP2fujh9sIiN
+ 1ySkWFsldgsF2QupkGbeQtKLVU3cf+JrMnOI
+ NjCMBG93uXw2sZeknPszq1s5OlA= )
+ 3600 NSEC d15.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ V5n+CIgwa04IVSIwa9gPekLzJp7rECoPWx8Q
+ ia3S8ZghzLAKT99vVcbvUdckbB/Qsh4o9jyV
+ pFb7sTzALBoOc1CqDx32anol3qIVNel3LJ+w
+ 2kGoAY5XEWC5TYr7O3P0IFsAP6miLaEjX26H
+ bmHaNF7omRtFmL7RigRLJQiNiQE= )
+d15.example.com. 86400 IN DNAME d16.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ CyLqrwZuL5yPAsxRIwqXk6jsmMIhgVNOqpNi
+ iuEeYjSSG+gFFBxeC34dX9/6kn6pla9fEa5q
+ +dxcKGqBbI6W2EuTLkvX/Z77JJBVD0Om0qmH
+ U906M9R5GZdmT/2VpYgjR6Tw5jGsxlczMhQI
+ 6zAhR/M2/TFgKex+rGMMBRDH0Mo= )
+ 3600 NSEC test.non-terminal.d15.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ MOJen55j8/qZFSNur74yJOZvkz3ECUDyRTiY
+ y9NgRCcMpweHzVk4WyA1+QyqpApakV+Lks4c
+ gJlwCDg3Zbi+9dDiSq1B8wmvTXlpHPDOO0rw
+ hK4o6Dlyc40UDddv6YJNF0jmsX1F6jcGHn1g
+ hyl+xn2IkeqBk3hIph9quhF18+A= )
+test.non-terminal.d15.example.com. 86400 IN DNAME d16.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ i7j+ye/1m4ZWC+1RYOcBENaSp06JadRLkagM
+ EUIws2vhB9SqtfjDog/qalHm8dVZwfFhzKrQ
+ NSo+A1Ft3sC1NfilIvi0yYqwsT5j1WRpeV0Q
+ T7Qe1SBL7DcDOIoVsyKo7QDabLJbF060e0Wg
+ Emfzm/J46/jDtHhOm/KFpsFZJJ8= )
+ 3600 NSEC d16.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ UHG6zpseu3ud73F/HWeU+MQPVpBgQp2z/hO5
+ HcqM56Af9CXBN2c9s/WuEtqAi4KMOxM9YriW
+ RAembvuikFRV6JQ0H+ftCoI2waF4Zu1kLcwU
+ Y5NA/xS1xLgKSdrO6JgA8RlwcOVENt33tG9m
+ UVkV3XyI8Ppxjc7tneTJhEoiGo4= )
+d16.example.com. 86400 IN DNAME d17.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Mrs5QfcEbOCIuJPVSlErmXgH628g9VuPHugW
+ TQRp9yB9oWO710r0mQzagWfK/9VFA5cPnoNY
+ MxrBWAN3a6O0Qwo2BBUmPgxUsWUJ4sITCDt6
+ ystNF2BsYqMv0h7tYnbLMM+AfuojoHY1Z8TA
+ AISB2lEn0xa8HI6X3CXjrNIJxco= )
+ 3600 NSEC test.non-terminal.d16.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Hbdv3SdJolh0xmSKWSLdqZRzo7V2nWAL7ykn
+ 5RAWJveZvpeZNLAafdePTqygEfUb4FrM2dqr
+ jm1P1OY9s3ECWUngYn6+2Twn1hS1IiWs1TkQ
+ 0cf8egUDmrQ3jkNU213GjRaj2/ir6EL/Y66V
+ 7sI6DXH/pVIY3JBfgGXbferkn5U= )
+test.non-terminal.d16.example.com. 86400 IN DNAME d17.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ P3L9ijIF7sdq4qbsFz2+wshgtrnL1Xj1CgxT
+ sOv24t8YBfUSJz9udgg71rqEJcmYHsdRxyh3
+ m6A3pCvWLW8CSMfedp4AAner+2WFYZ1CUJlm
+ XdCNDnOVQNKagEur4yUjLLZRjuTtD5JRkVp6
+ qu4EM5u/4FR8TGPg6orpC5wgkJY= )
+ 3600 NSEC d17.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ lsG2m7m5cPvmyqOcMiUKRsoDwnLs92Lz4lbR
+ 41lsyaKxk++AlegRyeaHW40e+yIj0Nk20olb
+ LzJopJfTgLsjUOf7ClMoQkXz8+yCsDWqbmlj
+ ifM1EODugwoxIq4K+N2zQ4tGMvNLxUvwqMPw
+ j+q669F0vkZPezOPuVWS+kTSrP0= )
+d17.example.com. 86400 IN DNAME d18.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ BaabmIcyWNJcSmaDlM7/HF7u1ZgyPVxwJCTv
+ V2L8KN5YVQaNwiVJG4zyoe0mZ20568eMxIVr
+ 4KRMVdv/NXhhKJDy3pVaWdqViSftBpudIooZ
+ TBy9SgIe2FU4nU8KbS0qAjRzrfJ9vNktKSTm
+ ZeXCxNd5HD/6//F4T+DUkS0usUc= )
+ 3600 NSEC test.non-terminal.d17.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ dUzhCcQvrhwUt06MySWxzwGK5sAmLhR0XKHk
+ XQotzD7u3kRwmSbiCH8BL9cynW0kiTZbdOSC
+ RToEgEPRFLiwrOYPxWVLzgcXuoXZxvHgnFRh
+ 8TaEispFkSFRqCCPqCSetKuV5S1IohCDGqLq
+ yXJ0Vi7H+8dKchGgnDSjJKRSWWI= )
+test.non-terminal.d17.example.com. 86400 IN DNAME d18.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ CJNF09vYxJ0UbkjJsd9P04a8Jpu7/kSKLOG3
+ 67ftUASZoalm1uGIvJMjcXidBUod4XXT0ljh
+ LTuezFj2kKbZw1YKcqDNv+Hy86Zhi07v4FnC
+ 75n5Rm2IgyfunvaBV4VnckiDRduFbSKJQaqx
+ GhUBQFzdApDuvaUcrdw41aLFpuQ= )
+ 3600 NSEC d18.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ KJFyF3FBlv5nkj53t8xoUKf5P6aWFQmKgqxW
+ fts6nY8fjbmAvOaf4iPwgx3VrnQqAiuOBDcL
+ oiLnY6YN7mnn02Hs8YLH8qVUB+BaPnRGaFZM
+ /8BY0ssr+oWihGlgZpXJjuNgC6kWNEbbrI11
+ 6V+pImV4fBODjh1TM0wrnjSvm2M= )
+d18.example.com. 86400 IN DNAME d19.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ aF6mM/YQOWcrjMTe7MBaSDmuO7/6qFwHAUkn
+ hooppu+GWnuYr0O2tKvHJ+01/Nq3GbVPddno
+ Qcg6zYk6Zy8cfzaifo/b3HbY7/sHKBZjhW4H
+ CkqApNcBu5bj1DvcaNudKKzu6EEfN9JzDXZt
+ sfSkTW5rSneiz065dhGrbm+LD+Q= )
+ 3600 NSEC test.non-terminal.d18.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ oJgKUcyZVatFOgKIu/jq/2nazUHSk9yYiEWj
+ mCh6J/Qvy8REFqWrpkeGu0jEw+Pclaal8QKY
+ XFaMCXHogWucpwulzuFDS9r0VMHxIjPdUAoL
+ 8M7oxBV3cjQogG29tay8L67XCEnQ1jhNW8t1
+ 1oJ/VgTvsCZbilvCtRYEjKOcLqY= )
+test.non-terminal.d13.example.com. 86400 IN DNAME d14.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ neQfJMo/qebAeLx42Lb1u7u3EBOnlumBB3EM
+ uy+6lk8Xvxvj9mHmcGhD8E6VNhJz20fG2Cdj
+ pCctrOFr+Bt129aNALiYFvy7SllM9t/i2Fca
+ OH7UnTX3ZGotmAlsEDOevZwrC6Q78KCB4Glo
+ CHMBE8r1LkHZML5zIJJ60LKqVpo= )
+ 3600 NSEC d14.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ txarW5KbElkJuR0U583IVm3vNRUK6U8PP2oH
+ fAJ0f0gEJ8QrRnc5xOpFLnT8bCzZKpvpTCAG
+ gVEqLzO9scIajvMXM/MrWNFI9D7V3KTSHAmR
+ FlhqpJnN2agXMduEGxqBowKpGxFqFjISPg+5
+ AiPlg3drmWqO+0KZW6LAR83nj40= )
+d14.example.com. 86400 IN DNAME d15.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ QIprPxslxv/sZo3JS/sykg/RS8z9ZP7F3b9L
+ YBJBfTQ4vLaqnfUY6EA7cf1vvL8eigHJNXBw
+ MZGsp5S8O9dgUhc/TtBkiWXn/Q14/Wdy1l5b
+ gZKYTOcGhD+tlTgUooyNU19APMX3vEDFp345
+ JQyVw3zi96zX/Mw6dIzBcVPlKkw= )
+ 3600 NSEC test.non-terminal.d14.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ pP2JMjQ5Zgc2AWXkTlN6qCVl1SXfgIk04e0a
+ IEsqJyEIvVZdzPCskvOc2GHvaDJ4pLS6mTQ9
+ V4OWdkDC/jNesmdsY9MFbvArp31pHng/sYv4
+ RSg+cC1ZjhXxv9HZcQ+SjYiDZNpo+ASokpR6
+ XBXiZZKAZJFH+GE/HtjRIr67K5I= )
+test.non-terminal.d19.example.com. 86400 IN DNAME d20.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ D8CYk/S6rFMD1jFoTxBWIj2HQsyvFas+MgR0
+ gHGMjv7qgJizcay8CD4Pa2bBv4r1pGeFzL0o
+ OE8L6nrbGdklEDilJ1vnMZLSadybVFx+rfjR
+ 35g3oJhF9pxx6Q9mSKA2XGKMj37J/+VSlwNF
+ ktW8QfN9xw0htvcQ/ovy59L6YQw= )
+ 3600 NSEC d2.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ yhfqS6E1PTtvR+6uxLuce1dAASE+WIBXIxqb
+ Qqu1gdor2LJZdhNo2oYADJNOpaO9ZUNURB0x
+ UE0UdDaGF2EZlaA5chh1BzNkHhPvx5vfUHQy
+ 7+jupjFFDmjeq/R2m2VKD/hzstFElmOgrRND
+ wIcZSTehIOEZp1m02Fyq+NCayvo= )
+d2.example.com. 86400 IN DNAME d3.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ jGJ0gTTY1xQ0jKTXs9h/9NQYZufrY2wJj6+N
+ CZhLQFAIOETNBrgLiglcBde+4b8YMTFIb1vv
+ jX8dOZWQdDdmzdkHTOrp9zmFQ01E/hOMvDuQ
+ xrQzRDWer9ekzyvedkX1KOlWnoegs79t4KSr
+ ZILTZDUJXhBvn5T55DNHJq5WYN4= )
+ 3600 NSEC test.non-terminal.d2.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ lo4Vm2n0t1q07yfsHscXC2XwBdqzsNTJqy0F
+ OEG6oXDCujR+q1DwFyWwZ2iK2FjFfrmpus6o
+ wE8PkxWCJlAhlGandab77MwIAD0Qv1z2fgjd
+ eMKhN2tqdHIGScr8/NszhC5Tlz939iB3FQyL
+ BTQecjH3bb3mE/GjASjKKP81AIw= )
+test.non-terminal.d2.example.com. 86400 IN DNAME d3.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ FiOhlWNxdC2WCLplysnKFSXko84vNOUS0bDp
+ LX+d3oBHBN/+KKyiIwWJdwfFQ5ZhThsOQwGD
+ eTU3jdXddMU3L3B/XgPDeFAYjocyzKc5LI1t
+ Yjga70MUEcO6BUojB2QG/TcNDtdVEYiv7l5b
+ d/P/YefpjKGyqGtuyqV3RBNqPNI= )
+ 3600 NSEC d20.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ pd4iRs4YDj/nR7rcJxeRUOFwHcbXDwA8IZ/X
+ WhO7W6M+6wfYUU6VW8dAF+rUqHcUd5+p2l+M
+ LT9hjUxqI/nvufcAtOO0Wd1JGvKlI70s9vR6
+ /VAbIg20abuK9tWdjy8pyh3kY1Tkdn2Ah/7d
+ yG5O86DDTRrVsz5SGTecj4w/RE8= )
+d20.example.com. 86400 IN DNAME d21.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ CeRBWcoTPJayf7tSPHYoHafVkFfDaI3z7XID
+ /W4f0f0LWluOdljl2k/9bXk8OY4ajv1Pc5Y5
+ IPAQ6XMUhVYxWe5o0U3NhCP3QZoissiN1a+z
+ GUCDCREsn/OvuXdvN9tIfJmbqnb7SC6fDTZh
+ aEZ9iqRVNk/N5yrxWHFMFLyXuSg= )
+ 3600 NSEC test.non-terminal.d20.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ ntRzsAX8hoSRRTd1eXlDeVbuWjH4xw/BKx5K
+ Gz0JtcvbOkf3cmq6RjJs7lsEG0J+Noptbawh
+ vW2yj/nLWantQQF5b5t36LWrfsTLLPOZypQE
+ m+dpzV/GpJURrwgDn0uxm7Y+68RRildmzSqz
+ C7UDx1p2PswGGIXh3Dm/2fVrWiw= )
+test.non-terminal.d20.example.com. 86400 IN DNAME d21.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ kV6a/gXbO0vLbS02YAs8+hf+NKblK1v2INBx
+ JhLbJi0sM66LxnoJIke4910DrKXQtojP2eqN
+ 1KP9dt8ND9iWmGhhJMYqfQMJRDzzsl8yocbw
+ 5sPHv+ZkZb5YhNal1LRJtXBZrIF73CIr//nA
+ UBZdn4SJBp/IW5aEuUeboGpBLJc= )
+ 3600 NSEC d21.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Lu7Wt0xdCaEyXHI0fZWf+ePvmw+aop6NPVoW
+ xjuf/YBLqJsUoIFYJAiFtuBPHbdhIxRHVvN0
+ oq2qdV77lw8jbHLEgnoLdlP9DX88cTioJfs0
+ vuLmYhe7ncex9jRttJWPyhF3PwMuIkNILeU8
+ f26nDo8nlLay3ikFLqZGb0Mgip0= )
+d21.example.com. 86400 IN DNAME d22.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ pqtitqFpSeaB07zL7eZ9RQVVW4VOzlFNyZjL
+ cE2KtU5mcTWUhr1zukR5GeHbK5GyoLQwnPyU
+ cFJBLt6XfTnXZ70kZ1w+YfFl/+skBgPRDY2C
+ 9Qc2knigQo7noQlYIWjamzCdp9zGf1Q+jb7+
+ iWq7+qLElbcgUrb4cwX/g7i5xMo= )
+ 3600 NSEC test.non-terminal.d21.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Z8+2YtdqGek0KWucd+dFVa1D9IEyFdTOtijr
+ 1erfz9TNnNJqT7oMmI2EWVMOLNfkRTzghUGG
+ CwXTZzHrRlKs5Y2ImUaTqJ6pZY6AjOKmBwQF
+ uPJK3Eal+mrWwOfKwPZy99z+1JwKrPP4GfGC
+ 30CoJAfpU++EfGB+Yi8CaeN/IkI= )
+test.non-terminal.d21.example.com. 86400 IN DNAME d22.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ NouUFKVMDc2EFJzTKaStH7y2SK5idF5XhVqp
+ jsp0A1ArQJ/OumvCHP/EDuZh3nazfjlRmGWe
+ xXPtjKVQ9mo6MPEs3C4y5H/hkyfHr0SLBJPh
+ ca5Lu2w5YssTH0ycqVcR7vaE1FITxF1J1m+O
+ WUNgzJ8C1Iaa9NvBuxIJTxVJb2E= )
+ 3600 NSEC d22.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ C8sQzFd+I4yQcCjiYQ/Ml1WL4g24qN95wuJu
+ 14KNhLoDIaJdlrAOgIACRT9RgSWTM69eeFVk
+ iYn4L7t55gj9eBwAqHY2bWWVqkQ4WkAmD596
+ B1zLhRWFL0c0RNkLgWpHuxkPg2qugWCSHdjU
+ nbXhNKfhAWYYE7PmZC1r6cLasHg= )
+test.non-terminal.d18.example.com. 86400 IN DNAME d19.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Euf38MjyhFOhK4YGImOfcfXajRNocQr+04zT
+ gjI5O4lzb+tYJKL5nYSgXLEZ0KdNCttabkT/
+ JEa7Sgfc3B7Ggi6f/dt1VbsR4eYcX0qd2Mol
+ lUNaa2kCdpkFcWPtvhTuHiFcsxacZumk93zM
+ CFkI5H9jbF42E/ngB1kRDOiV51k= )
+ 3600 NSEC d19.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ ao23NWDq68jedx4get+cBEPZlYVNb8Kf7Zer
+ GcrGth44a34Tp9gOUJeMlhmp6UzmMIo4BK0/
+ 0rf3FuLsReUfUGQjEJKY8FTgsHpM2sKhV8QE
+ gPvlLlzmCrIz+P9HqPsEhnCDgCBM/Dz5iZzQ
+ h5ScTjYMSuTpdf1fTHrFBvjGVMc= )
+d19.example.com. 86400 IN DNAME d20.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ N0HT/PTQBnVNU4A9eBQUTyumrav6Ri+C8cy4
+ tgL4Uw1wcll/H3ruCsDqERZN4RA8xKCl/C0I
+ DjAchaz6BeFUZRp7ETgWJls/qmsH62LCnIhO
+ pE4mW39A3J1tB4a+3C0ZnbpaQxU51PhJanPt
+ xWDDw/CoyWfwOhL7dMtk7cULpuI= )
+ 3600 NSEC test.non-terminal.d19.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ tseJRrkaCddU99/+haOo7Y5v6pBj9+H8kzIo
+ 9WR3n3EkyA9fuRVVad2Iv4OIkuJugeCFAOb8
+ otWAH8LSAMc4cGZ4qndAtGz+/Bo9rgTShAvk
+ q7ClqBDzQd+G1rmMp+VdiWJyWC28/oaE+Xhx
+ zx9bHoILa0Js+eUKGxC/QrAb1VA= )
+d23.example.com. 86400 IN DNAME d24.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ JQgGS3/ep1C33sdFynMolV09rQiB1bvIU6JY
+ DDd4zfdg6gARv3Yldzz5imAtZDuPsLqMOC3T
+ X0VsQDoqtPZ+rxMtF5U6KhYcyAhzk8o0XhaZ
+ nkyky/jPrh8/A+ZDqg4uDyTZ1yQjWHzQNtKX
+ eVyrdovSoorPhxIChMv8C2JzjYI= )
+ 3600 NSEC test.non-terminal.d23.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ R+6R821usGq5plO1LRKnAhr3TVPG1xVOKpJF
+ RahtcPiOgoSt/FbnuW97VEjmZybVzOq+ndV6
+ 3mJE5Q+/eIHw2WegGP/t+gA4/9q+GEyI8MCK
+ nRtoRN/hRzKkx0Vu2S+0xUcJ706S2rHNgUfx
+ QAR+ZQI9ziD1wKwmqGrezpTIxKw= )
+test.non-terminal.d23.example.com. 86400 IN DNAME d24.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ bcaFCvHpwUr9kCxPk0IPISNyyoOsut3IU6K0
+ fvxJANFVZSC5v1qhw8xI4wXKwIfgDseuvV0A
+ nVkS51MhOBufduGzrDEEJdJo828vslVqfZq4
+ M1cONAp5dTwHnd0IBB0xpiPKy7X/eVgpu+TU
+ htZa7vHOtSbPsg93PzBUDxu4Yr8= )
+ 3600 NSEC d24.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ SZjgbOAcBDMqbl98hQioFaBdclLDvPJbY19h
+ 0LapWiC+Ul2hk7Df4606+VV65EQhng/emr6W
+ PmG+wejcalWnfldCruIZ8Qp7HK3YobtpkxRP
+ FZcq1T4ye5kTSay1FMV5exqMnYKmKT4heZKC
+ 034OjugQbpwBt4bC7FngmlliVm8= )
+d24.example.com. 86400 IN DNAME d25.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ QKTiVsUl1e6CXgJ+dwuTnvLZiw0VVmQwe4cU
+ JDXLtdUepOYadkKrzds6sf5ryozOrImuKear
+ c8HY3PwCv4wh0OPpwm1moTTlj6qhNsnJZn3b
+ n/INtiSe1Um/LzOrdSVSDJDoX1LU9xivbQk0
+ O1gfIylB5E1s73QgrOag0PX67Vo= )
+ 3600 NSEC test.non-terminal.d24.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ f1FbCR1voPyT2gOIOXlWXh726ghR2WgHux7N
+ bT+EqTAdd1luHnclhU3Uvl2/00k78JBjwYID
+ CM3q0IHHN4A1A2OSEQCcPVJEHb0bXzCsZS/Q
+ fyNprb59q0aJQ8mUtO6UpvRbJu5oXcgDXbSQ
+ pRJhrM5NyUe0UsPkG5pSRC7byqk= )
+test.non-terminal.d24.example.com. 86400 IN DNAME d25.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ AvgJxGCFXcJPQKBfo+wgLP9UDEKafiG4SmXp
+ gZrXhomFJVwe7MSlogv4p/sH4NoBFjywB+gD
+ pTZfpT1WeMh4t2mgp9OeTyo+OKWocnwtee1s
+ tadIlU4d2MO2d0Eab95JkvacYUFNnpkQ8V7q
+ ChOUt6nHYrfveEz/j57dSsuGCho= )
+ 3600 NSEC d25.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ SLYSGumPiZQGIm7sZWyL96JheM79UcNL8Jby
+ 8Cjtfanxj15Zz8jKnDUyWzeJIHGd6uKjXi/K
+ il7LLGm4hxknlWLM63WG9argPYHDkSDYlI8l
+ ov1fzhrmFW04P8tHgebaD+Om20QALnUVEda0
+ MITe4fWITnel5NsdHDMPLEGZbkE= )
+d25.example.com. 86400 IN DNAME d26.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Wi0oXidrnrmUW8YRMi8lY2ldrW8fkO5OYjNh
+ UNefjH2hua7EesiT44ddHepmYCSTpXlOE6bq
+ JV5kjNZjnsmz3bp1mypx4AAqK8j1t5y0XTdQ
+ o/uMsCeqIGZdiDE/3GZXBfZUUDv90Qx7VzVA
+ n89hAFyTNOx75vuBBY5XqDgkoVY= )
+ 3600 NSEC test.non-terminal.d25.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ kyLYfp2vu7r/VJ4r1KUy9fM1naHRfzz4u7tK
+ A/FmiEahM0ta/W94Rgw5N1FjTetvLY+y0hGH
+ cqctmOofwY+2p9GN3PAnDNIp3LPr1YIGzHa3
+ k/KhbtSgUuIl0ZfcYEBfMSNg1IEEl0sywkQT
+ UuP5mKjLyvgKkuJQRjfpwElY+Mk= )
+test.non-terminal.d25.example.com. 86400 IN DNAME d26.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ zUyM847QI5r3pGcqbmGdtqnhSMsD2FwHdhKZ
+ ckRsy658jtUad1RLS3B6B+3XKzZDWZWi6SvZ
+ E0buEaY/FLkFT883K4W/fHq08Q6CChvzuTO7
+ DqX9HL+EkwHzzUUL5DlVVarvGQLP7ffwZ6nx
+ N6OSnIevJdG7z9gdiEOJfLo+JfU= )
+ 3600 NSEC d26.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ lUdwjulwBDjxnKePZOWPD/J0AUHL8e3phH7Y
+ XHiG/pIf3AyzvLNEGaZadW8ClAzzxh1nNF8K
+ IS9wKoAe9deOYFFgQuzyGtStawUu6t5QUfgA
+ ByIhZ6HCAyLIuDdmCDSSZ8O2gFlxPwAQA9tj
+ 7iToyq1Q069cfQgcxXg2RmMn5Oo= )
+d26.example.com. 86400 IN DNAME d27.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ CmrEWa2V9yzrdZc9JZBQT2+YZK0WUPpI9tpc
+ 78RPO3yODziMMO+2SiJCYJL3ZMaLKhmBwAWG
+ tAe9KUpRbJX+JG9hj8Mn3V4NqsiIkV7oBQSn
+ 4GqoP0SstezG16XO08QRjzjxPI67e5BePAnA
+ hozhSzzEJGnSbS6DkJYmhl6hX2k= )
+ 3600 NSEC test.non-terminal.d26.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ l/j9Rb6vuKOSEEhjh6iWUrEYoXgyEuQr/iYK
+ aVcYO2ngJj+NKvj+VYuUr7JN7YVbDsJS1i16
+ Dw1zKrOWFWqwcSNRU2nR3g8r/VLMIJWf+Akj
+ XMB44pAKSfzsbwVgvosLqFkzqWK1URrxL145
+ i55JBk1VkxcC4w2nhkVkgpvd4e4= )
+d22.example.com. 86400 IN DNAME d23.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ HdJSKEfomKEEZv+V/pu+rJuyzLCD4DjVK3Vc
+ ZPh1oF51SghRi7wDwma5saguexv9HJhmhIvh
+ 4lpHD69xvGvr92vwkOzsQcmqCAn0MdRQKsPi
+ QERsDU28Ln5AopdCN9HqceEoR5ydP0jNvhll
+ leaEs7KHl6GPOC5nX9RTCRyX9h0= )
+ 3600 NSEC test.non-terminal.d22.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ tEydzSTde8y5Q+grtET7M/H5Edc3URPonUdN
+ 83vhA4DlseCHIUfcn2KVlJHis1HSJj3ZOrDz
+ E0ulwuiIpAojuIDPuuvmdokqkX95gPdxcVEu
+ OJVsghY4ZNJv7gTY041+QRY2E12tp3RsrJRd
+ HLFMbS6g3OzK0f99mcahOPoshrU= )
+test.non-terminal.d22.example.com. 86400 IN DNAME d23.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ s2nQeFH7qxKNgI8p6/oNqHMrUvzqztAFEunW
+ N7TDFuhAxqGHHdXUXcQ5iLaG+nXlHqZjVhbZ
+ g5XFU1xyKzvr3QsiGxMcCbfMbimNFUBe96+O
+ wlEH6zH6LeS2TfU6RbXWv5cly7mKwAB2OZZ4
+ JqSGXh8+VST7cMdgQTEyOsCst58= )
+ 3600 NSEC d23.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ xD7AHNZABsho/o3YWgedJz5mGH2WkAqTPOKK
+ 0xuUB0q9q32Gfwe1irIzz+luKEJTUf6iZwtC
+ O/a7TqE9xxVvPwB1eHd8tTfqkPpsTn+EwPFC
+ gWjcn0cWzXJGf/YCHEN0A7g1LD2JbsuWKePm
+ 5Mbk0/VtV7yLGQDo4GnHseCelAY= )
+test.non-terminal.d27.example.com. 86400 IN DNAME d28.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ PjMS1OoEIDXiYsozP8j27urT+eg4UjN3ZY1p
+ RagCESTRBSAJMWwK+1DEvCnWUZejVR9C+nwf
+ DDBaStF0BlEi8SHWjcKz31G5Wp7feKvefcWX
+ t+iHl/dg2yOeNzQZqtpDNnz1fk00APItOe48
+ XHw5pAmPJj2TSj1ku+EfKlN9Yns= )
+ 3600 NSEC d28.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ ZySZ8MSmvWeJR+tRt0Z+UUArRdNH9srsPSe2
+ gzJrncABd5zHmclMxZzv3P7C6Wpyp+ZqAIHx
+ 8b9bsLaHSxojmcexKUu03KLgxRmUIGufD9e2
+ vz360CdkWSae+Stn7i6qquaHFxPqrrrdHLDz
+ N/El76yaHLCYEia96ZSSJp1lJXE= )
+d28.example.com. 86400 IN DNAME d29.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ MGLs+RhDBLpNZ6TzL8qCeQEoNUvbg5IU9vb4
+ aWE7yJC3jB5HsgMLxmGTB+MVEUfbzoEl0vu2
+ XFFfIogNOxg6MMwfTc53ca2q0Sm4Kvy8U/Wn
+ AP5BQBjr2mW38UFwSnrcWDN/NPuqt8iuw9Pc
+ xm99tv0BK6oninzVMlr4VEdUv64= )
+ 3600 NSEC test.non-terminal.d28.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ PHnJMjYlMKrKoIffBA/zqr4Je8IZn0UZvKoL
+ I/mO0Mv3wSItH9EhbH25DMz7VZAFykAUbBBE
+ nDUYGeKAp7iCHcToOiaLSAghasipw3W9ONK5
+ rtxnUVh7z0Ha8OgrzWbHJjb2qGJFJnT052KK
+ 8lcG5IIghBOZsWJzRmmtYLC3bls= )
+test.non-terminal.d28.example.com. 86400 IN DNAME d29.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ h1Hvv9sNDqbdmHnpfRMi7AhMmKL9/79/7g2L
+ /8uKxI+T5847tpV8xmAXONjTDFKvqY+cSESY
+ QuxxeZm0ONkPi8eZ0UsibkYBbVrzWoA3p2wO
+ NmUXCgozIPfWJ6+qb+S3T/Zllo2x3LtIDqjg
+ jR8wiuBHno5Y11dD/1RsyZxgFXI= )
+ 3600 NSEC d29.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ RsxrQxaCgsM08RuCavXBFAsvCXhSqM539ptz
+ c3Z25DX4YX1sdKb2klsu3S8u2V8dqm/lWeOL
+ YNvtrt1h0QwZV1AbbGL8MD4bRx/FKwc6DDbT
+ Hu8HwIz1Rif/hj6ah0ZBPe4NX+xF975iUCk3
+ 3algCJt6TJbOeTGpm3Qhs9iVXi0= )
+d29.example.com. 86400 IN DNAME d30.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ qbj0MsF0osT4ljhUHI4vcCLXH/mRyY+tzhF2
+ GD70++n053GA4XRhFIVmTkPDf6jMi5KeBng2
+ PCjDKqZ075sagw1KgJ863vFgvVtDFqpcZyMv
+ p/8YoAGGZ6tfzesdyQNsqvvv0IsFlyKMbmf8
+ VwEMu5w46lN6d8cdkgcpdu1qIeU= )
+ 3600 NSEC test.non-terminal.d29.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ g8NPe9d272SXcBLtLSa12a4MwPWaLCJo0L7C
+ 0oHI48Mf5hFYgd6c5eAus63H2xadWVVIO6Kp
+ dtRMVh+7Iru7Ttr7p8MQd7a/1kHKJUypQGnK
+ nc7kO1EZw1zSlr67xlky67BnVGtPpdTEv3xX
+ 7GlKQYikDhkS4y50TXMdgu3Xubw= )
+test.non-terminal.d29.example.com. 86400 IN DNAME d30.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ YMZYBk0UsQKvcUKCNoHB0Vr01SlJUNJKFeWw
+ 1m8ODQvM7iBD/98P/0blFJhRpU+8L3luMOQH
+ jw2WusX6tiQ01GigPId1Hx3fffRPMgFinUSU
+ Zqdbblxkcq0G/LS+cMw0U+P0FrYY0RLbG0g3
+ t3BFNIvc4zp93PLpNkoANvjkPuE= )
+ 3600 NSEC d3.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ SMPFxTYXw5SCCpGZN6iX/LXGchmLhYpkVF0W
+ eMTpE1b8qXNSEYOX/GcoPTKpq8vC1b5uDsTC
+ csQQvfw109jVQTQKDvj9FcTdBROCqu3+fMoA
+ NqOpQ9myqWlJRqh/j4/Ma5LXAPyjHl7bn/LR
+ /qm5cEOUuFmKN9SxCnt4P3wX6b0= )
+d3.example.com. 86400 IN DNAME d2.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ vLfN0um7RTzBYKsBXcKhjE16JHQbT4KWYMdG
+ 8OY80qoDPyJhOwh/IVwyphVx1mJYKGo/xSme
+ 1H5krPXDQAe1nHOzm+ccv/zxDtOe7bSZdKqG
+ /vwTx+HmFOSI/fhW9vDR5lzlvY9heK2NCYfc
+ ZJKpI6cu/kF2ERZLycBHfWBszXs= )
+ 3600 NSEC test.non-terminal.d3.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ H0nHHxU8yoDmQKxIvRTBQERmc7TlWmKT08HZ
+ 4Q0annmyAYwEmcMS+825ldWmv6kb7q/zdsA8
+ +h7In0slgBDh4m7MSQpl/1h6zkTWugBRZUso
+ GIn3XfX6GKtPfQAWLOdPjH7yoTmV4vHCgJZe
+ StXXGYpy5MCfBIC4pymdRouuydY= )
+test.non-terminal.d3.example.com. 86400 IN DNAME d2.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ PbkvKAx1BU8RKRQhD1KWxhuOYE6VMbvfh16S
+ uCeBr0Wlp0ldtnaq2UXxormGLVBNVVWpet5m
+ OaRY3FviXV09+55vBimJHkpsrD/q5y39JqF3
+ WUd9SufzwaH5lGR6FnQqpZytrHDFRHJdymwy
+ /xbmVB+iiMCpy17yAIy/iOj53l0= )
+ 3600 NSEC d30.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ b0IxpO3mLEovw/45lknt9Du/YmsCr0+tBGuF
+ TcXB+6GII00Az+Gwkg5/NWMJuDphGCvsxdJ3
+ 52dbP3pBaZSsfZrLjPHoUwF/8jziuAvsxE1L
+ CVFwtKuKh3aKP5WBav/pJ/w/KRryXqvXtGR9
+ Yvx2zQ8bpmX5EC03/Bv/t4rFoAY= )
+test.non-terminal.d26.example.com. 86400 IN DNAME d27.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ oQFooT2ajjBwlLFYJyT4M4dEYfcQZ+1YZdBK
+ YU4fDY5O3XaLW16ysOy4QSk35LJ+NudKb/Gn
+ 5+EFyOuqQ0FO0nSWb5XDFUv8bHcqkcxLixZH
+ Otz/gTKBBOG8ox+FKG93/oQLabaaDXnvagFR
+ 9p7zJagqCBGkV+51yyOf2UCOKeA= )
+ 3600 NSEC d27.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ XDEw3+UJZOdBknx0nXnPSCbdJ0g/oyLvV944
+ zmc2D53GYPUCw8CbY2ue8xs9SiIRMmlJVWv0
+ 4iaeRzDE1OEK8lgRYmPQ8A+I3PrAOZacEdLI
+ cZQTFTwIL2wG6ifI/gSXsuhbsg+NT1gPVIJd
+ 1Efc9qWvujkQ7Y3uOfO0Qakbv9o= )
+d27.example.com. 86400 IN DNAME d28.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ G4dzVFvM+hAc7F/m11AnrNjcRp/7gOa/MV1S
+ EXdf+geKzDOlNMSuDQYHebZ1yjyO1zSFc/TS
+ jA6InaXNXRf1IiLXll0Sc7bXqQZAlUDshpp1
+ tQU4az4Z0mzdRdOsLFysd/9j83lL755+g6TY
+ nVn/3KHbX6gRaPcyEOFqe6gR3ts= )
+ 3600 NSEC test.non-terminal.d27.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ ariwMYWZb8te6M9WnpRi8mLaNGPmiRfy3sY/
+ eEwwohC4eSueB5/OAO2Fa5EzNpCY8OiYc22e
+ sNou+IYICFTDn6smP35QV1Ltbwsk+M2VE2yz
+ RKWuXPz45qykVFudloHild3qcNz2RI+3Suak
+ rZ+OxgaqtD16nXZnxjsDY8bUB/c= )
+d31.example.com. 86400 IN DNAME d32.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Ibfxt0RX9+Euc0P9EWzoazqm2pNZYCdL2cwg
+ GnH6Y/oVk/KhjQi5UziXTQob5ihX82vLgRaP
+ 8MeUaPdACmy7CsuDandsRSVgc+ZkwOaaiFOo
+ 4xguJqmWgqD2FBSeI5qgtrlL/wjW6V+CsF0C
+ hvWmGhYMkaOOKRPE3xuqoOO5ye4= )
+ 3600 NSEC test.non-terminal.d31.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ RmoQsqaU9WHhcfkWUbJa0+yZQFE6OwWUi2oG
+ meLhay1FZ6YubZDR1/o343M0UzenV94+Drmo
+ GjDARWjHrN/fFHbrhf0paTwDxd2hCHKfRK1o
+ mGVGJzmmGYlTju9FzUsDhFVY07Ea5k2L9+VR
+ ZUklKZ1gmEVT4t5/uSrS8pT69LI= )
+test.non-terminal.d31.example.com. 86400 IN DNAME d32.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ HY+yqh3Ssj66gyTGxAHPW7IoZvYNeu7pauFn
+ 0WgRSwcd6y2CzyDrqCPRBoY6uZIQxbqw6DOa
+ T7QpAGzk+gaeBfZELmpvfyLTsbdd0+KzTaer
+ oNlveT9pIoUYyvF36jOtkq28Qh8YwCCC2GtY
+ 5sxQYDX9njTriEljlVtzeQdRnbA= )
+ 3600 NSEC d32.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ u8NHxb8uh5qwmJq3JoYOF0056NNalcvUN6eQ
+ ZsAt+84JPgUkjR+IA2BODjgZYF696VdS7FCU
+ n6jU+5UO0ouMjWBArILglX0AttVC3SmmKyfs
+ UIBmBK5caCEtEayaxJs9cKJC9Dp6bpivzvbn
+ iMHE/Dw1GLkl6AV8g8aDYs6WUo8= )
+d32.example.com. 86400 IN DNAME d33.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ AS5nd7zJuGcT/P9QDrE+JwPMLCWhK/scvd0K
+ JbgZvmbf7dJyDXjNwOx9I8X0JFH3udhL+6J0
+ jT8vaZYTkgCeMIJc4dC5W1rouAHlvKyQgM0S
+ IeY4bmc4UzUYbmgWoTlPzO4GsK2j5owkJFlt
+ UbGmbpoYuY2uFuoM+oqk/lkO4XI= )
+ 3600 NSEC test.non-terminal.d32.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ 0EsOsK7NuVQjp5RGvix7beXoTYLvBVDfyFlC
+ xuaMDE2kcdi0UcW+fiq8/WzToZKd8n5qsSkh
+ XvewdNoRsfaVykgj8+DjpfZ8etohf3auQVwT
+ p/qyBZ+dZApLhoqqcxhKbgfdyq6FmQCwX+xN
+ csb28Hsqz8U1xZcEf8dx9N1FdoA= )
+test.non-terminal.d32.example.com. 86400 IN DNAME d33.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ H33EqQS6p4UdDRfCP+bVqKAAOTSKR7ZAbwJM
+ kebVHincfNSPp7yl4HrOQd8i+ywEAVjoFtqq
+ X7KdvUSv1Reskw5kt2Yx5msbJMGJdIljg3F/
+ gm8afdHNLVo3ilf1r04JCJgEq4jpck0NDFv6
+ KW3sJ+B2q8SsAgZ/NsqKVkByn8Q= )
+ 3600 NSEC d33.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ QSmQHU9L3+67wx5YgwUNt9C55W+sfJKojkBi
+ BFkRTqUDb5+nm9aF8Y7Fc0evCBzRr0lvAjNi
+ m9z4MjQse27KWqpk+7cIDZGSPaRevbNO3Q8r
+ 15d0HXxuqdzWz68byabI2NuNbCVBFVCU7urM
+ v7y9OghP6sdY1Eju1OestuZ9VRU= )
+d33.example.com. 86400 IN DNAME d34.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ rOYGG79dKzxEZ5Ywazxq8942tWOeI/RMGrRS
+ Xe0fb1svHYV2UTX9ohX6LclTonzPQwVlOi+N
+ 0VjBECDZsH9GXlIw43yifybcSDV/VM9fahku
+ tStuDkhNy3RpjQ5PSWr+aXbuHM/AqNuCJXh4
+ K4F+AhnPBDE7Xucd2oT4gYEpUzA= )
+ 3600 NSEC test.non-terminal.d33.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ TzGtSlbvxKvpEQWVpOR7TmxqnGZVwvqXGgw7
+ bYT1EgPqtVVh5la+0MvszHKf5xOq2+S5UZjA
+ bgMh1gQ9rKw4IFelQ9OPBZvCwd0zWOj6T1+y
+ cdRtvRK3ZvBM5eJ1CAhNyuSVkvHOk6+wGasK
+ mG6KM8GMqNN2XhYt6Dfvt9klNKA= )
+test.non-terminal.d33.example.com. 86400 IN DNAME d34.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ zveTqBCx5lN9/4aqk2f/MYW56/fmhL+Il3Ll
+ 8Tx6RYnhn6qQZoeqy85dyLvWI69uwPOlKVS4
+ MxiALMn+c3rYyPw2zpW1jMKawMAQnt5OAcE6
+ UtpQcpmYuizbEvSKU8o1jPjFU+Kn4iCaz8Q3
+ EETXBpEGDSVDkiYHxWsJVTSevEM= )
+ 3600 NSEC d34.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ OtKiiybJm9EwaRKR5yZ+EL644M7Sd/ImxFL4
+ rUsoFenyBIoMOiLpnXuBsGihBLIyvg/ELMZQ
+ Y2lSZBSIYuP+w75nPZw88R1spi01+gx7QrPg
+ xiPM8Y6OEEVzHzv3PiLwkwbyGSu3Di1yv+jm
+ NKW4X6tnslpjFozJ3bhXT68vanQ= )
+d34.example.com. 86400 IN DNAME d35.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Hl6mLcNObM99IzWPf9uBCBJbDqF4qMeMzIIn
+ MtTqk8+Z6jVKoJ/bJm+VXX0Dy4OBuwfrB3z2
+ MOaIUl/1RIkDClFpFPYVWSbuUkELw0T8UqTS
+ TDReleobOtDuV5ckzQENxzng3BXUzQFI7yQq
+ H72kUTUhG3HP5EmuaIObw/DeEak= )
+ 3600 NSEC test.non-terminal.d34.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ iJEzg06kV32IjiWQU1Dz6fnEyt3hMviPuRiY
+ WKvrwZex8JNN1zO8MNcdvOQQPnZwmrgarVRG
+ ncl+U4A1jO5/5uCsEBXMzwtVqtbHjXuKUPsp
+ L/7pqHUeg3pRR1aRropTb7klYmHL5AHxGu+2
+ S26IrGdvxM8R+03D4ks2I5YDHVk= )
+d30.example.com. 86400 IN DNAME d31.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ iz66peI7dI1+8Bo4F0HEtmQ911g8wD1ILT7T
+ 2BwdixlyrEy3pCOYMs5qyhjUTX4GMCOT597A
+ osCt3souLPsDCShBSYIaf1WbTUGM9zEeoG4x
+ dDTgpzA0kmKcY+mJzQKriIJ9t+J3Zogjh3R2
+ 5RtDTefYyk5FR1drppbln7bnWhI= )
+ 3600 NSEC test.non-terminal.d30.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ CUzjs/O6TQRAivsAxd3zoc052NeN9k0NlpFR
+ KLWzOFl3yQaX2b3zFpXJhcC8WgIg4I2cMaED
+ sOs/98jqIOTv538WGRablidhEZAjkguo3YnU
+ Yi8foZ079frfWbeL5stzUn+bXiAFX6SIaF4O
+ 6D7qcScSFFrImBr5lUU5C7mdVwc= )
+test.non-terminal.d30.example.com. 86400 IN DNAME d31.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ miSX5BLAnSn80bdr+wNmdSM7iJ0yiBnvNFWu
+ aNKgv3nT4Ae3HSpEmNQObKOpRlA7Dfkw1XKB
+ qlJZOEjSE4UNTBG/8Le1G0u+qUuHeqHHAxUC
+ S7KoR1tAcwSkyk9vSSai8t9zcGzmZ5x+wpGx
+ xk1htlq/xigbGHAXoOk4axF96QQ= )
+ 3600 NSEC d31.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ UBDdtVUEkXxnz4jmt3NRE3uodD5UxczcOV69
+ buELznNVoO6IShDY+s2sWpGzIpQVdN32CMoe
+ uAzWI1PqQgu2xGMPLCynsiPrYVDkY2QK6FCX
+ GCSAncLinwYgF4mJ8rnwnx4O1bZtOxBPA6e4
+ 3YRDR9IxlOrWojTn3+0eg+tuiL4= )
+test.non-terminal.d35.example.com. 86400 IN DNAME d36.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ mUffclGpyz7Hf7LJVgwMBm8xIp/2YQ1HIHU6
+ 5in/8qj4Lt/KbiMkKUoylsEOk1EZCORgbdUr
+ c+sD7OL1IbtNRHi5zezIY/J0/Opj9rNvqDx5
+ LdqQLUZATVknm8w7P0zKAKR53dJsfBorodV/
+ 3ojk4cOJ7KQOmOpz4VZ51aX4P0s= )
+ 3600 NSEC d36.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ j/oECHOEQmCSuYZY+7ihr6kXkAU5HGBVRe2E
+ 1cvSu48vm4u0kpez5lNcgIYidXUGkkLgbzRZ
+ g8qerNrUolUGW5Ou6eH9vRyOKxFx7CN+r0VK
+ s4SmaA7Z9QKoDhMhTL+6L5MD3SuPmTfHeMSb
+ YyYEwfVZ/BQbUivC3f73uImgqa4= )
+d36.example.com. 86400 IN DNAME d37.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ EEdpNIRLMORdKGKHVrueW2QjjdTi9L832k2O
+ ZP3mH8b3VFKNehdpo35k6Jc1zHFB2/0TiNkX
+ OqjkgiBi/spmXHDop3T9o08R9egVmBkfxpHz
+ Hos7tfjjPlPExmYnLJto6XDJHEg3dhVQk8bc
+ 1hkPCXCoQUo8yF6T2KEix9H6GAs= )
+ 3600 NSEC test.non-terminal.d36.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Mksb5Hs5S3teHznWOMMqESYJhjr5FHikFxkn
+ uDgzRNbHUa1AQeMn9LBsO2hGA0xsZQ+urmJk
+ x6GaGTlQfL6jfqe9CeEybqnCAWWqBw9GtW/d
+ LsO2pqYPwmHe8tChw2FukH1F/zzn5dX4NJvS
+ hzkeZgM7IDJ57mcoOoTvbtK0FqA= )
+test.non-terminal.d36.example.com. 86400 IN DNAME d37.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ DXzD95y216T2+S/ZqH95hGzcN2yohQ/JEgCz
+ 4shcLhfyhBCF8UMQzuAyE7EK46nglb/9p9rB
+ r4bEYGOTbzj+Fucct6TLkToLPtFmYw35Bl+d
+ 6XAGhllLeEJI6tLHD7IEGkM6vpwqiJFZyXsg
+ E21gaNSNX6pxp9RCQyArBAxgg7I= )
+ 3600 NSEC d37.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ EEpCIFxHTpKCYFf+dKgCzqlj453laGc/PTA5
+ 6+jqWd6iGPTBGBOpyHm5QhgDfVVlpsu0G6xW
+ aBLRyN7zhW1gsCm5pGnymBSdrQkifHE4RnzS
+ DridL6bOrSGteU2Xgu2AnH9GLTttfs+CixcM
+ rh46Efjw1Iq9N4NYi+mzgitZnaY= )
+d37.example.com. 86400 IN DNAME d38.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ wNK3wDPNSo4TIM5spFthBdQRvL5ksyo4pbgb
+ rChnKVgaN7WlGUKUbh7ILq6L8Gx3Dgx+Gysn
+ 1IntGBz+5LJRwbFJ/mkBB+u/BpotekSNb/nS
+ f1AloGCtSTjRTp1aPE2P73+Lzqh8QQwx8SKF
+ zKLtZ/s3sxGqwA7q7qxbUJDVito= )
+ 3600 NSEC test.non-terminal.d37.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ AvLP/8seBWJHTYbBh9UahXM4N5vzeyDpKVKn
+ Y1lBfkMmiLb2db1P+Tvkvzo6YxRuETkZFUgA
+ QOFRAyYhqNgII4TlnMkg26VcyojGLZO+k8ky
+ WAnK3Py0jSOZlri9J4FgjqU9xn0Wuru9XZSD
+ kpn3fzUAKhU2KuUcKuXIWQUvGuA= )
+test.non-terminal.d37.example.com. 86400 IN DNAME d38.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ mzyChHLbPJW9yGrX73k7fLCDdavZBDJOtTxD
+ xixFNsfDLTX1LZTP4QtQw4sp+gGEOGQZbZrD
+ 9VLGnKTPSl9PmSKHEDpNsHt1LgJQqyPu8wF8
+ jl8muCjcw8wB4idoVRqoQ1tuQNdKazHmGE1/
+ zMNrEzQbDafDWucznGK9o4ngDqc= )
+ 3600 NSEC d38.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ oNwmaTIxrKdUB3LTHPeKtBHOPA0CAaNRYuxL
+ e8XY1Ex7SyARjaYD323Ch9nFIXezWXmQ3Y6X
+ xbAhLLJ4s3+osk50TGOpSUsmuCJ7oDYdKlwY
+ QDkigNBMUvHf8m2fnFJtfIjWTYZbAFktKABj
+ RIVqNpPAEQG1EcXHXbcy6MoWCvU= )
+d38.example.com. 86400 IN DNAME d39.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ hGzgFbxjCnZCM0FfXpyncpMaYDIul1IIHqzf
+ rd/c4vtU4mrJ53Ix5KI/0xTpu68CjJB1mIg0
+ J+1qbhuFYlDO8nftcuafCFXZMaTGoCtyL3Jc
+ pnzsD9mkhHrhhkMh7770ZXi+MECucoHx/siB
+ 9h1qsqll4wma+zcU99sfEsckRGU= )
+ 3600 NSEC test.non-terminal.d38.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ gss886rBEatmhX/pYGp2ycafXr09n51+q6L5
+ YWYrAD9IR29qUXsT9LOnh3gkmIawSiG/u/7g
+ ufRi1LRNyWuDRfLrBBmTmQfkyKTfPKUYWQwu
+ 40Wy9cZ7juNnW8lB6CZ/OWIFI5dS/+QDd0Fs
+ 0gD5G3EJsCPI/6hJWg+25cSMS9I= )
+test.non-terminal.d38.example.com. 86400 IN DNAME d39.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ vLHrl7gZRn11fvjVGVJp3sEtJyPWjE3usU1f
+ ozehBRzA0xuigXcRyuJ9OQHgA6Tmjxs6dsTG
+ ZOlT6kCWeVsFsa24Iiuy6G7ei+wPeYqbyZUS
+ x9lpAJTDjmi6T8eeHGNazC3mNSjtbU6XdEui
+ i21Ob89nF2XsKBA3fDv48w26whc= )
+ 3600 NSEC d39.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ T5iOV3jE0Gm5wcijUk5Mow6Lrzps6FvxQ9lI
+ N9675nomxuo/BD5Y/p8MkHKaQUhJ0cSQhNgF
+ 8dsaDzc0M2zJAHJlT99WHGhScJakBTo72x94
+ LONS4EQCnKoE/wYdfPClvWutp5spV+7WPb6D
+ +n6CFEjx1hPNdPsRdgnhb02OBjM= )
+d39.example.com. 86400 IN DNAME d40.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ NDIEHtFYWSI5P+8qBQj3ZLvWOOXwCNOtLDwh
+ 76QtFxqu7S+kHY7b+w9RZi+WR7cNCimBD/pM
+ 341M3ymgfKx6Za9CzbvCR/fHwEfdm0OTJfw+
+ UUdMdXk2gHOw9SrP8T237XUuWIz5QV/ZekMr
+ LgtGGmZ419qpiBVcUgj6o9P3Nbc= )
+ 3600 NSEC test.non-terminal.d39.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ SB7LxD9BBhASAyMoFI0BfVUIQbV669zfGa9P
+ E/VM3el3yuBYDUPpKQaw+ovjujeDGvIbbz9N
+ JiVG3g5eXiQMHony7Laasb1Y1VkrnomH6G0S
+ Kx/wPJ/gSkJq94uVM8vMwTEBYsUzTTFiwc0U
+ r+9qAndCue2ggO8VoFjY6OQRnZI= )
+test.non-terminal.d34.example.com. 86400 IN DNAME d35.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ vPUvcC15rTnoBEejvJe/7n8aivkRzA0PL078
+ QfkS3CNxrVk62Ba6MI1NY9+kQBOed0aY4bhA
+ t7ZEFwaiZtVA5owcRCWymiDZ65gX2gcmNppL
+ 40DBp2B5xEGFDM+337w21Gakj+f9US/AWllk
+ BY8xlgOTxLHTRkHds2PEeooUz4E= )
+ 3600 NSEC d35.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ hk8Napz3hJKVPlbN/5vNiE/1U6BnOGKdxj1e
+ yx4U509Ik4oc2XL3BeXPO40xPEAJKL0WMtUa
+ xOO7SwTNgLy/B2/1KZwqk0QTzteyr0XtMX9i
+ K7bPvVH3M4gZ64zDXE0OKngHs6Aewg0H+DH0
+ ofslIkrEmzGor8L4jJcO8W11YIs= )
+d35.example.com. 86400 IN DNAME d36.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Ep2CPSeWtSOdFuFenSMD1iShq9SzYF784nVJ
+ rOMpUHXeJ8qUV76Sb8OFinmh/nEZAP9KZIxX
+ krkV141Pvph2EuASLuv6+Y7DV846dztz4spW
+ xXLLbX7Eg9QjzHPPAosExomSGa7+y14PpaDc
+ JfFJu50nx7OQTkr4HuGCW7EMNp0= )
+ 3600 NSEC test.non-terminal.d35.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ fm5PRS8J58nYSs/52NPOREfn0+cQNcy4RLGB
+ us/hXZ5ahbRWlpaK1NgeDbYqCfriFpCSWJCl
+ oLMVKJE7NiawaspAe5VyiFY19vK7gpyIRjox
+ C5U/4GqVmQ9gSPykfsH9J/XFYfOjryvGFgZ9
+ p7lLopuYxhpvZVTCYBjlIgSCAD4= )
+test.non-terminal.d4.example.com. 86400 IN DNAME d5.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ W8QnYa1Uyb1jOYWIOB73ad+E8xj0UaadmzYH
+ eSCKl0YZ26L9d4VXjzFOrLIQMcxBk1pwY+Ll
+ iTrnQfoQC+MO42ZRNBWaJefh92VnBgZYnL/o
+ 6N782Jo6RTCTuzhODfZGMrvZdGOaagqk8BiP
+ YPob0BCP/4A8woduHq4LBIm572E= )
+ 3600 NSEC www.d40.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ oDZcLuL4ICNIwh1eswzWap3ZQMRcbgnc6Ofr
+ Db2N/qMtQ5LNQJxRgdiFA64WBEOq3AibOMV3
+ L1MlIDHZPOjnHOnm92V3deEQH2a+d3xntH71
+ z3XzvLE1Qn0T1ehvmiPz5WVxUbfD82mKNE2u
+ bqIhES7ghFGPsZwMisWbYnnbSaM= )
+www.d40.example.com. 86400 IN CNAME www.d41.example.com.
+ 86400 RRSIG CNAME 5 4 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ o56J8UlTilwtXGyMxQzx7RG7ZI9qQaEvjkj5
+ afY/GDbhDnjCWt38VEmxiOYT32qf4X+7rBsz
+ spZJkWYhJOkgBD0zuqWcIv3dRmCJyK9sqvaK
+ VD4PKpsx0n1E7n3Wt+SIaoxyB75WYcLXrIcb
+ Pe82mi//bc2UNDb7KO5P3MtxxXU= )
+ 3600 NSEC test.non-terminal.www.d40.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 4 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ q6XtW5CF5STV+ssIwjCzO3+WGF9wk+RGKhSJ
+ 8Swr0N3FIG8eVM1DFCLtntBTsWLVUa8GxtIg
+ TqNCo/QN/akRk5XAWdEPOaH8VH3j9TIiphJA
+ MEtmiBAau4FsNxwhMyzNoRU6K4eXrmthi5Qp
+ T00cwCDBU+L0+TgHG74aQWsXaro= )
+test.non-terminal.www.d40.example.com. 86400 IN CNAME www.d41.example.com.
+ 86400 RRSIG CNAME 5 6 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ xs27GJvBFwz6E8giGiO4mfvvG5YfJRGB/hco
+ dGvJSExS09qpZRj/Pv79utnj/e/SZT7KVByT
+ smzRNRp2zCmXhzdd5ymOBKSzz2J0yjCAxyJE
+ ezXZ5BOeyMD39s3wHNRla/At8xWntVtZ7sTV
+ C0ZcVhBwjTBdEqzEqo4ZWVvjHCQ= )
+ 3600 NSEC d41.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 6 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Y+ShsKZVeXkOQeu2aSlFw3sRb2hZTf7D2Kh1
+ synhkjSbfGud0RM87gtlLisHx6GRp/kM20G/
+ LXim42S5qRA6PZXez6SEVPHKsCHW2IjxkO0h
+ QScT7R44dre9oY88hX+QcMFsZ3c3qphJJPOo
+ VpawlU14Y9x5K2eFhmZRqwXpltA= )
+d41.example.com. 86400 IN DNAME d42.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ HALKMA0yTqwQOizKYXQ7jTFiq582MkO6yvI5
+ TKZLd9MzuIjuFLw/EKSPcvhKCIreS9Gqeqxf
+ icDqiTd+mqVfI9OVYFivI4KR4+cXxTDTlOhT
+ SxHfUFT+KWHFKP/yEQzlYkburU8Ku+S+HMu+
+ FjupYSTIwyJTOaEYcVKDQGJzTtc= )
+ 3600 NSEC test.non-terminal.d41.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ AHx4C0Bie3OyC1B7vaAGl4iMfv0I4y6cCLng
+ 7N+BLafBgondhrJvwwZiIugG2A10ogeilLm5
+ JfVb/LfVk/m/6hOM3o+HYj0G4HnrjLj221Cr
+ jNnp8Efs6Ey0Za/6NfMtdMIfBnpuQo0b7976
+ tH6KMUhHgJ0OjtLxKJ55p06Z/wM= )
+test.non-terminal.d41.example.com. 86400 IN DNAME d42.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ bLG7GY0x1i7OGxX1wvPG6PwgZnvm90kaKnnA
+ KE+HgbcwEnZMD7fmWNFG/+ASyh83waBVz+RX
+ D16XHdncxufxn0/P0Vm2x9JjWq8PTfSgmMK4
+ mh3up4ojOCzO/BVmBuLgjodF5CzELWALIPC/
+ gw7eW0INNu1AEQuR5+puB7+dlAM= )
+ 3600 NSEC d42.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ ky6mcrxja84cjouSZ2ptv5/6GhnUSS4iDBqh
+ 8xuSovtOMAi80i/0e9xaXLpQaZtw1tz/uATT
+ nJVGJdtz9efTahahKDUgRK4PoPh4fcJHhXi9
+ bvS5oh2RnfVJpGCWIQW6jIo5LWvi4cZRKPt0
+ V2X4pEkOSAMKmHjUr0kg0+srGxQ= )
+d42.example.com. 86400 IN DNAME d43.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ v9BTtT4w23lhSGF3/sdWPT4nGIE1Gk4uCXRo
+ fgNTQvgGDZXzkR/HsWBvLBlOr75yKxJLYAKX
+ yVoMGIECluCTiMD5raK/YwRrBzMqDIie9a/v
+ rGljVXiLz7+evSAhVS2Dsh/Op8P489F00h5a
+ t6c0F6bLEwNTBuHwrlcPQx/r6GE= )
+ 3600 NSEC test.non-terminal.d42.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ GEy2Wj8dgY4Pi4K9ZrAcvVNq6t/g+RWJ2Vi7
+ 5gUNkwuZl3XaIC8PNgSgAX1jbT2BD+R7IzTp
+ UDCsTyLJ7j8TnV5vIQIS4cPhQmLSYPKrrWtF
+ TbmSkewgiwMcSjBBn71KXvglYeq8EK9o6X1o
+ VrMIF0kHnZljfhzpLNO5PaURhaE= )
+test.non-terminal.d42.example.com. 86400 IN DNAME d43.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ MRSJ050jY2e0PLYWyaqz4dO8Q/iwP6ba8pMI
+ bAhM8Uk1JNOrUTcDVU1wLsO/kpImRJ6Xzs/v
+ zmiFM5DocAN682b3U1tT4AHOLcerYTEGlpkW
+ SLjp1pAF385dXIAnCv+rtXCMfyPC+YgpxMzB
+ SXTisFNd8F5e3u6aUqPedbwQmyY= )
+ 3600 NSEC d43.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ rmP0fij7DUJPiaMF6ZkItdAGUNa1FtVp4vyk
+ MpRXS+MttP7RZXZ45lGMEs+ymukukQOB7mV/
+ ZEja7C2Z+fo/QGHwskxI8aASMRySE6vjfYvV
+ YdSoXVEWBXMkemw71UOn0Oys8xl2iVEnqovq
+ ml7/XVe9Bs71nDzIHnucqU1/57U= )
+d43.example.com. 86400 IN DNAME d44.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ CD2maM1SqIdNxtcGjc9kToOkRq72ixZQcjJC
+ Ru/+Q8eo13KM6Lm6+kDFQ8HysPxht3eqrA2J
+ G/JW/Xn5g1y4DBlGcae29NQ8D4iH+noSarbm
+ N9ISn08BaNLPv5OeehUKaOg7Nr84iJiZRQ+I
+ wk94NH9WdZ4/Nruj0iyebJlPr6w= )
+ 3600 NSEC test.non-terminal.d43.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ iXuTUyGAg/HMX1oxcTKlABI7bzNg3/t/LMHE
+ z3eK9K9f2CgOIijVVrvtLxARAzTMT/XGK/Pn
+ dluny/mOBft371a/PdTybtLOkcE7/WpQrMmY
+ GhR1a8soX4LPNV5G0+jfI45P1067+5578Jgf
+ jXG5hxRCzs2jB0bd3fhCTR0peK4= )
+test.non-terminal.d39.example.com. 86400 IN DNAME d40.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ LipatlHHUbS8rIX8ebq9YxSTmjzkMcMuy8VQ
+ uzCsZJqJAMJErVmu5Dg/ru705ZDyuzpd4tq1
+ UaES2xEhyK1eLrPv2uCNNlRFjikCQVBHrpI9
+ cgMuycS9F0nDwVTchmonKkj+kPoQ34CbDFnq
+ 6DDUjm/2SPm5bF+qjCkV5IbO800= )
+ 3600 NSEC d4.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ bzj705cPqlP13E8HzF9sXJAfFS4lFL4D0+Nh
+ DRHFt0BrTHYD6bIqtJmHs0CmMOr2FprPKdX2
+ bY7p/Cv8qiVQnItaunfHXh67Fx4GTzYg+ejC
+ CY/wx3tFtKmTI0ia/cNYAZ3NT0NHWziPYGxQ
+ 4i3geIjS6z61D8o3iCp7N3qKSQk= )
+d4.example.com. 86400 IN DNAME d5.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ LZHOm4LZy2va6O3JRX/BtA8JQWk4G4qta1kF
+ SgY4dXycWGor7o9GYL+GKN7NCFvdLn1cpQ1X
+ RlAerWa6biCX8cwpBssCRqrwupQRoekv1hbw
+ LC3j/knlyqO0BkvQN2PExdQRJ5QS2V4maAGU
+ kDIPFy79GAJQ93QlDT/zifUxbvQ= )
+ 3600 NSEC test.non-terminal.d4.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ s1b5b/MYKL4vxdg5RUvf5/jWottjvPclybpS
+ zpin/ipti7UZuh8d1NNyQZ8J9jlcVxtsrBZh
+ LxUWNdOmEXVbYIdMy9OT7Ifve/HCHGZUIR/b
+ xLT5edj5gWbo1FBWsOQP5o8iMGcvxYXxEytB
+ DG9xU+8hxwY3rFi9E/fnTCTpCXM= )
+test.non-terminal.d44.example.com. 86400 IN DNAME d45.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ cNiTpXMKvquXDgxXLi5jat7z7ZBCipMRx5Wg
+ BOv30kuPnhi5410N8oe9yafxdp9ad5SJaaUs
+ 3Sja0LNr3DdP5OnZJwjRieNLSrOnnfW9IlVn
+ AEXV534mK0uWd8tVKkPfqGhYm5E9+VEMBJmS
+ P+mxUV9qN4Nfi5uKxsvsGP/X2QI= )
+ 3600 NSEC d45.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Z6B+6qoJby9830kXX0Ipb2YG0x/DPh5cT4iW
+ SkrW5HfQblP3EyC9jz+hfbb6ykU1hG2Uwebe
+ Rnh8s5KgQy1/QxjGMEQ/6X02whf2Av+U5LCy
+ 7M+zSKkh7hZOdOznIjz1mku+BI/rX9yC01Ub
+ PMZNNWxR8BOrASwp+6N9tnZHRYQ= )
+d45.example.com. 86400 IN DNAME d46.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ jHb09ju0HWTRdI9jAAiL7UOlQYO0svjOysGy
+ P8qHc/XStyVhstIi2tSMUUPZpeFlgJ61iiC9
+ c90OQNMveAgtSkbKaQ1r4cMaY7gVeHJuPIw7
+ mVxpF+n2B7xAWvvANt59rW5BTN/bV6UatVko
+ mdPFYuDvTlWhf6IvcYDqfsUSfPk= )
+ 3600 NSEC test.non-terminal.d45.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ ihkftxAsQSjHaDWKofsXfZ1vZl/oPixqUTTx
+ KJST/31O/47trPvgx6G2LSOpEgsy2JbEmC34
+ yy8hfQef4JylZ2b6mcyov/AhNC6PI8WGvAMI
+ 9z/GI+4x1uXu+Rgs7cjoAdaUnFOocvUj5W9X
+ i9VwC3mHSNmy6ClEZP9/79Z/eXU= )
+test.non-terminal.d45.example.com. 86400 IN DNAME d46.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ xUxK0dYE031R1BCgI6228gsDBNPstInJX8NW
+ MaAtbTGAvvf+D0XMFIWu4r5NVp3BvEnHeLzN
+ fGzFFqcQiQRBe+GF7mVVjqARRe1gWM0ROcqK
+ GGZFa/05+Bes1sSXnxbMYm4qX5KjaedbQL6z
+ CtAM7U3ToR8g4bue3G+VHPvlSgo= )
+ 3600 NSEC d46.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ SjJK8JkHuqV/a9lehj6bgogqLcBu50PqW3+X
+ 2F0TvvJOsEo9pWPMuyqaAiqHQpXUPsBm6fAZ
+ EMQWBN7T+tmImuaRgF7IXraUyGAst6TmO+L+
+ Vb+KwlYI+FujaQ/oFAk6yp6HnVYKMqV4ShOq
+ 2r/UB8WuN82ul5rNNz/h/pCUD2c= )
+d46.example.com. 86400 IN DNAME d47.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ XoBrzFfsxIpgxA1nOaNxYIOySa3spCUJ5H17
+ 1utUO0op9BgzdYEvehRIkBJjplv4oFHVcsJs
+ jCboFbv3tMCkj9A/Higx55xfNbHRNcmJbeJu
+ oi4ziXjUfSEqy9o3ldjgyUKY/BJIPzWo3O6r
+ p5Gfp9eMOnU3Q3hzsEV23Ifx94E= )
+ 3600 NSEC test.non-terminal.d46.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ ZVeXqVWde/EPyuz1Z2SAbPOr1ZltIlH066p9
+ 4PpYMzpTOzRqOstifzv3+LFMXCFKVLV7qHTv
+ jhs6F60VlvNUepcyRRuqkqXnyrP8Zh2Y6k6p
+ qG347nHdxWpg8PKEV7RhMFItBeMph2mj8b/k
+ CH37VhfjjRuXT4sxGY/gCa2G3es= )
+test.non-terminal.d46.example.com. 86400 IN DNAME d47.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ V6C/pyQIUWDpqI6+MidAIFN29TLDte8VgvHL
+ NKWYiDO/rxL+GFwOo+or5LgMQcQCJ3/Ld69v
+ 9yAgzZ4VXjFR1M9/AwBo/GdEgrEvDoP4/+s2
+ F42+JychSrlnBT4Pakb/1zXyEVIKjrvMo+bo
+ Pgc4cCLG023N+gUB2MDehLYTFWs= )
+ 3600 NSEC d47.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ IvZpHSWiTu5qRMoqnRxOQahb8v8HJ0VQVxu7
+ moqeOaVHI5LMpuH9nUo/rjLhAj/7NdTsXhJN
+ 3qAoB8NMilH8bYENG4F/RmptFzOgNaNk77X2
+ N4C3YTDiRfE5k/6atFX46cl2kR6gIqE+F1jk
+ 8x4xihPr8bOl6oYfPF1nmVRI19o= )
+d47.example.com. 86400 IN DNAME d48.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ xixHWa5CeM1lQa4R03whZvcZgoNZcwby2wuq
+ ACK754tpdnMbqjWqe4ZFASLZFmSVgWxfNhUJ
+ od0mOng+z9WFLY4DtHcNNV6BQ7NlxStEVTut
+ laA20fOiHd3iks4JZ43VeH3I2fi80sPN54NU
+ 1MVkEkaYZ1HJxLC4KVR+fWpBics= )
+ 3600 NSEC test.non-terminal.d47.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ iqG00wlMWWmZ5tov00IuECsekiI1EQjPV1PX
+ /wrwXdUseDKRLPH5kIXi+OvyMzXX1X9AcCpX
+ VV18vEHJWWcrZu4Kfir3w1oen9KIMdZW7X6V
+ 7Mwj+7Vlh0DCBQRxg8diQFjpvrY9imgaou6b
+ aVEM4+Q1MBFcD2423lYPoVZlNLw= )
+test.non-terminal.d43.example.com. 86400 IN DNAME d44.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ I0oUhQ4wgHV7a2epnQBs06nXHcqiUz6G5NIX
+ wSlT6PN9ThHEn0HFqT7V/LQMGx8JIN8/1Yw2
+ Q5u3ZE3p2xrKjv81ruqCzNZLENsBCH43+DqY
+ 0SYIQbtmugmLfmTgSXU/MMP4ztY8VGW+qo2h
+ pgHxz39cq46HcsbGj++mAVip0kQ= )
+ 3600 NSEC d44.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ rIa5atSObcXoXVmVYyuklbJK+IOU8GftEjrt
+ dbTPjk4T9DxIWuPRbKpKT/XHDLNbzo8aFRLU
+ hXGDaFmzngPZwv3Wud1zkZq/ns4ZQTlfrbUI
+ dwapcU16HWHAwGWMtpIruqu8xPh0LMcGadl1
+ yEjA+q0axbLcv0RyfnmDlw/XIYI= )
+d44.example.com. 86400 IN DNAME d45.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ yqPQHJ9Yr663aXtjK85RGBwHcGNnHH9lenLV
+ GmBF3ZoRLqJrJ0A49z5GUyCg3qYeHKxq+66E
+ Z2pTrojdrlagHLJlDBb71glOLVcm3a+37/Hk
+ 6kn83JYYb92f7zyqZpPfIn7iYJ+qIHiJtksM
+ QIc+R8jLNGxBl2E1nMnbo2wgP1Y= )
+ 3600 NSEC test.non-terminal.d44.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ EGZreUf5MT0iZ0CNg7TCp3Y/pIbKuhh9qxol
+ tgid9AZjULjbVpAXE0BZ/jcE1AcafnloqtuK
+ acDy2knb+cgnEzMh2cnX1EdQzEHcK3l0t8gQ
+ e7OiNNoPqC8PxAPB7b6lkABdZ4+7S3so6mbB
+ UyqVmU1SjSV6VEr8FqbXBGNbNEw= )
+test.non-terminal.d48.example.com. 86400 IN DNAME d49.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ FDdsMgd3r/K0KejqZiwPG1VpaXsL7oQ19AH6
+ X0KACB0eTD5LBjnsxsZXmEXfhn12aTSAUmks
+ cQWlUfhgSURi465V65PaQUjJ7K6bT2pKw/xC
+ LXLEN51ayOVpMCb7mOXclqK8x0384d7Ydoj1
+ Tznde21GMw3KfAQLxU/u8IdGDC0= )
+ 3600 NSEC d49.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ PPToUHTj59/4gaW/e75WdBnu2eTEsmjlAhwF
+ qYSAp/8KtxHgWi2pT2ieCnP/cmTjf+DwznUp
+ Wtjwbas7em70yRghkVlBxc0hOvwnY83JWkCY
+ xtQqHFyi1zjLv7xNFwklQVMuuOXXNZewgXhi
+ NfGj6OI6hSXYrN67ha+oZp9Svfw= )
+d49.example.com. 86400 IN DNAME d50.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ NGeU91ToYc/kcz30H1EyQPxUvGGIEqTMdbQN
+ ke8xZkcQFrN83pU1ticZb4kGIsM7FtD5jIIT
+ dL4mNIccp1n2ZHWj6f+8v/rUY3UoZHUEElQj
+ j2WJjWyiQ/RCeniXPouJhTBUJJSobS7Yv1B3
+ rdMJCS+xD1y9EUm7TqjfQ/gTvRs= )
+ 3600 NSEC test.non-terminal.d49.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ qVvvc33dbxJckhXaK8iS2wR0jyxenN0v+HQ0
+ JuM0abF2jO9PC+ii/as+nlJqx5i2JpbEfcpo
+ qbHaVIjk2fmJ0bpXzInqy8FIYx5Ecj0gvvOL
+ udoaw1uQyjbDuld5YS6Gp+6A0zjJEv1rM2T9
+ llhJqDNM2B4q0YUrlXT0Iq4885o= )
+test.non-terminal.d49.example.com. 86400 IN DNAME d50.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ zFySwAcqUfxAT8EjN/zyvX4MLYegRedzOEmD
+ PJ3WLeS7+Cf1adj+pnVngtU3b2O+n6qD1idx
+ Jk9/2hhs6QfdXh41M5+CmSHWmBOB4ZolJZaH
+ 7LbGboddB7Pgg5ii7aI5PestuIlxti0bDni4
+ CT9y5NuSDkh0ZLANu87nPgyvFHk= )
+ 3600 NSEC d5.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ HrjH1Sls23W70YGVTC+oArCIolJJnkdXwmpd
+ mFIvA5DcxxXHL1Ts4VrN4basf+V2JO9Z+qJK
+ OwxzyqZNQ6RaAKfdMyi5r1KtXOiwXv2CT4OC
+ zkiwJ0LIPM/LfY1XYWfuscfwxTf9P0Ykno+f
+ /k6KRafBrVwW1FfsbvIXWk0KbFQ= )
+d5.example.com. 86400 IN CNAME d4.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ P27Ws10dDQwqUBOvgj35x+oiTRbeb66Bpm8h
+ nh0EX2ggiAThkXRivtUpq0YGoalowF6JeFbh
+ kwTlnLUkap7Si2fLl8oEWfXtjnn3nKfiwaT5
+ dsgtBr5SRnW11r9KmSPG8L0epZLrx1JErpKf
+ 2GeJ7DBRCV898dMBYZ0SzP7Hm3I= )
+ 3600 NSEC test.non-terminal.d5.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ yOkGOgkwjs2N+CjTu/wXW4UfEReQrlljcGFQ
+ IwzPykpswEIcRwNTzDEon2pVNjkPVWR9KrYS
+ 3pDMAC/mJ1AMRdpeYBa+V3gXYLHr4gRbn/+Z
+ g5YlPvOapiJzQ6fpSaH23wRzJUlQ3YBjCCE4
+ yLfBfoFWa/XFkqPJRxZn9oTv6fw= )
+test.non-terminal.d5.example.com. 86400 IN CNAME d4.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ IKorGneADWlr8jw1na29kWTMKsLt5DEHkLV8
+ rKr/uJQyOL95NFjpK+TAdcMq9Hpz5GGdyyOP
+ LT1fgGkwQCwWI+PS3+0LGBbqhHU8KQ5FAhOP
+ 62Dmnw/ZUkdGuyZAM0PgkPH7VSnChS2asa//
+ qiEM6+mkIAvRLo9PAqDTJoG2Z4Q= )
+ 3600 NSEC www.d5.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ fsiK64ApthpuFVaGIDfA+IZB+B7W6hESuNgv
+ lOybm0u1ErUP3GjbdbzGy02P82/pHbyRgDr9
+ 8lguywf+/otpRqiXvryZ1zl+dJG6SY/oIAEu
+ vssgVAwaYg27k8URhth1t++7H2O2cPQFdLj9
+ LT8wGBqCiMM/zju2tlvfsvL88pM= )
+www.d5.example.com. 86400 IN A 192.168.1.6
+ 86400 RRSIG A 5 4 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ vULD1Jbi59Qxhz03ulRXo80nB0txjAqC271K
+ 5wD/Rz8/6o3OtnM0F+ur7IIKJJQexl12HddX
+ sl+b55HZhfuLwerz9ogoSTIqaLZhWr/6kiDD
+ W64amx9Q8LModApfqhJtIwXIafAbYB9PvJiQ
+ vzG3On291i6e6vKFZlboEJrgh9s= )
+ 3600 NSEC test.non-terminal.www.d5.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 4 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ pecgp2ophbepdqcJs9nBnFBPh8Tkatu9SPq4
+ 9HAIC67BLvbWA5PvL6fWa8gWhc38pw3pcIYP
+ Xyy4UIkfQ5VB9X111xCx4IKPbLu2a5oAcM9/
+ DbhPEvica24qm3oPQ9BOK/kgtgIlHKxzxkCR
+ /X98KIc+AEtBmOgrVxZaxmoTKbU= )
+test.non-terminal.www.d5.example.com. 86400 IN A 192.168.1.6
+ 86400 RRSIG A 5 6 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ pgSJ/3TEinAqRRnYar7+7t3Hka00MnAEHTlO
+ GH9Wei52rUwMfvWJ8CG1kDKIEJXNm5ySMkYO
+ 3m0MAhfXgFzJB1e+SxDMDh7cM4ZWQH0QEL9o
+ HxvaWRo6w5hDuNhHvvX3F5Wcv69w+yCZmEiK
+ gZH/DXwsvPdhBKvCVUhV2Enkr/A= )
+ 3600 NSEC d50.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 6 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ L1V09ZExCtlcPEZ6Udz1Md/T2liWu0BH2cCO
+ SJCcV4hjsQx4gZ0487lDp1L2+AB7SVImpU0N
+ 5uqf0mG/j7fSdtYOfcTuYxasTHN0SY8icv9v
+ nZzz+IZc/RHLWVopF87yqD3JeWpdyOABHfVe
+ 0Or8sNWsEBwO0R6E0xZOckKZhYc= )
+test.non-terminal.d47.example.com. 86400 IN DNAME d48.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ APHibTalIK/3/jQ4N3rw2P65yx/8lPb8V5zo
+ CAQCj5W/dHiuZ6Pu1SQ8Z2qEoEsw37rEzJ1s
+ EHWNxua2aGh0pxaeLcT7Zjta8ZYkGMuKUniq
+ 4l54AaYYH4bBvdeKVTMTdMk+GML1sMx8YlWX
+ 53a9qrohmSLw2O5gs+5JsYr9JwI= )
+ 3600 NSEC d48.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ eTUXVw920hwLFlxNJfzIZxbSG28/LRZ/tSm/
+ 4F+PLW0CthEqxV1INI472E4+FL2C/zc5hhLi
+ oSK8ZNlXK9r57oCYNAWzba9GdtNWERAtQl9f
+ OdvvdRfn0rN2QXh4Up8CXvfeEWV5AMjCcXLl
+ 0IM7mpva55YbY0bAIKr2OOOFsXg= )
+d48.example.com. 86400 IN DNAME d49.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ graqGvlYjOAhU6i6T1nds4DyOiJAmbW0G2kh
+ oXE1f8rGZd5BoiVED27aIdqP5351Tb0PvAj9
+ IW7BhFVySiwHs9GZ5OAAj6vjW6DFYTlmdc4Y
+ GMTsEOlyKLGFCGTh/XepTLuWmIi4+LBuQeUK
+ c2kr0Ed/qKv1OJoCGnh0VUH6aho= )
+ 3600 NSEC test.non-terminal.d48.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ PxepWNMME35o1ChOQhQDt89YLWwLak8F3rq4
+ iRWnbIgmN/N/SRf8rksQdkCiV5w++OLqTtl0
+ yjK5Isv87r79WFwxInxCA0lKJagbO2udW05p
+ K61l3TE5Qtxtt+ByfZv5vBezFR0CKUBVGBfs
+ FV7K1R8LfAhzS0CbyfNwmEiuQlo= )
+d51.example.com. 86400 IN DNAME d52.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ob7SvAUXVsIZER3zbqaWDr+3cvglyQrshVTJ
+ e/zpf+qkxLrQ/xuspUrN4u69AIGBh8V8EQub
+ q1BwSIP8fSYweIdE5Vr8NZ2T4pT0H1qkZWgZ
+ ulB1N9eGlBw/93GZQ4ol7s3AINgVcWTo2UR/
+ zA0G/GgSJDn9W5DmS+JWM6+Mki4= )
+ 3600 NSEC test.non-terminal.d51.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ ukD2EC5ZSNIjqi+K27LKR5O3JFGK7Q192TxH
+ 8wQpCN8mBs5WbBdUcYoCbww3cF8MYEqF71/i
+ XKlAfZ90v0epp637aYIyCP3h4jo0cAUB3WSo
+ RlWpEEDoQKELaC54a7Igg9Fl5ppsK7JuA9KN
+ dgpolGwcDI8SGScSlBjKnEa9c+Q= )
+test.non-terminal.d51.example.com. 86400 IN DNAME d52.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ OHeLvB8FdcnIGHv10dwFvOygb/h950MtdpIZ
+ Qzd6UNAnuyhYfhcL430ve0B0NqDYUlyE+J8l
+ PFEcRbaXOHS9phNud49FqL2z2kxiRUzljH3L
+ YWYKKRCuIyiIVLcD/7N68dbhIh2w/DxoLDlT
+ Gl9Bt4sIqibKqLZvWCVlPhVUmkk= )
+ 3600 NSEC d52.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ l7KlwFlFAHjkfRS1xknFqZyFS5rQvZUfsAP6
+ 8SY6yHJ7uf8ObMwn5vnFNZmlU9lKuMoqrO3D
+ u6Rj+gTkYixs9h8+yWCuxa05CzpF4dBBqMQ5
+ acNoEPXdKjX9VNXNwQY1BQ6hj68nbTtB4sxm
+ nLuXPDhYJt1hRto4b5oNjEp8LTo= )
+d52.example.com. 86400 IN DNAME d53.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ pwTKX029yQ2Ds3kewJVumKJepAvBDCPg16In
+ xYY0c39EMn9M7KfnWcKwRIyi/6jwFH33ngRw
+ MldxPtyC0BrTxMU/3g8fbQwa4+td1RzXoqyh
+ P/TRyMYuZqg7pRvd3ZvFNE+BmLIK6Nl1tTu+
+ /5U55WiMTIFMLNBk4rszGI/yDek= )
+ 3600 NSEC test.non-terminal.d52.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ R3PUeC7YLueyfxokG213cfGUdOxH1GYv0Xtc
+ grLW9vGWWZPqbk+ihl2iFL4FnCGkxz844O9x
+ 9p40HblMFbP5m/ZMvfXkT7fRvO8I8JAlV8v1
+ xsE4pQZdfPm2qFjHBIweFekZ7xgcfGWK8m4s
+ qICF2jGxzTS60b9hVxl9hn2h+LY= )
+test.non-terminal.d52.example.com. 86400 IN DNAME d53.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ FKwgRwy3//wjuTOO38IJQzVX4QA7TKc7soDV
+ aGhLAzV/iJgvOqDR3aUWp2FkvXBZmFKz/uYr
+ 0ktN1L254Ld0yON8fGpb22nxiTjTjZ6VUn6f
+ OdPGHWQXWD0JkyVzopHbHZHvFFpn91ZiSb/9
+ 3OKrzWhd9amcnmYg4qAMtTbV7E8= )
+ 3600 NSEC d53.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ JtQfr/5qedGto/KadEIT956iI1MX6ThkTjMF
+ e09HJj/DDJx+N7oLUhdtpq+pDOobldHBGpvv
+ aiOmkQZrUt1eruLfhmbN1LnqerBXT+SzOKt8
+ 6SdXdyQv2FCRu6dzRxSgXbkdoxObWeZXrVMf
+ 4/jC6IiQF9V7EVQL0XoMULHOlYk= )
+d53.example.com. 86400 IN DNAME d54.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ wxWrxE4uGjPL1/qXJCoAf2Ya2ovHw0gDjEHZ
+ BnLwQ4FmCK0aa1OCg9WWLkWTaFHJWgo7+YeV
+ ksPSFfwJ14Lv9UG75mxgRyEs7HKYtsyfn5+x
+ 8Kl3F3/w7lTkr8kyh2iuPPPBIEjH0CdzcNV/
+ B/pyyJS/Tw9Ep9CrCJeXIJU3hLc= )
+ 3600 NSEC test.non-terminal.d53.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ tulemDQTMeBxeNlTmhl+iQ5277c+lmqlt1UA
+ HfvP0FYE/JIyDQ0EeYMZm6G4MiYAFipJkiSb
+ d1aE3nUqVqB5DyxAboUSVavr876HPaSaHmH1
+ tbHayHu+EOIlAoNp/TRysbtA088x9oEBNMzl
+ CMcFSwTqeIM/+sHYYFv20NIDrP8= )
+test.non-terminal.d53.example.com. 86400 IN DNAME d54.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Av/rhbzcoT5NMBy+W5gC42TGQACIfID+v2zR
+ 2AS34F0YctsV8nRqUweDc29neHertB5QavCR
+ cYOcjoq8FRU2Fv0nA2dq2sV29FOlbemSuIjk
+ mRurIyLQvYsM10X0XyIbspiE0WGUd/whY89R
+ xq5tV4d63bgScmPMThWkh2zrKT0= )
+ 3600 NSEC d54.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ jMjBoTAENoFkGGVC4ZYIwCB/B17yiFI/PGkP
+ PlAc6FqXAuJv5s4ANZ1ivmRC2S7xfoFhWcRa
+ Wi+rYsFA4HCXtd4XojYeF51mvwf1MJM3QKir
+ JIPxJmDriQzMlIPrA792GXbxy/eHm31JKOff
+ 4Lg6xBRrarbjGbLn52Wv6Qx9Upw= )
+d54.example.com. 86400 IN DNAME d55.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ tLcB809dF0SzNNkTDxQi2yUUvGKLLx80cylQ
+ 2Q+LQE0thrKWEtzoUhp7dojgyTLuZom0ZGOL
+ st91bI18DujPydi4UZuXI0n0z81uXrP9Jr6T
+ ks0MwWJWnavrZxqxMootxjB/2YMi8vCunKTe
+ YRotKTTfVh35OQATrmD/ixjfrzY= )
+ 3600 NSEC test.non-terminal.d54.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ R37llTMvvIym9/JyvIyndMruAaY7tYiAIADP
+ dx3xLb8tOd716299yCNWvjXb/1DROrRt9GD7
+ ZW23R7wVzsd+MIhmtM65z0JvhZaqSDwigW3V
+ r2MQmgwrw04PKpabMANu6eNoi6cv/lYbCyTh
+ FrLSwXkqcB1ITuC9r2cX1ab+yEY= )
+test.non-terminal.d54.example.com. 86400 IN DNAME d55.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ pJmpKXUwGwF9NVXTj7p0VCFgLBgPy4pFG7+R
+ Az7HiuVWRRhU3GOjE/WlP/4yYrDIHVkKUqIE
+ KqZcB6/H9INvWDDCl5QdFtNn0U+eR1POPLbL
+ QIzGYEBWMnBQyfbAPolXv5vXS+Y4lkpxgq3R
+ 6TvxrkY715Y+/XL/JbozYbTuTIE= )
+ 3600 NSEC d55.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ IlnT22tG+kP9KOvuD5BmA9340tK9Dg0SzS7u
+ 5hNa0OwkgHmlRkl8QQP+fszXqcV2w5iJXs2a
+ uPXgNYeUa1KPJVLMhjGuxhcQE7QO4htnZj/L
+ YGUvM+TcWSKvsxJJW+pWK8op2/Wryq4ZhxK9
+ rwrzpOpxWsrrM5qdbp3nSBojMKY= )
+d50.example.com. 86400 IN DNAME d51.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ K38j/kWSLO6dlsaj6zjwzAlTyzh+i/vBy9FF
+ 6piwjv5C/zTVMD1FJfib8lt59+3XXtHQLY4I
+ k75phzMefkNltxceDjajWizW23J/07pMfYFn
+ tkqaiMAPRAQ9n2IS9YGiE1pXGqUgDyNgguPo
+ u8W8FNXnDeLt4li38LFvA2iXJEg= )
+ 3600 NSEC test.non-terminal.d50.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ PPCtzDBJWAfEY8bjbhFkmMFdrPMcOdY5MIgq
+ xKd3inR1G8Dd51NiEAcjHp+Q7mMAyEUMf7n+
+ 4l8QjLnbRcBF73PPtOMr7TIX7jzYRYHRXHFT
+ /TJPhy92NmXqc6t2SrWWRB27vyDm91KDxACa
+ hdZFGjRPuHeWCE2OXVZ0F1ylBU0= )
+test.non-terminal.d50.example.com. 86400 IN DNAME d51.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ iBHaBt2XClcxB0nB4zKOinsruncTbD34bWTU
+ lXbKWRzY2muNaht8QrbkOcGp01GviPxexQar
+ oMpYD8ranSChSRDeBBBu6KcUSuAeWT36iRDV
+ 8trQAnMkf/pAg+Yto9eDsY1+Xae6Ji2sMWhJ
+ BjjmVKBLmNQVfRqpPABsmKmpnOA= )
+ 3600 NSEC d51.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ cVuYXx64JJdqXvauOdvMUuJqV3mKej/SSmIk
+ LZf1GRFEeRkcfTgsrNMJyJPYAaqSRLg9dX6I
+ rRrV0J47CcAMLmoknYmNYRqLLbDlV2rqfkre
+ msB9xYw1ip/r1kk3Aa7+7+oqcDyFh+UdkvsG
+ 8To9CaLe+Z4W/8XT5Ipef2FJP0o= )
+d56.example.com. 86400 IN DNAME d57.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ A5FrHt38MZ7HRVeOk65HFsY1//PGz+OAk17Z
+ g/LGytFcTEF04VHK/V6UthcWmgBr/bTfwwLz
+ MHPQThKv/a9BH1gi+xh0Z78s/Bqz5wYoyvwv
+ xKM4hP1ybXX5+ymVVwQ0mVKHml0KYMZKmSIq
+ o708k4fKUS8R8Da8gOAz3wNiLI8= )
+ 3600 NSEC test.non-terminal.d56.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Z/iyqtyhOATyFDbRwK/2vzwVG/s8wqT/XRC9
+ QPodJbFfR4veh+SNkJJH9vgl1plMpUPFrhr5
+ YZQZIltnh/XB4lknhH2hBbItDZzjntkv4RsZ
+ 1QDqveNMgCsJUgO+wcRggALI9evUzHT/6m/w
+ 9PyywulEFdV442oTHYRwU+GIabU= )
+test.non-terminal.d56.example.com. 86400 IN DNAME d57.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ FzVD7OlhI3F0ucWJpsiNcHSdjgESqsFDOIQl
+ fxMDdAx8dZwAjptkWMd0UFomLViP6XxnN5VR
+ zOa9kFm8tLsuGnThDWX/MJXEhCL3ZUIkQ4Qz
+ OI7rq/S7eJwCRsekvtNLz9t9o+Bdegp4aqAt
+ 8IS4j5pHN7UPFJGnWU3+izZ7tis= )
+ 3600 NSEC d57.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ KEtvHe8ziDkahA14gafEjTg3sunGX8ZiwSYy
+ ZzerUSPz5j1yYBhGNN3icENQlPSs8WVeGA7K
+ wDlA8uG0WsqxBeTzIwk+SWrnW7qrOek2zYr7
+ NGIVsnONs86+DarU4i+k2b4WTt356F9YHShN
+ 31QGI8dGYnuaSwQ3nvUWfHHCa98= )
+d57.example.com. 86400 IN DNAME d58.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ aepXpMXVir5N39tnsWWqa+TBIOL2O3wUGwxM
+ Gf0BKdCLffME8dSsjHDzePx2xqFRXmaO0Fqu
+ 02hHcUUS6gr/0QHvwdM3fag9c2JLZD4Ot2sD
+ g3dz2WlkeLDYIiJP7CX+WmtjBRGPIbDM/mMt
+ Gu435xsdUzey6hqAIeCnPRIbV4A= )
+ 3600 NSEC test.non-terminal.d57.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ XzgpBHxvhafDE3zHcgI5Lkm8gDmxqWk0IKGt
+ uiewi2Cd1CdflbCBKn+YW6KjWjCcGYc2LNva
+ lzOpL5XNc+2Dx2gp4jlb3VmNXh0oEetvqSRb
+ hjlo5REnuQAHiEQH9a2iQL5HCk4Er/PCIRs3
+ uoqpIU13gCCLdXONdEoxoQ8aQHQ= )
+test.non-terminal.d57.example.com. 86400 IN DNAME d58.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ wTn554M8BJc2A9xvTs0/f03p7Zi0wjetuFyN
+ Krlr1eqHxhaKP5xcBKxFBkO/DG2tDK1jlYOI
+ /hY4lxQnT0ucuYl8xkaXKOfitK8dN9iOxGpS
+ qA+EyXZpNQJVvyMYvVwOJoUKKlJRb0V8FcBY
+ oRiZXriPAVqx0+pmRHn7mWcAciA= )
+ 3600 NSEC d58.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ AZyh+Ul3lfZQS2sZZtd6QQZWYEPhyfm5ZKpw
+ iXpYww6dgGLsFfxo0NlXM9Ci1WZ5dOtNJN7T
+ F8ZwrDgMESlJ06f2wtfOWSK3CiK4TlTAvEYm
+ dbbvkjCxLOSPQa6NW/x3tHdKqX3oKxm6mQVz
+ CkcBIoXL+O7sWFYgoR5cHO4vAto= )
+d58.example.com. 86400 IN DNAME d59.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ g4KCW7ISDwBggwNDFTV1dQjGd6l2CMBOAMnD
+ B116Aa4VN6en5MO88tDH5KnaUehE40C5Fh5w
+ 7s3zrMSnDsIAEKS7Q5WVQzJYW7rCvH+l9uWN
+ ffG++8WK5AF8oS1jmx9Ai9B2r2TKkidaKOfF
+ WQohh582K3klHK8fVkeXfAO4XJA= )
+ 3600 NSEC test.non-terminal.d58.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Hzb6pV53Lgs3UeNl9PQSuK4vXH9Usif+AE3v
+ JUEXMot9sf/Yqj0YQ7bp2fi24CHtHkyJTBqL
+ xr0OWwghDiY1mzzc9f886O1UPRMaVw0yMhix
+ tGPtUrQAmlhxbCEkT+HL1FqS6X5VenRRStgr
+ hhejEInXnKcJvz/mu8X5iAybVyU= )
+test.non-terminal.d58.example.com. 86400 IN DNAME d59.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ RKs5QfnSUcAXKCRJ8cQwmzJGZQ4Fww9vwngJ
+ 6h4B1xDJ/XIchmupkI9ZyxOCcPNNwvI76Xmw
+ 9zJCiDzRc3vvleWmZ+WMntDzwn1LFGRgoS1z
+ qrol5HuJbnmLXFLHzDIi6xKdHhA9OH8pmMDf
+ VURAjLRl2vHd0uA+mG9VGWU192o= )
+ 3600 NSEC d59.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ pYVsbpS4N+m3AM2IjGVnEhaCyeW9PJKysg+g
+ CAar16agqOBZAFEQ9imO9u3zLYL68aS+X5B8
+ cjibKkux4jynHN979m0lZZKFXlxmuGRd2Hlk
+ EkbWW9a7nay8Rw9enNTk38vTX3MNcaNtufdc
+ FTHqnDIFzRm+DUvU74kfT7SC2y4= )
+d59.example.com. 86400 IN DNAME d60.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ HV77cJwpdWFAisXOgbIkS5iTQ/j0QFspwE8K
+ mpVT/VVgXFVJHcD4WQLnshNUFPtVE+TTEdWG
+ jj5iNZtNH7nnZMH8GxhXIAGdZLRIilTSlxuF
+ mQVoE2arlQ0MVjUKTWkJPTmlQtPAIPJMydJz
+ 2h4cW+gv8qbKjG8xe90lpN3ijVs= )
+ 3600 NSEC test.non-terminal.d59.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ wFxN38pgrGqoslSEI+p3oPvdMbP38YKekQSX
+ YCazFjuxyYQDpA+Q0EA1vZBvGEHy0VmlO0AS
+ IwHlN+DzuAWLqDi2sfIY/9vJkBHmRhs5KDV6
+ yQUELyH09q/0Nn3IHdz4PKLLN9NWKdwVdnvR
+ 3ZC/7OVPVyqMJk8ZxIVrUH9YSfE= )
+d55.example.com. 86400 IN DNAME d56.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ IiWLmG2Qz+QqrPwbd+PEXQcaupEmJSVE+AaI
+ sQFDdbAj9X6oQoKVwRMj7DFhWr2AlVotAfo+
+ UmQAH1hvTjqFS2gDi2Y3iKVQyQJ/2y8Htvze
+ xmvhdL6j5PjuZPEHQpJ2lZs7BDhuJj77Ydcw
+ oKPedUcHfIbX7LQY372oGiPpYZU= )
+ 3600 NSEC test.non-terminal.d55.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ xyV3SO1yg1FpRzB0l+tCOOlQo7JjJOIOFFyl
+ Ee1JIox27pDz7zRFjDg3/YWQ2KeKJx9noxOy
+ xaBdcpKrj4OUnmUFKU6NfH+fd6Kbq389+Xa+
+ fyPdGZRwjv7bVuP/neO5phkGUWwJ/kWHM7dx
+ XnkqZtKiMQNfWFRWiq6E2Jn+Iyc= )
+test.non-terminal.d55.example.com. 86400 IN DNAME d56.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ wTyWA8Zw2epn77Z/T/Oien5kGWld9yj4GnQX
+ uHDC5BbE6nwl/iOQIThVSfX44eUDQ6ZaFtP/
+ jdzQfAmjj00CZ9MNkMVO0OTvytIJn9m8n+Lz
+ Hllr3trcuRR5fXkLi/76f2bOW60Xa5vmBp4+
+ Y+G8r09NHh+8lsVrTlcodMyAF5I= )
+ 3600 NSEC d56.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ qlY1jFfkXadSPnSaFVGWH65YrjE2WkrVpt4u
+ taX76HBaJLXiZ6NZd1srPss7LI8m9nRW3gKS
+ s8BFjZfJ7tqYLXW2vLekYHBlKWd4A6VLTW/h
+ uxN1Pni8hPrSQPi88VVEymbsE+NqE2g4E6pi
+ euwOTylhs+oDvqMbNMNTjGpUtDI= )
+test.non-terminal.d70.example.com. 86400 IN DNAME dicarl.cnnic.cn.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ sJOusae4Tsw5x4toPAZaqoWO0l3LxNJUIoQc
+ cYeLVCdVNvqLMOzu0HpuV9H3RLHvp8vjBJBD
+ vB39ujHG5YBLRzV7Bllzy+2l69OrmmNhAo9g
+ sdz/7PhPCUkc/tedDrpCDUqmvA4LOE6OmF4i
+ zWUyC3701nIgp/8bDg5bQqCZSls= )
+ 3600 NSEC d72.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ HzbLK6MfElgWNL1klvwyL5Rezwx1JmKNfkBJ
+ tGT4xFwV/l1hNzx3MmcOgdI9vc8vw84RXPYq
+ vlCvfLt8HCtZmpULDxrTcK4+hzc9Rwd6sk2x
+ 2ZF7Z9oZFfND0o04qfBQummdTaU34YH/gzlS
+ xWiAFiy2LLe7YiSPEDLuBcHtjas= )
+d72.example.com. 86400 IN DNAME sub01.d72.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ oQsloDjou9E1NRfVb49eHUuKtsehFiUu/Uxw
+ AUoojfDtVWf1JgRpZv+Uh0EQyjky7U0+MmGK
+ Jio+9ws9Ek3oCJIdDVScdfg4EUHANcCt99Uu
+ ggRqr7VwBXiYz/vnAL2/7qJ9H+IajKwFZxUm
+ k3TUE8rItUT67+GbgjSvgacQTbs= )
+ 3600 NSEC test.non-terminal.d72.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ BzbybR57RmDRyn4oie1kfGuyX/AWGhCVqKLJ
+ iI09oGeR8qxaah1wnEt8J53nqTDA9u1nG2R5
+ XNEa8k9GPjuqHsVl7uI4+/2bAc4rSaU7KA54
+ EmeWw/5J/BZy2JBH3Fbao4eO6k70r+3DcxCV
+ 5Gg5Z4CSuEEnB0G+hHpYgiBojX8= )
+test.non-terminal.d72.example.com. 86400 IN DNAME sub01.d72.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ mTtEj+B0PvJH4o3sUvL9pWMXo7n5Kq1nTB99
+ 0trN+F1So91BjrGDznv/dZ7nkv+8QovFuyyL
+ QgKtl4hQFqaNaC73SpkChlAdKQO78JPE/N/s
+ vabju8PLRd2fYRk8C9qBGqF6bfxhvQgwtMa+
+ RpFDWytdzzbYeftcLK1O9Jfg8C0= )
+ 3600 NSEC NS2.demo.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ JUrLP2PHy3QHGcOTajs1lES2bVh1674iREdS
+ lWUPV77GIFycVPQnCrh69aEf3W/7Z3ih30sd
+ mAxRaKQRSVpofa9mOY8m6hIN8lF+fLFj+RNK
+ EKc2rn/jlYZAIIA0W0T5x2mKsNFMsCjxjwHJ
+ udsQ11DSbfrKhEiZZsd/fdAQHPU= )
+NS2.demo.example.com. 86400 IN A 218.241.108.15
+ 86400 RRSIG A 5 4 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ gEBkB1vm7CjYdB866+lGSyIRuwxiErInV4k4
+ Kpa7iJvyK4aJ2K9vqoG1wiralDK9HoeksKI7
+ 6/80+p1QSkqbeCz2ehrj5qxDvh+afQnWzh1p
+ Ah6/nZipnGT7ZZcxlYKXCVosStpwT+yvX90x
+ Qp1uKeXBGQIS3doSO5Lxnhc8I9E= )
+ 3600 NSEC AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 4 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ yhhP5MbObZRTlDKhvX85VX/1ca88R7yPUaJk
+ 6aiugigneW/uMi1ZjjVm/aoLufHhQYbcEJ+1
+ IeQW3xGDNl01dFfwZETizQoqOzpsQ/PtNYbE
+ Y3BaMYvGtUi2+JxPDkbTicRX1Xz1P++u3dQh
+ rPvHd0uHQtWMM1/cOAkd32/BxTM= )
+NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com. 86400 IN NS ns1.NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com.
+ 3600 NSEC N.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com. NS RRSIG NSEC
+ 3600 RRSIG NSEC 5 7 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ efX0JgQvcHgH7Fh76nqS04/6f7i5Grz1p7lH
+ 6YeEyZyjl+v2r7ym7kdyp+kUg9Dbbv6RO2pl
+ juSFb3x2WNt4k4poUH3zveDY005N5teX93KT
+ Cklu2bw0fkJ8imo8hpNNvClp4TDXcCCDR/jP
+ 2hSBXnzA+AC1l8bkuMdyGsGnksM= )
+ns1.NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com. 86400 IN A 192.168.2.2
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com. 86400 IN DNAME sub3.cnnic.cn.
+ 86400 RRSIG DNAME 5 7 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Pkj+vbKUhB3wDl/k2vnC63u3RCtPymJuy8PV
+ JLaNEQjf6svjS393FKrH4xvJjP78RnWeVYsd
+ um+wC5iOgYQEvyguZd3LwbzjkED8se2Sr29J
+ tGnHiKu6iNKCnjQBSz+G2IoL33vofuzAK9Dx
+ KXAIU7kDjcdpA7rOO/qouzG+Rtg= )
+ 3600 NSEC NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 7 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ xU36WQo+z1lj4DeMxU/kkzlVNvTEO56NiCrT
+ wI/eBiDTa/scpXsAgLjkDK98eR3sPDSbYJor
+ 22efGHKL3r7HE0JXgXg3QqaTtHYRx4aHVMvB
+ ui3BEgB7M6/fzq7M5a7NNsqm9bTzQ4kFkFWA
+ alN9kSbWRqZeTVY+WnH1cWHhKsk= )
+ns1.N.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com. 86400 IN A 192.168.2.3
+N.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com. 86400 IN NS ns1.N.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com.
+ 3600 NSEC mail.example.com. NS RRSIG NSEC
+ 3600 RRSIG NSEC 5 121 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Cvi2ndHGWcwRYdPZTCehM7WmYht+7+ZRyFs6
+ qr51uwvfaSwaepBghslFUx6OaNPlFCx2SH3h
+ Dc3WGKG5L4Vf+diFCbbyQJd9T/ZJ9XLyamJx
+ s70tGx6HCtn5WLSuK8t+ER7mkazaW4wkhyT5
+ 5eec49Q+PrVErHs0sTh7QmR3bo0= )
+mail.example.com. 86400 IN A 10.4.0.1
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ E3BIWNPrCMlws0hchvEmK08cxmnk/Sthe6Ha
+ KMTkqSW1GvYqopHNkT306tpznyRPCquz/5Xg
+ fr4h0ME4Ii+Sgdc3cQ3y57FckehktyOSCUv4
+ /eq+4ZNCIU8CEpM3GPif/+6Jw6YJNdo10psi
+ P5BFduWTcf4D2wkArfyeKFX8zf0= )
+ 3600 NSEC test.non-terminal.mail.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Ex1fByxHWTiEUvk+SvIHtClMf1tpaLZbBkU0
+ Uvvb6cscstzgBviip+LxNQwvP75DkXIIUu5A
+ YWFIYcFZATQQiUPhXeQxjh50pTRhhyA16Krz
+ urrNuK5asKiAaZqJ9FZ1CfYfgfhAfsUr00SF
+ CV+oaAFLTuzycM56Bs6hhpbQEfg= )
+test.non-terminal.d59.example.com. 86400 IN DNAME d60.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ k2ouJMhtyyV4zQdY5tPxavUC4O/5bhzABxmd
+ 2HRsU5rAh9fwQ5dP3pSegTVXnUDaEOAWO3Rz
+ D2OfUsQcJcBwqJk4aM8vjimqFOKuIGy5A6SL
+ ByNjum882LA8c85utl7+dE/F8cdMcIS+mW4U
+ kRJ1M9N54GoYTNFVhNpn+O3lXkg= )
+ 3600 NSEC d70.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ WXa6gm/fCfzC+cCJ4FHLyuph6UmvtBoikli2
+ xDRHwcr7sfIHEPMBsWkSiwSh0ooibDcnxc9b
+ 1Q9KMiU63eyVwnYrWa08ZBiNfeGU5MFICoR6
+ t3flIl+7PDQw78pbYm7piiO4gxS2AC7fBn5Y
+ KftJNCWiBVnroQFC+aBZ6lVZQbE= )
+d70.example.com. 86400 IN DNAME dicarl.cnnic.cn.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ MEfjKN9rAmiv6FWIBmFRwpyUhlgej/s74oZE
+ nLuniJl5qdiOHLsCM7C7Koo8tYaUlU9k9wsX
+ ARFReBoUQ/E+u9eWUKMzkg2je1bR5mieNVYp
+ 3l/xGO79gcLK8sp3fsHxWMeVAw7ec6svCsjm
+ g1ysEcuNN1A8GbAjzyaTeKE1MYI= )
+ 3600 NSEC test.non-terminal.d70.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ vzGn9aTaLqQfvuZRf3NP2Q+2lROavGKDkeuc
+ Gzm4/2oGOtv537VRyNh1W5VMA3hooxFMoxf4
+ OCeTaxU0TowduMT33qpxEW5amPZ0H2KpWi94
+ Sks5qX+p17352SlXrUmn1PpUtlw4SiAcTykd
+ IGyk9SyB3EDkoxL19QKB9PwzlVw= )
+test.non-terminal.mail1.example.com. 86400 IN A 10.4.1.1
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ WgbJfoitNOZcm06k+IK+DiJEaSC5G3SYR+k5
+ kyWsovzaB9AKqqzTz4BZHNmEK8MuzBv7fo14
+ 6dB4LuR38KdiZsrM1rpE+CaeS/qc3JxihFwT
+ I0MkQTNaYzXaJlVwacFMOFix20e0X4tIe8as
+ iSEui2GAfwLt5zoEsC5Ul9J63Qs= )
+ 3600 NSEC mail10.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ vE0IY559z+QzSelb3Bj7d/jreDH6RpGzM0Yy
+ zJJrvc7apgzCRP7VDya8liZQEpsjRmAsarEm
+ GdZSv0uKrLz0HHBsykDdR7cp3bBg8v9QDtHB
+ RQG4ed2Rpi5B7ycdx6HXEa0n2ZLhZk90D6oZ
+ ytyx77Z+jG7Z/me3RI5TymxAH+E= )
+mail10.example.com. 86400 IN A 10.4.1.10
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ wv7NomK60P/RCdDsS1eUBrtI00kEsu/NJyhJ
+ VJM4HFVrYXOcKjEfl5lXM/fJBv4LlAMhuzFD
+ 2MziNeRr4crbzVt6vAYzQq/2CWBZDniiJIKd
+ EakNNliNu1BDVr64lm1gDDs3+a/2hWL2E7XK
+ XeZXphgYquug2L1dtTRbW27G1ZU= )
+ 3600 NSEC test.non-terminal.mail10.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Yc1N7vRqNUhxvcPwS0GnjofDzyGa1h+gHTZz
+ TkG/RYSeDeUz13jXtsVB1/ZhpA94cEn5DR5x
+ 3Pi31mr61Zsb1zKI4q3NsbM7vTor32gbzbj8
+ CZHVwMjkpd7AOiPAk14q9iREPjPYCC2+mMD0
+ OcNs6HssNzvC/DrhwRWPwz4nfGw= )
+test.non-terminal.mail10.example.com. 86400 IN A 10.4.1.10
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ oBEDA9mWjn4OiB0u1eSerGPp7A5g31dX7bod
+ ieAtEu4C3Lnnrpkcem6iS6XZN2d9D2M7TTO4
+ kYho5fytEHFu5kTfmtWuBirf1DoAV3rcpqY5
+ Sbc8NZE03uJ4jKuTHbNOdLuk8Gr78apm1sB4
+ MC1thf7n62h033OrfcYwwobwBRQ= )
+ 3600 NSEC mail11.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Um60SGEk2RxUQK5GNZ09duBxDi0iTuIslKXa
+ Wi55L5/oHvXR/MM7VqNWnyGmJNBPz7Oqe7V8
+ i7GA+Z/sbkj/Gs7Nnzimf712UlxxpF/rTv23
+ 3VZw6/MLw40eIXVFkymOLIeYzt9zb5+53RVh
+ bpPsYviQ1mOCmw2gQ25VNJ9rPHg= )
+mail11.example.com. 86400 IN A 10.4.1.11
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ XaQmxG9oM6lGDSbNNOG73U8NeV/3kdRHHsvF
+ 9Ja+sl6phtEY6M8ErMTsxzmWkqxfJ9GvjWdr
+ ivfv8/SjtWiLMZJQhigpruMU916sfK1X06LY
+ NVbUhtVJm5HNhQ2CVKyZFRWbidfXnm7SJFNL
+ 1hFGKNWTF/DRlPK0bsEDqG2DhnQ= )
+ 3600 NSEC test.non-terminal.mail11.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ repU5qTAzTYlOJwTesJkEzZrQ1qc4mWVqHf0
+ lNcjzKIoN7aGplQ6SW/MCuJMRfAWWK2HLFse
+ 2jXwU8tEDfvr7tuv2CZioN7WuDE7PpjNJzwn
+ sxdaiEBZSWDL9kSacQwyNVwOjL1WMxHSuuRm
+ DzNkWMhC4xNLCFHKrdoEPWk3gj8= )
+test.non-terminal.mail11.example.com. 86400 IN A 10.4.1.11
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ RM30OrGcHqGperkip7zqX/3bGYfdwRIkzgsG
+ Yn3ewcaG1eVmu8peZg86Z+9jljSy26oy8kan
+ 9//kn67W9tyBfglj223vVhU4QHlRl7AQxMc5
+ 7VDUQj9pHfXh0x3hLo07lwta4H8ednxLFHnN
+ l3GR6bJyPbE/AzXfhIFLiT+SKpI= )
+ 3600 NSEC mail12.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ BbVJnGuGXOC9hc7wIhcOGFz4eH2sfqK4fFhc
+ m4fEt6H6Gn8X1iXA+4czMkNqQv+Y4w744SSn
+ idOj9W7xj19zAp5uzmviFZUyUeQ08JOSxaE9
+ w1immavwVVInaqoDzBUF3k/EQO6ZlPRklZlc
+ stMHTIU1GmdqRcLUedHTUDGs+HI= )
+mail12.example.com. 86400 IN A 10.4.1.12
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ULkNZR9GJ3jNYk6tMgA4pL9mzqw8fuRSNUYd
+ bdRFNvbbosxxz/7A5k4Eyf9t3daJXQ2BOoI7
+ ior+ioy8HtsbkUhkhTwYJ/LYUmUif2J7jWMx
+ 67I1IFXDbWXEqv+iV10nnknKL8nJk8a1c7xt
+ 3285LqsQXhifGD4nvbXOIwTYNZE= )
+ 3600 NSEC test.non-terminal.mail12.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ kViShVqq51fKGo+KUhc460FRF1PmfDaXtSZo
+ JEe0ds7jP1jdoIMs6rt/M0NH1lg0gcmbhlsE
+ DEnClu8HEqCsp6lbz1TgNeqYNgkQDqmyZggk
+ mXyjEDtQ4xql8XfzbkX00dX5u9ACPZIkmvKV
+ 4iQS3bLGiCQg1w5WlPGfOZTl7KY= )
+test.non-terminal.mail12.example.com. 86400 IN A 10.4.1.12
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ lYsqWwKz6k0JDzTw8T95/MAnXbaODOB/Ab5M
+ zkmjC3jWKDgOnlvQrMlYf8BqE0HJb63vX0px
+ vAX2TKPGvQ+wEB1fed22nqw7DYjzfuNzOaOt
+ 0ELyEzlNAwQ7NDSkT85ng1l1qEzPKYIzlgc0
+ L97wHcnPv7Urj/igApMX/8NkQ74= )
+ 3600 NSEC mail13.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ PU/IhwdYZcKTwIIwSxlcuen+TWvG2gRp42QF
+ B/Fldaec83BSWKmq9GbXuccIFoHNKMTArnfX
+ 9uuIP4xLqkXkDUYD00iaNhpRw1Jffbeoh3Fy
+ JSH9aY0xW4Y3osobMQr08iavv987OhbNKiYy
+ v/fPjuz0iYm9/1HoJLupZUsfeZs= )
+test.non-terminal.mail.example.com. 86400 IN A 10.4.0.1
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ DnPjHjEhdqCWkgzAPRifXUGDx3g9V6yJt5j+
+ EdYQRCt++GDbEF2Ynl71Vd/zpTacCUWYps+K
+ WabrsUhsjMHIPoipa2xjobIfjrsqfo8pqrMx
+ RZtCt8fZyxK7NLczKU/Ie+apcoOYnDMW1AbN
+ lSL+h8c3HiZ1DHQdFPq8D2BA3LY= )
+ 3600 NSEC mail1.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ qNtQsc3FtsLw2H+d8zCCslSYohsV2ofLlmyK
+ 9dBVxWmMkVcPBpfx+4b1fjV8SL/+SHUtVPA0
+ 2Yx8S1BIRcOMBuM2ENJNKKExfCAHLf0dqOvd
+ mZZe7z1TTgMkeBCAG5lOZhsZDg5F2jAPYOeC
+ b/YHwPsRrPWh7p6Ai96af4BmuAQ= )
+mail1.example.com. 86400 IN A 10.4.1.1
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ eFsMrAmwRL0R5sbyaZrkr4vfQi9RvbkYObM6
+ rqNpfDjw6eOwvxLm8oZFr12oCGI3xBw6mgHT
+ pF1l7y24pZoCnGpg4Q1ag+TBVgvZuFfEcJAk
+ KALe8a9BhF20Uvs0Ec+BiKcu7ed7irAic71x
+ C7qanobK/CJ0P4PX+hiW9skHGV4= )
+ 3600 NSEC test.non-terminal.mail1.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ mRwBgE7mSYb9F5TixnzooW/4dvwLq8zEn1/C
+ HIGSimObo2B94n/Ef5NQ1kf1gqvfyn+ZP1HW
+ 8hvDLeo1paMJd8xmqknIjOcV+hcjntTid38T
+ BgHAurPSRjiy4MQARJGWc2EuHnxt0QqAjs+H
+ MhDoIi1II4LAxJZyWTSyWthL1YY= )
+mail14.example.com. 86400 IN A 10.4.1.14
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ H14+atsKW8ZWNd8JZ36TkuBFZhXdkJUThLzW
+ c8gqBsErgeeZMxcUC5ygm3//cI++yJVMD1Bx
+ HTu3b7fksTbJGvX3UdhVTzGdR9YvJYi9D2Xn
+ cafKBE+9ETotMM62piNdmCY/lVEURI00/yvk
+ 6mXZYH76sDNi6i/deK6SmMpHWv4= )
+ 3600 NSEC test.non-terminal.mail14.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ WxINgY9cqH55Isi0HHR23e9i4eKjvdw2lv4t
+ QYXV2NUS1sFTrEIpCGaBMKYwKh8xkSM8fuL7
+ bpMzvG3emC4Rg0n9tizYCNjsfTCQNoFNvpqj
+ 2fKuWxUqV6gjzTb6KjlKOSfx5SW9L5Sg0Tc2
+ GV5b2QHiW0e847ABx2dql++GF6E= )
+test.non-terminal.mail14.example.com. 86400 IN A 10.4.1.14
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ J//po6XMFoHBXbqh6v2zbK3aUovMyDggAYj/
+ o7eDkEihai8nWowXtpMbxys/1dm/l0WWyBCF
+ GaO7vLLxkRt6F7phAKbcAV2yJF4U64nnvIrV
+ aHFWF3fkdEN78t8CHtl+aYi37878in4t9Yvw
+ ALGkXfLx+UG2+0TxpzQ3mGfto74= )
+ 3600 NSEC mail15.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ coWx1XV3F2ZUu50ZiDU+5msSuqZwpZxvBBys
+ TSj8+jo/sPDSA/ilZSss+WxGOHrhppalbpcX
+ TnLxEhmPHPGUf6NLfB5+N0v0Pf1HyhXq8Z7g
+ ULFqYCVK16MQkSGuYxX7maN8/XtosxX+ZrF1
+ 7SeJqpHzWFTPIiO+gTrAAXSJHak= )
+mail15.example.com. 86400 IN A 10.4.1.15
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ YP2OUilH+GET+E3E5YWCCslWg0rCQi4xIIGi
+ FnagBLB+XNA4L6ciizUxKgFdZ/Z0C7Op7X4/
+ cLEMSsOtCGgYaNX0EqdT4oXk652+mL0yKs5y
+ T24PzldUd5Zh/iUCCZ6uhjoO1xTMSsKqZnyz
+ 6DIHk6OPqbjV4I3tEIaWgQ5qaAQ= )
+ 3600 NSEC test.non-terminal.mail15.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ tZ6C9X+QdFelME6sS9gz/aIUBM3qst73Km1f
+ 0qkA3/P09OA0hlFzFSebDDwq6mpFyVbi9eNZ
+ PtCdYo/yU8Ijn9Hnb3aazkcPUQk4CI6wkAzE
+ mQNpj7rwzvMdBmQbRAdwUGbdVoJTRbvjcZ8S
+ 7VYEHp2V78IC6+yDrxT93dKgXTA= )
+test.non-terminal.mail15.example.com. 86400 IN A 10.4.1.15
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ nWQkiRRvlHtXeb//24mAa2yBryERD0bvWw1l
+ 7oL39AemUF+MVHmHc9xAYqahzizK1SAmd9ax
+ Q26D2ipGfDDAvcLkZ7w80QiPWELBCC09O+2R
+ lUXr1n1XopyT0m7DTFYg4BH1c2xwrqMrAqyi
+ frjEhuKvdnPucunHpOzhJaLd6+c= )
+ 3600 NSEC mail16.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ czIMj3JdbgqmUC0i7Q5qxCO7YlYwjag6dPN8
+ eT3mQnWoM5njhxVh4WTonM3Lh29BhZdYMdkM
+ u3Ba8xG4JFASCO21EqArHjrOsEr8h0RVNT0g
+ BXY5NEUXH5IjCnqePI0DTrgFf374HoAAK5ve
+ cwAtWtWQl20AeRBrFB1auzqme/Q= )
+mail16.example.com. 86400 IN A 10.4.1.16
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ QKYCaMEqGKQmVHWNriSBcVRwuqtHkxGIfaC9
+ WQdNL/Mbt5zGxS/6v1W8MQtRpWHWrWOZBvNn
+ RjfNta+GNjI88yY3qe/Q1S9RQsWdLA3I4XKT
+ +Y50ekCI/+qtxi6yhhHFKTSQK4DvPskkX+9D
+ UkhYhnzrqlp7zUQl1RxV9aQJDrM= )
+ 3600 NSEC test.non-terminal.mail16.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ az7+23AJg24nymox8k5AB5VlGa0Zvplh9K9i
+ qkAYdvVR4qQK4Ugd7B9gUxVeWiPy4sN8S8IW
+ YgBnuskgy/Ly99DAQ1wqmkJdFpIzW0oC7P+Q
+ qFEViacIEwtmfGHczJvNtkeXQBHS2dgglxHj
+ 7Ih37xOkph2NdStunkIxNfReV78= )
+test.non-terminal.mail16.example.com. 86400 IN A 10.4.1.16
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ TJGi0Oa4+d7VIPH3n/oFToOXxLKISZaByKjA
+ s8gqdx8iw6D6ce6ces97fWQWY4QysYFmxKsU
+ zxefahGr2NW3NwOqN5kCyP5hzbN5bvzPia0Q
+ wPvZowOcotDzd8E2igxRdna3hAa5UxV6BaEt
+ G/qsalYLs5Sd5n63gaMk7zD26hw= )
+ 3600 NSEC mail17.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ V4WYG/l1Peo34Q5hfm69QwRtUszRoZ2JjYdq
+ d1wQqZBoXO79SXU3TssrH77iL4hTZNxug9AC
+ MVWbr14KIok8kVgOTiHcuoD8MEvXOYldVT2n
+ PHur9u98YWUl67tIHxFJaEDllUr+F/MSphIj
+ xDE+JoILqyqQxiBplivpYQpKd54= )
+mail17.example.com. 86400 IN A 10.4.1.17
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ tP5Kusdk8U8sk73CRE5h4OzGQA5xX867rStw
+ vnmLO7QxUwnUt86iHTA0WLZ9tUSU48e1QgA3
+ sXdfsE2s9lL3RkBCOeZBbtVaEoJra4lrsQqE
+ 33/lJ2dEXinmUp8V8ndMrDZjoM2akMWqil8B
+ retyu8+6sDBRDq7DwOo6DnhXZpU= )
+ 3600 NSEC test.non-terminal.mail17.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ rLomo4w8U3IUOk3Z/VM0cq8Wf/O2w7/ZWvVx
+ a6b9nWBEfkDPkhLNHMN+bb99SMepeWKZEbNB
+ aM73aSqbebSFwdc2LLBAqQ0tN8H3ay08FEK0
+ RkZUncMkUWuAwdWePDPyy/OWllJCuMJCOP1w
+ 9fVbQTm+N8pIQGE+8VbwKb6CR1Y= )
+mail13.example.com. 86400 IN A 10.4.1.13
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ekti6VPO+1/EmlifNgbhfoQK76lcypNefc6J
+ F2TLJvWqiVAObvbLGamIu2gXtyZjY3SZtkL0
+ DN4gkao68jLi57kmqQq8QB9TYUjV3Sk9q1KF
+ T6IVYs3hMXtVftUf5F48fvY8MiciDX2ef9hI
+ DDAzlju7Xm+28VThG+4HdLGOABw= )
+ 3600 NSEC test.non-terminal.mail13.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Ofh4YmlpGvaFnSfgxt40TCB2tXJj1ni4qE/i
+ ZKO58Yk6Yhewoh9PnFu+zY1iqqiOFdkwm1p8
+ 0ZnBv8zEnBgyWlaDGlyXYaekbopPR2RCNVCz
+ zBDfTUkV/ZH/9jHW52vxuCTEXJbfyDtoMpSH
+ bpywxlsz4qUl2LsTwUXln7XWj0M= )
+test.non-terminal.mail13.example.com. 86400 IN A 10.4.1.13
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ RF1mMLuNWPr/PlRrXFMfOa5OpOzrkmpPwACm
+ K5Q31EJxO0ypnWSR09YzAkltDVutHLM6tEvF
+ 2r4kPeAPMoNe6dh30QMQp51knE6Ltcqp/2AJ
+ g4g7w2V9I0cwRnVzIvpSvZESJKKWEpjFB1qe
+ T/QwCOMDUKEKyVeQmk3/qaJbS4c= )
+ 3600 NSEC mail14.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ DTP8SAm5AK+j54fkHzEuAkWdlJ9+y3nioDsU
+ Gc+UlH0iDZJ0sw5xRbzFK/p3eO2aYbOQqyCX
+ 2J15B3KMCcUNRRe22nkHS3zEeQqY7vfo3xW9
+ U5CBg7PY2EmuZ/nwj7oP8RE21SQj7NaIC5nn
+ pej4vBhEFWqPC1fsebCp4vxil1I= )
+test.non-terminal.mail18.example.com. 86400 IN A 10.4.1.18
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ cDlI0qI//7Wy1+EE5Cd0Xvbj/mtk55jC1ZIy
+ 0m9TwV8M7vMKv7Z88w35YzpkOlZAbvZrOk4Q
+ dTXjaT1KVVW4s3zn0ZGSHjMyiZu3XeDmFJGg
+ CM8FxsrzwemZmVrWgLRkvo/iM8h+rkMM0c6F
+ xSMHyQS+cETpPCiLe6XoBtrWEpU= )
+ 3600 NSEC mail19.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ SXveX1Oea1X38bLeIwQ8XqKyeCPhiJ7VMhnm
+ sj8VCrIVAl3opZt4TeV4HhbEO8OTHORb30o0
+ ruRxRgTiIPkjiPsyJ29jSklyL6BiN32HTJGz
+ dUzNOQLaa1BVQn4Z1/vafMfABamOv1nkpdwz
+ D2xC96J2A3dfgtYcOw6Z9uH471Q= )
+mail19.example.com. 86400 IN A 10.4.1.19
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ PsTOjwnxY1kNxu7MfaFZ68LjNqq5DzFBtU6/
+ 6L6VshN9VKaP9XmlvSbj2TxWNitcK7159y1w
+ Bo8O3E1xr710wOvjeEoEt7zRBxaZKhHO+WfO
+ xpsP2d24rwaQXt61hP2rREow5DjCT0lHXUm7
+ /stCotu0+AisTQSf4UrJSQcos/U= )
+ 3600 NSEC test.non-terminal.mail19.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ lnY1TXd46C+A9ScdyYn3AZNg0h5xUk3DvKUS
+ OG5uDVgM4Ox/i2aIlAcnrtb+YlYKDTi4dZQi
+ CIoCSsvahVnB3rtkyqmNYps/wD+31FukUN4w
+ KJY1IJSSBOd9TpuOyOMVOZk4a8ewJCReJLQ7
+ fdQdaxc8wz+VIWX5m6E8I47I76Q= )
+test.non-terminal.mail19.example.com. 86400 IN A 10.4.1.19
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ rhR31JvAxtmNDYbh+BEc/7r409c4+c+54nnm
+ tUlHy8mAT6m2N55avXOvjHXCifhlChCDoToC
+ fzehwMH/PaV5BqarR4f+IESsCeXWbpgreQGp
+ pDAvFKoQSMSG6tHb/oURZz5D9Nj27hi0yW7Q
+ +0Js3qKbkzAVPi4qCAg2qCA83Fs= )
+ 3600 NSEC mail2.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ SGOyr7LJYoaqqRT44xDjqwJ7l8+3SkVZylDG
+ b1Uk4D66k2QoEb0382hXIou8OylOYFu6tKha
+ CsSL9CjDq4gP7XVar9sCwqHnRiO84cEO4TKQ
+ rWKK7aofN+N7bGJojEPMIcfMjAQyVEj0DijZ
+ Bz+vfbMr/3sGHpjwYyDfi5QOXwY= )
+mail2.example.com. 86400 IN A 10.4.1.2
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ lxfw+OaPPVMAePmo+8Tj/037dN3b9bwL7Vrq
+ eUfzJQDfXX5lcxxfUvKWZWaBYu3+SGQcA/iv
+ MfX7dU85urSeHfDrtzmL70v/ltJVv2vShg8a
+ D/WbPtACA0i7AQloTV0iRUQElwP9H+VtaI/h
+ F169y8UouYvhrxVJpkIfGsKy5bE= )
+ 3600 NSEC test.non-terminal.mail2.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ yRRrHYIrXUzNO48M6ol/YKQDsDscuCXD/ZTc
+ qhd4SjVCRYwmPa4bFWSgrZUlOLEOIBZ1EvZm
+ HYh52Hq50xhzGZp6sH9oew7jp+obrEqFgE6P
+ pcZb4pSiM0r+Jtqzs8PeNjuoC/nKXvpbN6yK
+ AMjbhKymox3kOBqGd7Bd5nKR+SY= )
+test.non-terminal.mail2.example.com. 86400 IN A 10.4.1.2
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ M98D8qNyCROc7XGZZK0wXCaU61Gvgn19ABeX
+ 8OKXt9N27a0P5khTQ2I/ANqixKdjMPTXAEtn
+ RbCLhE9m/Ffrcslb+6q7gmIquehlrSeHgovM
+ 3Z/KdPtCmn12CASmXTV+SglLjPi3zpqSGXeU
+ NVEo+1BK4/VjaA7vwFJOEGNRvjM= )
+ 3600 NSEC mail20.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ UqXAJQ0qmNqF7Pi9ugPXdlAzYEextshmHi+0
+ d8Ex7jXeMis2X62F191k7f0h6OY/sAxjbugy
+ utGhqDS37xObZIf1pIYYQrI6q2DJtU0tLLBK
+ v9V8lOEcaAya2btbevjSFYk/p0R8lsY7kjLd
+ FtqLs/ca8d/R635/bh1kuaTXZO4= )
+mail20.example.com. 86400 IN A 10.4.1.20
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ k33/p4b8hiJjrapigEjN5y19hANXjA2jOZWM
+ QLJDh15G6kTxiPIWmj0sS9+77fF01LYEO+wX
+ KFr5+EHDvYiNMqr99sjpxkKymkDem996xKSZ
+ pbH6YDRvTppF7rkL/wmG7hmO1RDwGyginyJr
+ V549ykQ6+1As5qcM1aUFwGqUWHA= )
+ 3600 NSEC test.non-terminal.mail20.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ bNuO49PAGLOyE8ACYFdaYW6QJMfP2MbCd5ct
+ M+gBo4LzsSiSkni+T+hMro142fHJiJAmYA+L
+ 3rv2+nT+DZWXplwY+AMz9KW7vATRSFlRlFfF
+ PZ1fc/TNmsauPIHARZnMxc5g3P/c09wN8n0r
+ IKp1unynOUpKKtZBGsvK2zJMwms= )
+test.non-terminal.mail20.example.com. 86400 IN A 10.4.1.20
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ AduBecIyU6OkPrmM2rpdxLm0FKPDJzw90w4z
+ 70qUdGH/hJPHg3b0kmD0WVnlbI2FNWD6juZS
+ Zd+bAriXFxxg3jIOoWthGcX7ndWqJQ4MUk1W
+ 5PeKOgyA+o+DtUBymKKS1C2G1DQmOcitWOD1
+ pOo1jawNJ8PrL7r8psS6PEv9VSA= )
+ 3600 NSEC mail3.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ NFPdkaP+u974qr1A28LJKjF1kOTF/bN1pM+W
+ J8uSC2ZuRFGrJtKYC/IgbkiaZA4wG0OiQzbv
+ 9UWu87hETfGszTPfvHhSsgQPbw0D3SVFx2MR
+ xqX2Jejet+eS/IBitiTntqUJUKTkBIcVZ57b
+ N72RUhhR6LIzd2l6HCnZWKdtISY= )
+test.non-terminal.mail17.example.com. 86400 IN A 10.4.1.17
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ T8gcprOnmnCYj+oa2agvk5UxQ1SIN46p8GvE
+ PV2+d+oLaruxIRf50Q1aCVaa3qtXa5cKZglc
+ 6OPTDykCNYPZ8Qkaqbauq9XFWEu0jEg+Ko1F
+ FWpPHKesHQjRQu9/XsJq3198aDp1JF+Od4CP
+ /3c4EF4a76jD2WHltHU+2tYPDAw= )
+ 3600 NSEC mail18.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ xSnml2cHIp7DLeiODjrm4CckTM+eGhUketW4
+ qzlptyPht+BcBY6r7QGSsD2XMd71gLLC5zFX
+ 3Ih5suA24CsXJRRf1McMaAlsLj3W/043SIE6
+ QT1l1WVRkaAYZAwlK/ZVwWvWXCzAFaMAwl0l
+ NGg4GKljzo1VKej7mxQEepfkIKU= )
+mail18.example.com. 86400 IN A 10.4.1.18
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ pgMM8YR5BN5sS2FZqHQkJTUrXI5fwIDP1K6S
+ p30INrhtV7ZzuJftLPhU9iA0+pgR4uCLKYT8
+ bzVoQOg+ISgxWkMUr1pkmEA8fQIJqakIJAp3
+ laU2Jz5Egd0ILQk/ZwhVTBDsnHC91BWaFCTd
+ u0sw5DTlEC4Jw4rd53lrROJgtSI= )
+ 3600 NSEC test.non-terminal.mail18.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ OvjZKUeOwOhFF29tGvHGlad1j7tnED8t2EFX
+ uwKw2u5e8ALW6/gI6qD5/cXlHxV/fV3Mmydo
+ Do9XZRpbRzj/+GSc01nda3hS89X/c1vdxEqh
+ KOqzmukIahWcb6OdSxabzQBxUMX3Zn6xpNeH
+ 7ZF0cuPuBbyg1+D6V12h72xtIoU= )
+mail4.example.com. 86400 IN A 10.4.1.4
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ PiMqiEaBWJ+5AX50Vx/Nt+8ZW8aX9qJ/2yTo
+ TFUWr/x+UBN4JuTIdslKRCMFUaaKRsRE6zx3
+ pN/oAwGUU4tavBiPoL4oPK7gX/DotyELK219
+ PCG2coShjUsrjEXoWs0G0Tcczf/zH1SnRkL1
+ /s3HvjZqmgPkmqGx2kjpnp4QMcY= )
+ 3600 NSEC test.non-terminal.mail4.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ zcsX93LwEFg9doHsO0wAS5EWhvQ+FoFiFRju
+ dNmipFXcoZ337K+5Q13gSW0XR8xBCMtZhNjI
+ WVxem1NbB87UOTwynp8ybHv3FqwtCzhOaCXy
+ qpVWZnrxJCyFsmWjmL654YAvO5yc/hm9NVTo
+ mLQRJmkeGXHYHdtoILaN8ZYpn44= )
+test.non-terminal.mail4.example.com. 86400 IN A 10.4.1.4
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ qI6qajPmldqEI8dtJ2aylv/j5PoTb+UD/xsw
+ lpcYvpBbk1ZJQXraWTAKvytlTf1tOswha+c+
+ +uQcUzsGKdlIO7pFIoNTbf2UciUkYzlw87bj
+ 0IqdLws0Orq7beDMRD57bxYAcocqsg7JcK+b
+ QOkx7ThU+vzO3PlqhpCPrIm+XV0= )
+ 3600 NSEC mail5.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ hyyqXEMBD0wr1EiuayMANDLRjWuWqOCJi2uD
+ s+NNfwvPzCArxkjhVG1n8Gxv7ByDiCsGj3k7
+ q0Y8cSX3XItqdmF2ltKkvpjMLmBN5OB71ahs
+ rM3nFS/hp6Kq3NQpiy3qnl+TYxKVflqHroIb
+ yMeD7xDseHZg1WelNYq5SKIOlkY= )
+mail5.example.com. 86400 IN A 10.4.1.5
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ BwjGy/pQq8wwq2oWeo8IjkZWnXmxU9F4Aiui
+ V7enbF3/e5Ls0/aNFFH1/C+BiX6ehulxCLkF
+ 8Npgg98+UMVgHEkuqcph7zHivTuArO94M4XN
+ zC0ANphLEac93//GtrZcI/QC1mIxQrC9+Kuw
+ RK5swzlI8jEWvn4Gncw0KVVsZMw= )
+ 3600 NSEC test.non-terminal.mail5.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ kFxxuuQI4s4rutL6doGHWWzh3xa56l6Q8b3n
+ OMMeh6QcAkc2POP1iK2/GAgWyymgaF5J16+f
+ qptFjboQl7XeusiFt539Xxjqd7kyE2H2m5dZ
+ WZqeoYI6jeQy4RYEaQkji+wm4w/kJ5tT2jil
+ 5pwyqkQx10xnvnx+wT52xv2Hifw= )
+test.non-terminal.mail5.example.com. 86400 IN A 10.4.1.5
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ nQ1Rf5Lhe1y+CE91nOrgW9KqRf5k5wZmp2jk
+ DuvgTJ+p3BPRXOhyVVxGwi90N4grlutXkIu3
+ I/FgibSaUSmoPQvZrmsxfwB+tckPXCYp+AP1
+ U9iLrA36lJ6vpkniV2aGfxxkxyFt8xGVWy6z
+ xlMN3OrofQ4417d0wyCMyJIsi94= )
+ 3600 NSEC mail6.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ XWNdpdSMLhscZuHwpjTOQly+5b+EeQLGkxU4
+ kB2+UmdB8t+bk0kPCC0Fn/iUDu+iVxasow2i
+ F5GDBJTtqCdfXZI4uAb0Difwsf2O8q5H2ljc
+ jSQpv56iYt36XxobLWiVe02dgixVEIoTZGQR
+ qr/nSkPSGkQZV3t92CO7bXvFtZ0= )
+mail6.example.com. 86400 IN A 10.4.1.6
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ U311WSJmd9YNtNw9VMXSApDFH2VnzY0fc09B
+ NAiQYo7Gj0NCvIAK/0bL74pZjBEg1oqSoNG2
+ QcaHA+1HY+8jvkEii1kRVAxP03BZvW2U0RoP
+ eExCk/WyNhyPf+E6rujFEjkM7BiD+43dNeX9
+ Uuw9enf9Lge1jO7oqE3c6Uc0cGw= )
+ 3600 NSEC test.non-terminal.mail6.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ oFMJmWpaSlpIZrkmW5PKp/ZEsmVtDrNYSAbr
+ gGHDUUt0+ZmVfHAX0tqTDdFg+kaKQ5J3BN1j
+ 8yAIBtMocPzefaRvI+vU628lXQvve6wezZMd
+ 0gQPURodkeSf/s85hMFhkxVx8jkapiHisxPe
+ veVdhCswAvCDhWcLToLTQyDVKoo= )
+test.non-terminal.mail6.example.com. 86400 IN A 10.4.1.6
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ hlxRsoZQnLv7Vd84GLMWWbvpeXI+WmNU/vGM
+ k7vMqloFdK5VbNiV1UU55RAszL+mfxFQiLLH
+ /bxRSxqpwaQ9n2HdnB7EfpmSk7CthVhjOMv9
+ 5C5zB4V1Zq8t3EUkoEgrXULoMRCJ5kjkHbUv
+ BuwCwvcwO8dzhy/kkfR6CU9E2OA= )
+ 3600 NSEC mail7.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ iTb4Nb6g7r6GgAMmgr7+b5eYscku9X4mhjIz
+ XjEj69qxTYjk3hDtX/eEC3SFGP7MDqqwbFH5
+ rNEO1Z4dE9o4P0D8CcYHi1hjCnQcBaYKpy8k
+ d82DaVXkxeuKPSTHBNApBL6IItcfsR5F7IYV
+ 3MIZd1DqdNNbWroZD0r9S0UZ5xI= )
+mail7.example.com. 86400 IN A 10.4.1.7
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ xq5d9fK4T5Byh0DDoU9ng3S3ODGKagJFHuGk
+ AZ7F4gaHRuu65To0mqLR7EYcpIMHT1N0qIfw
+ pig2GWtcfG8hnhM2Sg4Ecec1Spq8MnRcfEVP
+ /taJWtTc+uFPz26Ib9PBZcFEusQO0uObH1rz
+ Y/+3sI9150q2hVo/9VYQdG7Dw4M= )
+ 3600 NSEC test.non-terminal.mail7.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ eVx1EXYO0mkWdvbBM0bsPC7cyA3XmDzMSR9j
+ c+ljmJjE2tGyPJlJHoyqSrxPe+ZCLPKxMvMe
+ svILL090OysHffdCnNUHbJv5P36XrDMtP2AY
+ RhLFmQfY4z3bu1WWIEZmt9gNSwSDD0wJlS/P
+ gx9IyKwYzbYgI8RMq3A78iCnzd0= )
+test.non-terminal.mail7.example.com. 86400 IN A 10.4.1.7
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ IJUdllCwxGAuk5DFWKXf2UeJyoSU4UezntSQ
+ bKFHK2MCx6DgvfQMGkHVsQpobQGiThyW+Up5
+ UZULM85mtYzNaW2FcZ5inBgNk07+ulhBRYSV
+ yfoJMh22hvL2B9kUrq9ahdxQEXwAi2EXsx9Z
+ IqY3x1GT6sTiRr075QFGKsm533E= )
+ 3600 NSEC mail8.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ H9QW8lTHfPL9+68q1K2UDhxB+GBfvf3OHSVT
+ XGrc/ZeLRozSTdv0kgEw+fMtZEnNKjQ6FkSK
+ IT4KRjpzfgPPerFDSdPnpRLB92oexIqW+4HL
+ VyUqvndhJHQhtuI+6oUds5kKP7wtx0SJNtlM
+ FFApNNKJbNXqGSgdcMH0VX6X3xw= )
+mail3.example.com. 86400 IN A 10.4.1.3
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ HY2Bj1RiTEJ50RwIVeFIHtltIqSe0Ag8+hRV
+ 2nkT0XJyfyYJgUzmyhQZXyifwmVbA9GB+ikr
+ 48W8YExB0tz/0LKQ/7ZnAJIVeIqZNxTHH+8E
+ lTtdY0BgVb1jbGwVjMPPP2PMtHIV6js3SOKf
+ etKGzHGtwPKLJ5zJQ9JIqGLAcb0= )
+ 3600 NSEC test.non-terminal.mail3.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ dDmzEDtwj1sY+OIx45+eR//i/eXqgDTK0BvV
+ wXTGD7twq/4wJm98L0zwVf9nBWvPBVuPxbes
+ RRkYQMUDsrzbRe6nwlMOzBq8A+vkgjPg0jPf
+ XGXjf+VuBhLkfthA/zGtIbydaZD6+9GQZcuT
+ Z2PmsUcE7tLSUETrGUfzWLUx+N0= )
+test.non-terminal.mail3.example.com. 86400 IN A 10.4.1.3
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ WK8oxOqRtx+WvmlPwLqzk9cg4i/edlo9Q18m
+ c3WSKOcl8k9PIsGLdmR15S/0FwPE8RAwZj5V
+ ivNvD1jZPji4FUd5uqDOIIEf8I7h/oJXtICt
+ fuHXBta451J9hHax2CQsbdRAmgOPePKumLjE
+ DjWcuIDlwd5fUUWlSNJXGgaGqB4= )
+ 3600 NSEC mail4.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ JlLVYj66GZBi5EzNOj+dNuNbhAzNfETJEM+v
+ HEKoxHIMQycdQIE+qIRnslLTOiS+mGcNqvuM
+ QwDh/pX0T/aJfv2iNavo6Kteo1mFqjC6WdlA
+ dwKHgGQUaFpITdhlLdoloBljJ+s8qf0XQu51
+ prk95kMz7J+P5HDfISD1NUiM2CQ= )
+mail9.example.com. 86400 IN A 10.4.1.9
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ilueEhVsd566HjAQ9OKBjKllUmR34IIsUt+d
+ gDJHfac3bkLpoFTaONpUWHFzzGdMk+1qJz1h
+ 1JUlaJhUBZaAVS1YmTtnVhtEe0ir8RlJWDti
+ Jps6xnL0NnWUJn9OHVHyi+4bpewBuCRCL1oN
+ G53y0Ie2BtaQ0gKfxOv81i7PZoA= )
+ 3600 NSEC test.non-terminal.mail9.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ lOFQtp7jpHPGoWz9OzviTsXFBHUQs244Gvh4
+ p4DTipDsg0RaQiyK9klKigNabJh2j5hrt+lx
+ q/bvlur6lfUijW593HWEAgCck8wQrHPgg3HE
+ vxwBrxIbueuxuxOT6QOYH6lBzzG4HDf6LSFM
+ +zCoYsYXXtbEI7rxqcd/WieiFqM= )
+test.non-terminal.mail9.example.com. 86400 IN A 10.4.1.9
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ FVGEqnhagAxIPSX0Nim/AR7ePP5GwBEnvCsu
+ oRpgnIgpCcBKJrKPqlF/aOF4/dFtysXvbQCW
+ Tt0MSFEfQsDFcVOj6bQ/jZq4oAvZW/TBG7na
+ z0J4pTckegIPzuzVso+PtLHbONxu5Ts+IyyO
+ Ble0Jz86L58IamZKXRHlYkV4LOk= )
+ 3600 NSEC minittl.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Tj6rYC12mMnPrPa2wDOp09e9cuByqjvO+y1i
+ riH51BzIMDEUEeaDYCQfPWnJtReNPOoxjeA1
+ 4RQbyLtv40A8Wylwq5U3lHrHO5iB4hWTm/Qe
+ vhbzdmrxPYKWhZUgamb22UMY/mPk5O9iMeQA
+ adOVtlQr+vxZHLfP9st/M5FD464= )
+minittl.example.com. 100 IN A 10.10.1.1
+ 100 RRSIG A 5 3 100 20110408061651 (
+ 20110309061651 27366 example.com.
+ Mf8cekGVYrEFZW3FXsta3pbcxONMxlfpxveF
+ yvKxd4RmEa3a+LW7AANsVSCLXdret4r1hFcE
+ +Cz6XSw+HcIcF+3tvcQRqpHbtu+ZBZVafIHc
+ jlvCpw8vaGr9TL9+KiFSPxZvh7f65vd7oUlR
+ 0IJfkPLsRiKLq0TFwooxXX48w0s= )
+ 3600 NSEC test.non-terminal.minittl.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ sbqJlXF9wG3NiLwQFhKu+LCEx5E/S567MXwU
+ l4845BDvl2xUr+UK35xIVrAzbKk8baYtc6Ad
+ YFEx7CAE6wc++U8WdON4ZZtMaFt9v4ckBAAm
+ /El1zvZ6LhzhkzQTtt8fx++g7iUfNRfJeuBw
+ iVe00wSg1cRchlP4B0QtaNw37nI= )
+test.non-terminal.minittl.example.com. 100 IN A 10.10.1.1
+ 100 RRSIG A 5 5 100 20110408061651 (
+ 20110309061651 27366 example.com.
+ LwMLnZZyz34kJ8AstokH/TxMvAGtaOO04D3J
+ 2k5HauNrJCtluPYbDELm+b7ngEc/wOsHhu5c
+ PPdWRWrmhUCz/sEcw0W0MD6lgEVd57GTEAim
+ W7gEDp6EcQt9f2g9LUxuGS4g9YoeHucENI+n
+ swfDBEypCOzz22ajeqic37jgiqA= )
+ 3600 NSEC multiple-type-a-record.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Fy9D+zHXn4q5C3Ypa+oYjOwAD/SyI7PW/AWC
+ WlbPBIYIeDMWfToE2FNahRpV448K+D9QGsyK
+ rpQCGqyZoK4VGw+SMvmwIowQ0kP3vfS9kjLM
+ bGtd2ZZo894qa1AwHMjfC6HJKSfg117l+Rfb
+ rQR1g2B9dSq8vTRMHPBFhEMqZRE= )
+multiple-type-a-record.example.com. 86400 IN A 192.168.2.1
+ 86400 IN A 192.168.2.2
+ 86400 IN A 192.168.2.3
+ 86400 IN A 192.168.2.4
+ 86400 IN A 192.168.2.5
+ 86400 IN A 192.168.2.6
+ 86400 IN A 192.168.2.7
+ 86400 IN A 192.168.2.8
+ 86400 IN A 192.168.2.9
+ 86400 IN A 192.168.2.10
+ 86400 IN A 192.168.2.11
+ 86400 IN A 192.168.2.12
+ 86400 IN A 192.168.2.13
+ 86400 IN A 192.168.2.14
+ 86400 IN A 192.168.2.15
+ 86400 IN A 192.168.2.16
+ 86400 IN A 192.168.2.17
+ 86400 IN A 192.168.2.18
+ 86400 IN A 192.168.2.19
+ 86400 IN A 192.168.2.20
+ 86400 IN A 192.168.2.21
+ 86400 IN A 192.168.2.22
+ 86400 IN A 192.168.2.23
+ 86400 IN A 192.168.2.24
+ 86400 IN A 192.168.2.25
+ 86400 IN A 192.168.2.26
+ 86400 IN A 192.168.2.27
+ 86400 IN A 192.168.2.28
+ 86400 IN A 192.168.2.29
+ 86400 IN A 192.168.2.30
+ 86400 IN A 192.168.2.31
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ YT07B2OmuwkPtDW5FUPj4iy7ucdoTKahQKWT
+ 8KGn9vGwdbVLZXQ0L0rtvv7SO6SiDsYbDmEX
+ MxCp5Ecs58A0FCpIPhP9yKhPOLHA2UKMAch3
+ FfdujPf7SK0P/TxE2l1zQ2wF7pD/dUuV3DLf
+ uCuIetcVYC7AYJy8xQKi951ubYg= )
+ 3600 NSEC test.non-terminal.multiple-type-a-record.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ d6wmda+yHwrLO6zvpOxegvusUWmIwW/QqPwi
+ dLc6+IcunjlFPd6/fiHa9SThJv+Dh9rssiFQ
+ iLpi7tO7sPZlDdmJoXJMXlV0zapSs9ACxdiY
+ vWDbZfFcGdCeN2/FqjqCQ6WnCnFf+R4ahGTx
+ KJkcsKfPVAYSbDuDItUZ13yxPq4= )
+test.non-terminal.multiple-type-a-record.example.com. 86400 IN A 192.168.2.1
+ 86400 IN A 192.168.2.2
+ 86400 IN A 192.168.2.3
+ 86400 IN A 192.168.2.4
+ 86400 IN A 192.168.2.5
+ 86400 IN A 192.168.2.6
+ 86400 IN A 192.168.2.7
+ 86400 IN A 192.168.2.8
+ 86400 IN A 192.168.2.9
+ 86400 IN A 192.168.2.10
+ 86400 IN A 192.168.2.11
+ 86400 IN A 192.168.2.12
+ 86400 IN A 192.168.2.13
+ 86400 IN A 192.168.2.14
+ 86400 IN A 192.168.2.15
+ 86400 IN A 192.168.2.16
+ 86400 IN A 192.168.2.17
+ 86400 IN A 192.168.2.18
+ 86400 IN A 192.168.2.19
+ 86400 IN A 192.168.2.20
+ 86400 IN A 192.168.2.21
+ 86400 IN A 192.168.2.22
+ 86400 IN A 192.168.2.23
+ 86400 IN A 192.168.2.24
+ 86400 IN A 192.168.2.25
+ 86400 IN A 192.168.2.26
+ 86400 IN A 192.168.2.27
+ 86400 IN A 192.168.2.28
+ 86400 IN A 192.168.2.29
+ 86400 IN A 192.168.2.30
+ 86400 IN A 192.168.2.31
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ iYwlsJGf+LDo9qHyfQbjh6+fEqliq7qTyiFB
+ aUdSRT/RHoJ2dWXxrkxxJ2uo5xMnVyKxlfHT
+ mXXwUSrUU1Swfi3ROh7n4+9P+T8Z9wvmTLSp
+ VBDIyn98uKqacA4Oyj5TOLUuu1hHRfqJ5lfM
+ O1Aml9wQ/MMtPr9XjiK99+dHnPg= )
+ 3600 NSEC multiple-type-aaaa-record.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ a6PDPkS1fCfOwM5+GDtEdRK9MfR9bgd4NMj0
+ Hnb5ZdIX+aRUrEykFGvhdKHmoae4nvagOLfC
+ rd0fMCZJqia4JLOh6b4Z52qf/yDyraceadFF
+ A7bcrLFCdKcumJqUZMs1XEkBuIdThtcHG/S9
+ VtRbtoeVIGCrHj1cA2seUFM1RZ0= )
+multiple-type-aaaa-record.example.com. 86400 IN AAAA aaaa::1
+ 86400 IN AAAA aaaa::2
+ 86400 IN AAAA aaaa::3
+ 86400 IN AAAA aaaa::4
+ 86400 IN AAAA aaaa::5
+ 86400 IN AAAA aaaa::6
+ 86400 IN AAAA aaaa::7
+ 86400 IN AAAA aaaa::8
+ 86400 IN AAAA aaaa::9
+ 86400 IN AAAA aaaa::10
+ 86400 IN AAAA aaaa::11
+ 86400 IN AAAA aaaa::12
+ 86400 IN AAAA aaaa::13
+ 86400 IN AAAA aaaa::14
+ 86400 IN AAAA aaaa::15
+ 86400 IN AAAA aaaa::16
+ 86400 IN AAAA aaaa::17
+ 86400 IN AAAA aaaa::18
+ 86400 IN AAAA aaaa::19
+ 86400 IN AAAA aaaa::20
+ 86400 IN AAAA aaaa::21
+ 86400 IN AAAA aaaa::22
+ 86400 IN AAAA aaaa::23
+ 86400 IN AAAA aaaa::24
+ 86400 IN AAAA aaaa::25
+ 86400 IN AAAA aaaa::26
+ 86400 IN AAAA aaaa::27
+ 86400 IN AAAA aaaa::28
+ 86400 IN AAAA aaaa::29
+ 86400 IN AAAA aaaa::30
+ 86400 IN AAAA aaaa::31
+ 86400 RRSIG AAAA 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ x8x8CvwAHG+JZBh9u2x/0DaiiP94QpQZGhXM
+ jTbtwBMphbStQ7nic1hj6PbAf9lD+aS5hYuo
+ vUc4Ef1wCUdvQ7bzzgFPChzWJ1cMQf+qD8OX
+ pUYUbMklFReEIOA6M/0qeD4XaWuq4NedHTVF
+ Kks4D2u5QBHksqAFguW+k23I8uE= )
+ 3600 NSEC test.non-terminal.multiple-type-aaaa-record.example.com. AAAA RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ hnQieVeyJETv0V8rau8a8CXJuALihgviFDAj
+ EctzT7D+97HFGkmQJuwoTIIZMl65AlV4p/tP
+ dDoT0FnjahNeA/+ifEGqpSb5nM4J46SipBEl
+ yc7gXwYvF3VzthY1JtXFIwz6/EhIj9Ypoh3H
+ dtRVcSwNe9Ts1LQen4MJGXojlis= )
+test.non-terminal.multiple-type-aaaa-record.example.com. 86400 IN AAAA aaaa::1
+ 86400 IN AAAA aaaa::2
+ 86400 IN AAAA aaaa::3
+ 86400 IN AAAA aaaa::4
+ 86400 IN AAAA aaaa::5
+ 86400 IN AAAA aaaa::6
+ 86400 IN AAAA aaaa::7
+ 86400 IN AAAA aaaa::8
+ 86400 IN AAAA aaaa::9
+ 86400 IN AAAA aaaa::10
+ 86400 IN AAAA aaaa::11
+ 86400 IN AAAA aaaa::12
+ 86400 IN AAAA aaaa::13
+ 86400 IN AAAA aaaa::14
+ 86400 IN AAAA aaaa::15
+ 86400 IN AAAA aaaa::16
+ 86400 IN AAAA aaaa::17
+ 86400 IN AAAA aaaa::18
+ 86400 IN AAAA aaaa::19
+ 86400 IN AAAA aaaa::20
+ 86400 IN AAAA aaaa::21
+ 86400 IN AAAA aaaa::22
+ 86400 IN AAAA aaaa::23
+ 86400 IN AAAA aaaa::24
+ 86400 IN AAAA aaaa::25
+ 86400 IN AAAA aaaa::26
+ 86400 IN AAAA aaaa::27
+ 86400 IN AAAA aaaa::28
+ 86400 IN AAAA aaaa::29
+ 86400 IN AAAA aaaa::30
+ 86400 IN AAAA aaaa::31
+ 86400 RRSIG AAAA 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ szXkzygL5I0RgjQ9CEDYm0yeFS0bpwk1EgO7
+ cYnf2i9PxX5npLk9WRZVLsFLsHmj2eRgXvsb
+ AADYxOzSwdEIZeqBgsy7Eoee8qYntoSpXOM0
+ QqyVKp/4pVP3JAW9a+j6SyjboR2dXJFY/9XG
+ Ox8BkwtrlAsW5/2tLT8mD9jfjYk= )
+ 3600 NSEC multiple-type-apl-record.example.com. AAAA RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ DjrQLbKKPBy1hB8LWgIO8BlFonO2LktUIigM
+ wTmzaWMgAgiKaw3BHZwYsbKzP0BqAb5FcS92
+ 9R6rx7yvd1x3ykx0AjctR1Teno8yqenlErNr
+ eY/0aU1PLgnnnqGMJEc/Kv0vuQfqWrzJDXDH
+ Vz0SIfn56DArnR/+k/BD/OfD3yg= )
+mail8.example.com. 86400 IN A 10.4.1.8
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ oOjuOj5G4jOjwHN2NRy7j+jpbsDF+bw5sVjn
+ UKSi+WENwlhZODEtJENVVoRB1ri7B47w3JV4
+ GagwVUWVeYmbalk38hRtKD1Ak9C2o1cAyv+p
+ BR3YazWd7mYqxhdvu/n2E4D7IB5+MUSZ2LUT
+ YPnrsCta+BfEobMTA8kUplMj6XA= )
+ 3600 NSEC test.non-terminal.mail8.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ yCUwmQfvAQblEsFsNiPxnhCVKhjjZTeBFLPN
+ cES2e3gA6cy23sHmujvkSsUhl04ZceNmqZE8
+ UzZL5YFNemGy+GHAOnvY03L+4d52pAIsH/33
+ OC8KmOAPXySnMvAkIF4nv32gJIuCjB5Qn1LU
+ IlxyAMSe7ZOaxfcc9d5AvkA0xKA= )
+test.non-terminal.mail8.example.com. 86400 IN A 10.4.1.8
+ 86400 RRSIG A 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ MuQ87eA65dY5dqnUVkoau0U0AMOYEPDciAmm
+ oULk/zlvcHpPuxEcHh0oIB3jvzYIc4BqXDyJ
+ fc7JKXhwWJnVI9A4AkUNebdfPA+WkR/LtOpE
+ 8lmu2gPxRWdkWuDflmE/e6xuPoK5oTz0see4
+ vGgzEEYtuK2PNJo2WoJQL4jVfps= )
+ 3600 NSEC mail9.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ z0uNfSHz4i4TJhgEkY8QWkDu+Nqa/ngzQ3rZ
+ 7SWCVhMQxROnFSF6l9U67oxzariVRobR0Bt4
+ sv/ufpa3j68bm28B1JjbZEUkIVteAtu2mSgN
+ s9jfb2c/NVdacVX/qtr8d/9boq426im3OvEq
+ bEsv4DbQTyzTjQIBFJmfztZ7AIE= )
+multiple-type-cert-record.example.com. 86400 IN CERT 65534 65535 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45Ik
+ skceFGgiWCn/GxHhai6VAuHAoNUz4YoU1tVf
+ SCSqQYn6//11U6Nld80jEeC8aTrO+KKmCaY= )
+ 86400 IN CERT 65533 65534 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45Ik
+ skceFGgiWCn/GxHhai6VAuHAoNUz4YoU1tVf
+ SCSqQYn6//11U6Nld80jEeC8aTrO+KKmCaY= )
+ 86400 IN CERT 65532 65533 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45Ik
+ skceFGgiWCn/GxHhai6VAuHAoNUz4YoU1tVf
+ SCSqQYn6//11U6Nld80jEeC8aTrO+KKmCaY= )
+ 86400 IN CERT 65531 65532 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45Ik
+ skceFGgiWCn/GxHhai6VAuHAoNUz4YoU1tVf
+ SCSqQYn6//11U6Nld80jEeC8aTrO+KKmCaY= )
+ 86400 IN CERT 65530 65531 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45Ik
+ skceFGgiWCn/GxHhai6VAuHAoNUz4YoU1tVf
+ SCSqQYn6//11U6Nld80jEeC8aTrO+KKmCaY= )
+ 86400 RRSIG CERT 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ xQoPoH5wwAOIiZspU1WKMKdO4QoVyW0BolZX
+ 5Tdi7VW/tD/HYBJsJ6qm+YsfMEs4gMFjkUTy
+ oxIMi14lDk4CvKV7g6jpn1XReRJQHM4sFrcN
+ /Rnr7xLWQicNi3jCIdHwQiGAon/ld9+dhQwi
+ P/DffsAYU8XHCnrB+vBUF1bGSlA= )
+ 3600 NSEC test.non-terminal.multiple-type-cert-record.example.com. CERT RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Q6w8eQLJK6pucvBPhxcDis2mEmPfH0cvzFvy
+ Rq37BEk3qPqE9VzvnMlWOfcR0D/f1zychP0y
+ PwSxRSX56+IiBnAUczMMI1ESiy0CMpWFI8Cw
+ kuJeVcDlBbqzgK6T6aRs08dwfos9V2WcQczt
+ um4kDs1iP6hu95xoIXOD5AaF23c= )
+test.non-terminal.multiple-type-cert-record.example.com. 86400 IN CERT 65534 65535 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45Ik
+ skceFGgiWCn/GxHhai6VAuHAoNUz4YoU1tVf
+ SCSqQYn6//11U6Nld80jEeC8aTrO+KKmCaY= )
+ 86400 IN CERT 65533 65534 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45Ik
+ skceFGgiWCn/GxHhai6VAuHAoNUz4YoU1tVf
+ SCSqQYn6//11U6Nld80jEeC8aTrO+KKmCaY= )
+ 86400 IN CERT 65532 65533 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45Ik
+ skceFGgiWCn/GxHhai6VAuHAoNUz4YoU1tVf
+ SCSqQYn6//11U6Nld80jEeC8aTrO+KKmCaY= )
+ 86400 IN CERT 65531 65532 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45Ik
+ skceFGgiWCn/GxHhai6VAuHAoNUz4YoU1tVf
+ SCSqQYn6//11U6Nld80jEeC8aTrO+KKmCaY= )
+ 86400 IN CERT 65530 65531 PRIVATEOID (
+ MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45Ik
+ skceFGgiWCn/GxHhai6VAuHAoNUz4YoU1tVf
+ SCSqQYn6//11U6Nld80jEeC8aTrO+KKmCaY= )
+ 86400 RRSIG CERT 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ OZzzum87ApOeJSFbd7wDbmr4iY/3iAKbh8RQ
+ UNJDBPwHj8KbJlttJ9gmjToSyk3P7SrbS7U7
+ Pk/2i38keOWZVW9ivcksmt0ghx2x3I1FP63g
+ aH8ch+7Xhuh5Jchg0Kce1+5mXpVu+j22qfPQ
+ 1cPyG/Ret1LaUhrSkXMzsPAMbCc= )
+ 3600 NSEC multiple-type-dhcid-record.example.com. CERT RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ WopCB1qLP8JM8dH0Rg7ahT5KpZ1PrkjfzQTd
+ okVyD/OeeIuA0AtUZ92DqMvUu3HfHHp/Dt52
+ ROAavolZh7nXqULc770QeysyeHvBOjY+H0F5
+ yZCjUKFm8GH0+1LPQsYnZTE8yrCNWflb6qTk
+ saBhkD1SnfAaLkY9fjCQRcXvZ3g= )
+multiple-type-dhcid-record.example.com. 3600 IN NSEC test.non-terminal.multiple-type-dhcid-record.example.com. RRSIG NSEC DHCID
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ IrzmyShLB6KgAaQAz5AOWMBW8Ww74oWgoWry
+ DP89FY0GOn8RdXfeBGTNVCLuZO46l6JBdcYz
+ 0YRoSp2EsfUzcEP7ykNpKdUiIt8cu3bO//w6
+ jViWdm7O5yWvGVgk03o6xJMqsSsqqXXx07PC
+ s8oICZkWDc/ivWe9EZm+N/nCoxo= )
+ 86400 DHCID ( AAIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 35 0 32
+ 86400 DHCID ( BBIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 35 0 32
+ 86400 DHCID ( CCIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 35 0 32
+ 86400 DHCID ( DDIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 35 0 32
+ 86400 DHCID ( EEIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 35 0 32
+ 86400 DHCID ( FFIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 35 0 32
+ 86400 DHCID ( GGIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 35 0 32
+ 86400 DHCID ( HHIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 35 0 32
+ 86400 DHCID ( IIIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 35 0 32
+ 86400 DHCID ( JJIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 35 0 32
+ 86400 DHCID ( KKIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 48755 116 32
+ 86400 RRSIG DHCID 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ zFbrcp3DpDdFEj6IWGhneuND7eyaKu+2Sx15
+ ol0dEX8HlFqmojg95PruZxCO/iUlT0azgfEc
+ zAmztRiVU/YSCW6JjMb/7t8BU9XvISyMQvqB
+ IQjKKtmkHBz4QkZOp+KhDG2u1lCXNsx6SNNd
+ TI0MBFI2uOs6r8SvwVVyaKT+9Yc= )
+test.non-terminal.multiple-type-dhcid-record.example.com. 3600 IN NSEC multiple-type-hinfo-record.example.com. RRSIG NSEC DHCID
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ D2ft8CG25E0aXD1OQUvZAyQwEUwrgQwubVc2
+ 745OhUK74XrisajtydaXeo1lcY63/YugBhMn
+ fbOO7dAdmsA5PcUmEUN6YPF64F9fci4SBmoh
+ I2VMWpQl5wDGMJJlCTh//UsYMgVxitsf2ilr
+ /d4c5zpd4KWZiCMx7va4MgAUyoo= )
+ 86400 DHCID ( AAIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 35 0 32
+ 86400 DHCID ( BBIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 35 0 32
+ 86400 DHCID ( CCIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 35 0 32
+ 86400 DHCID ( DDIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 35 0 32
+ 86400 DHCID ( EEIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 35 0 32
+ 86400 DHCID ( FFIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 35 0 32
+ 86400 DHCID ( GGIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 35 0 32
+ 86400 DHCID ( HHIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 35 0 32
+ 86400 DHCID ( IIIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 35 0 32
+ 86400 DHCID ( JJIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 35 0 32
+ 86400 DHCID ( KKIBY2/AuCccgoJbsaxcQc9TUapptP69lOjx
+ fNuVAA2kjEA= ) ; 48712 84 32
+ 86400 RRSIG DHCID 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ lY/VinZHODSBjAKVarQgP6t/W6ELmy8nrFN5
+ MmAxDY7hEniet6b9Pj2ZfJwXuxCLCaBjK533
+ CflXFrMUhRQ2ou0cROzx5SYFaHvXjkTYBNjx
+ 1Wyq9/oymCoR7wvWC8oVnQ19C+xn6bQaJqMK
+ ALeaYlArNpnRFCba8Y6rXBLWFOw= )
+multiple-type-hinfo-record.example.com. 86400 IN HINFO "DG MV-4000" "1990"
+ 86400 IN HINFO "DG MV-4001" "1990"
+ 86400 IN HINFO "DG MV-4002" "1990"
+ 86400 IN HINFO "DG MV-4003" "1990"
+ 86400 IN HINFO "DG MV-4004" "1990"
+ 86400 IN HINFO "DG MV-4005" "1990"
+ 86400 IN HINFO "DG MV-4006" "1990"
+ 86400 IN HINFO "DG MV-4007" "1990"
+ 86400 IN HINFO "DG MV-4008" "1990"
+ 86400 IN HINFO "DG MV-4009" "1990"
+ 86400 IN HINFO "DG MV-4010" "1990"
+ 86400 IN HINFO "DG MV-4011" "1990"
+ 86400 IN HINFO "DG MV-4012" "1990"
+ 86400 IN HINFO "DG MV-4013" "1990"
+ 86400 IN HINFO "DG MV-4014" "1990"
+ 86400 IN HINFO "DG MV-4015" "1990"
+ 86400 IN HINFO "DG MV-4016" "1990"
+ 86400 RRSIG HINFO 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ UwdNrH/kb403kMqM5iogfB1a0VrA77U/kqEc
+ kyUgUuOmX4rDM7n4de2ZF8/llmqqM0bGBoiS
+ CjqpxIiflbq56pLEgWC4GmzoSIKtWZOKepZJ
+ QYS9zjAEr8r65S64XtrBSCC9bSEHrPVVl0GD
+ lHJLWBBs/8bPkOFevrbIHOjrmAg= )
+ 3600 NSEC test.non-terminal.multiple-type-hinfo-record.example.com. HINFO RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ wxkUhmJ2GrC/KbBuuaLO2AcSm7dprDcbbBmJ
+ BmxuJ4QDjp1PCWbhzo3GlAcQ83zDbi2JQMWS
+ XFq3/6SJCJ0U0K5F6mSVd0MKJgcbHBvMUdIj
+ 46FxLCRjDjN3+Ej2A6egcmVcVxbmolVcbwS7
+ jLm/xMZHUHFs8sIuCJGDyZLFBns= )
+test.non-terminal.multiple-type-hinfo-record.example.com. 86400 IN HINFO "DG MV-4000" "1990"
+ 86400 IN HINFO "DG MV-4001" "1990"
+ 86400 IN HINFO "DG MV-4002" "1990"
+ 86400 IN HINFO "DG MV-4003" "1990"
+ 86400 IN HINFO "DG MV-4004" "1990"
+ 86400 IN HINFO "DG MV-4005" "1990"
+ 86400 IN HINFO "DG MV-4006" "1990"
+ 86400 IN HINFO "DG MV-4007" "1990"
+ 86400 IN HINFO "DG MV-4008" "1990"
+ 86400 IN HINFO "DG MV-4009" "1990"
+ 86400 IN HINFO "DG MV-4010" "1990"
+ 86400 IN HINFO "DG MV-4011" "1990"
+ 86400 IN HINFO "DG MV-4012" "1990"
+ 86400 IN HINFO "DG MV-4013" "1990"
+ 86400 IN HINFO "DG MV-4014" "1990"
+ 86400 IN HINFO "DG MV-4015" "1990"
+ 86400 IN HINFO "DG MV-4016" "1990"
+ 86400 RRSIG HINFO 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ gkoYkqVsjRqPFQx8a5B42+kidExzFOoEup9r
+ 9q/V/xtxx+z8T84u/qXxwLwKgLoYGBafVH2+
+ 0XJLQ/Gg7pJK2CeWAoDElKmeLSl7VB3epvxe
+ KfFIWl9kOjakoDkaEPc6XE3Yo/JouelyGj3Z
+ LqHYXHA7xozZYw+K5cLqsMTNqjU= )
+ 3600 NSEC multiple-type-ipseckey-record.example.com. HINFO RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ z+pbp+klFIu5h22skrEjRFJV3P9c8cmUx2aX
+ fLRUl4XMUf6hYrQl+4zuMp2OwS3UnMY+mGQC
+ G/PnbvoFbc7kemyaYtJXbs4CpE1mk3FlSzbW
+ Rowb7K7gy9S+P88b/SLgJvV5V0cZLbp1UqV7
+ mewGUQFsc7JSXZZzko8QyDsW8D4= )
+multiple-type-apl-record.example.com. 86400 IN APL 1:192.168.32.15/14 !1:192.168.38.0/28
+ 86400 IN APL 1:192.168.33.15/15 !1:192.168.39.0/28
+ 86400 IN APL 1:192.168.34.15/16 !1:192.168.40.0/28
+ 86400 IN APL 1:192.168.35.15/17 !1:192.168.41.0/28
+ 86400 IN APL 1:192.168.36.15/18 !1:192.168.42.0/28
+ 86400 IN APL 1:192.168.37.15/19 !1:192.168.43.0/28
+ 86400 IN APL 1:192.168.38.15/20 !1:192.168.44.0/28
+ 86400 IN APL 1:192.168.39.15/21 !1:192.168.45.0/28
+ 86400 IN APL 1:192.168.40.15/22 !1:192.168.46.0/28
+ 86400 IN APL 1:192.168.41.15/23 !1:192.168.47.0/28
+ 86400 IN APL 1:192.168.42.15/24 !1:192.168.48.0/28
+ 86400 IN APL 1:192.168.43.15/25 !1:192.168.49.0/28
+ 86400 IN APL 1:192.168.44.15/26 !1:192.168.50.0/28
+ 86400 IN APL 1:192.168.45.15/27 !1:192.168.51.0/28
+ 86400 IN APL 1:192.168.46.15/28 !1:192.168.52.0/28
+ 86400 IN APL 1:192.168.47.15/29 !1:192.168.53.0/28
+ 86400 IN APL 1:192.168.48.15/20 !1:192.168.54.0/28
+ 86400 IN APL 1:224.0.0.0/4 2:ff00::aaaa:cccc:bbbb:9999:5555/48
+ 86400 IN APL 1:224.0.0.5/8 2:ff00::/8
+ 86400 IN APL 1:224.0.0.9/12 2:ff00::888f:0/24
+ 86400 IN APL 1:224.0.0.13/16 2:ff00::7777/72
+ 86400 RRSIG APL 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ aehwZTTprSc6w/FDMjLqB574zGk5TMjPpKw9
+ XPUJ2oH2BvAffjSolgd96+3DdrcRnn/8WxUB
+ NxJGGfRldaWrpz1/2Kyh+H1/b/neo30pAHn7
+ yM6Ikl9INciVjk7iubLA0jC42szWDywaGPRm
+ GxaxZrcdNU1m+76HG+X5z7/qtyw= )
+ 3600 NSEC test.non-terminal.multiple-type-apl-record.example.com. APL RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ BLMYiCErePflhN13zVr9H4ixeq1EC/m1/Igd
+ c3cthuQ3YRbYylhmJ1Y/3FBJyjnExM3JVPlg
+ 0v+kgG34F1i9QzItAKk03VNWwSSxuW3wLRhD
+ 7m0KlyactIGcn4PzzQUbcLNuvApiphJb5EDT
+ Wd9TAvhZchgdsbcB2SJTEypHPYM= )
+test.non-terminal.multiple-type-apl-record.example.com. 86400 IN APL 1:192.168.32.15/14 !1:192.168.38.0/28
+ 86400 IN APL 1:192.168.33.15/15 !1:192.168.39.0/28
+ 86400 IN APL 1:192.168.34.15/16 !1:192.168.40.0/28
+ 86400 IN APL 1:192.168.35.15/17 !1:192.168.41.0/28
+ 86400 IN APL 1:192.168.36.15/18 !1:192.168.42.0/28
+ 86400 IN APL 1:192.168.37.15/19 !1:192.168.43.0/28
+ 86400 IN APL 1:192.168.38.15/20 !1:192.168.44.0/28
+ 86400 IN APL 1:192.168.39.15/21 !1:192.168.45.0/28
+ 86400 IN APL 1:192.168.40.15/22 !1:192.168.46.0/28
+ 86400 IN APL 1:192.168.41.15/23 !1:192.168.47.0/28
+ 86400 IN APL 1:192.168.42.15/24 !1:192.168.48.0/28
+ 86400 IN APL 1:192.168.43.15/25 !1:192.168.49.0/28
+ 86400 IN APL 1:192.168.44.15/26 !1:192.168.50.0/28
+ 86400 IN APL 1:192.168.45.15/27 !1:192.168.51.0/28
+ 86400 IN APL 1:192.168.46.15/28 !1:192.168.52.0/28
+ 86400 IN APL 1:192.168.47.15/29 !1:192.168.53.0/28
+ 86400 IN APL 1:192.168.48.15/20 !1:192.168.54.0/28
+ 86400 IN APL 1:224.0.0.0/4 2:ff00::aaaa:cccc:bbbb:9999:5555/48
+ 86400 IN APL 1:224.0.0.5/8 2:ff00::/8
+ 86400 IN APL 1:224.0.0.9/12 2:ff00::888f:0/24
+ 86400 IN APL 1:224.0.0.13/16 2:ff00::7777/72
+ 86400 RRSIG APL 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ FDKSvC1Hlgc+duM5wdWPDAjmqdJgxv22pHhI
+ xxHh6Y75VPi1zockKHZ/L9vMVm6kTtp697/h
+ UjnY2zzD104gUX1NPJPfuUJg8bdhd+r56zpc
+ uRPeBZI9EXvSXkmdmnIHtCv9Pq0wR5mOZSp1
+ zUeyUnR8GJUH+cKraS45IW7mwJ0= )
+ 3600 NSEC multiple-type-cert-record.example.com. APL RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ wlrUQ2kurNfp9VNdmGudUuLx0GbQAgEHyh9V
+ ABZDLzzEZy6ioJ71evrUa3ra3XoCb5/dg/MP
+ aOpGeD++ohZ6XOTmDEygH6ZxQflVLAuevBGN
+ XfmrZxpEAX4Ff9EecEnW8Esw3a1bUs7Pt8e4
+ DPUEN++I9FnGZ/6AETeoQJbqKns= )
+test.non-terminal.multiple-type-kx-record.example.com. 86400 IN KX 0 kaku0.google.com.
+ 86400 IN KX 10 kaku1.google.com.
+ 86400 IN KX 20 kaku2.google.com.
+ 86400 IN KX 30 kaku3.google.com.
+ 86400 IN KX 40 kaku4.google.com.
+ 86400 IN KX 50 kaku5.google.com.
+ 86400 IN KX 60 kaku6.google.com.
+ 86400 IN KX 70 kaku7.google.com.
+ 86400 IN KX 80 kaku8.google.com.
+ 86400 IN KX 90 kaku9.google.com.
+ 86400 IN KX 100 kaku10.google.com.
+ 86400 IN KX 110 kaku11.google.com.
+ 86400 IN KX 120 kaku12.google.com.
+ 86400 IN KX 130 kaku13.google.com.
+ 86400 RRSIG KX 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ K4xlhr1K6jZ/6wNo4FFN/gKSMRWeC5UD1J3T
+ inMvzeTwWLHM7u4HvNB/uqqM6d6w/clp2bx4
+ YG51yG8w9yZSMWLeqdbgMrvi3PojR4GQRGAM
+ y+27D8ocGPuZfd0tGIJ6rKHxoFlwTKJ/0lKQ
+ Hy+mN8DszNIexzJGGD9j5VYgGAM= )
+ 3600 NSEC multiple-type-loc-record.example.com. KX RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ nGn1/sPftbUJ8K4cmAW4yzVfjphyNDt9rQWT
+ B4Ut+I0llInvc+4qShem8orJzmTbH6gi4mJj
+ Kn96n5X9yvbrFby5ptwHcOVokn/rzlYpV+0m
+ 4G2wlMVAfzFts0gJ54nKUmUmIzYETLduYPX+
+ Aq0HzuZbMIRCMOLK6wBI+f9QTWQ= )
+multiple-type-loc-record.example.com. 86400 IN LOC 32 7 19.000 S 116 2 25.000 E 10.00m 1m 10000m 10m
+ 86400 IN LOC 33 7 19.000 S 117 2 25.000 E 11.00m 1m 10000m 10m
+ 86400 IN LOC 34 7 19.000 S 118 2 25.000 E 12.00m 1m 10000m 10m
+ 86400 IN LOC 35 7 19.000 S 119 2 25.000 E 13.00m 1m 10000m 10m
+ 86400 IN LOC 36 7 19.000 S 120 2 25.000 E 14.00m 1m 10000m 10m
+ 86400 IN LOC 37 7 19.000 S 121 2 25.000 E 15.00m 1m 10000m 10m
+ 86400 IN LOC 38 7 19.000 S 122 2 25.000 E 16.00m 1m 10000m 10m
+ 86400 IN LOC 39 7 19.000 S 123 2 25.000 E 17.00m 1m 10000m 10m
+ 86400 IN LOC 40 7 19.000 S 124 2 25.000 E 18.00m 1m 10000m 10m
+ 86400 IN LOC 41 7 19.000 S 125 2 25.000 E 19.00m 1m 10000m 10m
+ 86400 IN LOC 42 7 19.000 S 126 2 25.000 E 20.00m 1m 10000m 10m
+ 86400 IN LOC 43 7 19.000 S 127 2 25.000 E 21.00m 1m 10000m 10m
+ 86400 IN LOC 44 7 19.000 S 128 2 25.000 E 22.00m 1m 10000m 10m
+ 86400 IN LOC 45 7 19.000 S 129 2 25.000 E 23.00m 1m 10000m 10m
+ 86400 IN LOC 46 7 19.000 S 130 2 25.000 E 24.00m 1m 10000m 10m
+ 86400 IN LOC 47 7 19.000 S 131 2 25.000 E 25.00m 1m 10000m 10m
+ 86400 IN LOC 89 59 59.999 S 179 59 59.999 E 1000000.00m 1000m 1000m 10m
+ 86400 IN LOC 90 0 0.000 S 180 0 0.000 E 0.01m 0.01m 0.01m 10m
+ 86400 RRSIG LOC 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ulzhF8Ko+Sr8OHUBwmFjaJv55/L91bpQvg5e
+ 24Wm5wtvHh/HKDJpokvbj9DHhCpqK1E/9AW8
+ kc3qZjSnzt4FoLM3RqXrUVyWF2T1AnQgOCmu
+ kPaH3oxyrPSg8H8XYSFNckLA8OXicG1xTNeh
+ FdDhgNMEDr4PnBvgmUby7u3cQqo= )
+ 3600 NSEC test.non-terminal.multiple-type-loc-record.example.com. LOC RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ mwez/8p0PQ3c/jv4785yYIeWJmj1UCE40Sbn
+ rBGW/cPQDluXBSrKkcHiakmwm2Ox6VTNZPG9
+ m7sh0w8bxemoH0ELEePVXmbmICJxRC92n91f
+ laQKNMB3x0BWLviyWWzP3CIftWMRf4VBUIcQ
+ VhZHkXOcNfFF8gBeeOm4msZdX0M= )
+test.non-terminal.multiple-type-loc-record.example.com. 86400 IN LOC 32 7 19.000 S 116 2 25.000 E 10.00m 1m 10000m 10m
+ 86400 IN LOC 33 7 19.000 S 117 2 25.000 E 11.00m 1m 10000m 10m
+ 86400 IN LOC 34 7 19.000 S 118 2 25.000 E 12.00m 1m 10000m 10m
+ 86400 IN LOC 35 7 19.000 S 119 2 25.000 E 13.00m 1m 10000m 10m
+ 86400 IN LOC 36 7 19.000 S 120 2 25.000 E 14.00m 1m 10000m 10m
+ 86400 IN LOC 37 7 19.000 S 121 2 25.000 E 15.00m 1m 10000m 10m
+ 86400 IN LOC 38 7 19.000 S 122 2 25.000 E 16.00m 1m 10000m 10m
+ 86400 IN LOC 39 7 19.000 S 123 2 25.000 E 17.00m 1m 10000m 10m
+ 86400 IN LOC 40 7 19.000 S 124 2 25.000 E 18.00m 1m 10000m 10m
+ 86400 IN LOC 41 7 19.000 S 125 2 25.000 E 19.00m 1m 10000m 10m
+ 86400 IN LOC 42 7 19.000 S 126 2 25.000 E 20.00m 1m 10000m 10m
+ 86400 IN LOC 43 7 19.000 S 127 2 25.000 E 21.00m 1m 10000m 10m
+ 86400 IN LOC 44 7 19.000 S 128 2 25.000 E 22.00m 1m 10000m 10m
+ 86400 IN LOC 45 7 19.000 S 129 2 25.000 E 23.00m 1m 10000m 10m
+ 86400 IN LOC 46 7 19.000 S 130 2 25.000 E 24.00m 1m 10000m 10m
+ 86400 IN LOC 47 7 19.000 S 131 2 25.000 E 25.00m 1m 10000m 10m
+ 86400 IN LOC 89 59 59.999 S 179 59 59.999 E 1000000.00m 1000m 1000m 10m
+ 86400 IN LOC 90 0 0.000 S 180 0 0.000 E 0.01m 0.01m 0.01m 10m
+ 86400 RRSIG LOC 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Hhg2/gJ4NSn/PBU6SaFXqd35wqDXOKJ84O5Y
+ Z0SfMJjZQ+S/jmGfPEDADp0p0d7J7N9ttari
+ yw9HMZ5AGOjl44aKfwVLivXcjITsar5RKyIT
+ E5Q22bb/SrDJUb9orcGJZmhFPlJXP7VGBbO8
+ frk9fsvG2g1wsO3Wh45M9us3jLI= )
+ 3600 NSEC multiple-type-minfo-record.example.com. LOC RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ y84udhTt/XPPoB6q1IjRXiC3DCBklB1h8rHY
+ fmjpmoqGc6eFViSWr3K3gx6XnuaOhIsXRjFe
+ knQlkYIRGy42YHvY7IZ1BiLDtM3k3twqsasP
+ 9sUVavv3Km+IdvOfvTtbU5UYcaLiTIr8M7/p
+ vIPoqkTWeXntb0KR8rYYylVGPZA= )
+multiple-type-minfo-record.example.com. 86400 IN MINFO sun00.abc.foo.bar.liu.zhang.han.cnnic.cn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+ 86400 IN MINFO sun01.abc.foo.bar.liu.zhang.han.cnnic.cn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+ 86400 IN MINFO sun02.abc.foo.bar.liu.zhang.han.cnnic.cn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+ 86400 IN MINFO sun03.abc.foo.bar.liu.zhang.han.cnnic.cn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+ 86400 IN MINFO sun04.abc.foo.bar.liu.zhang.han.cnnic.cn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+ 86400 IN MINFO sun04.abc.foo.bar.liu.zhang.han.cnnic.dn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+ 86400 IN MINFO sun04.abc.foo.bar.liu.zhang.han.cnnic.en. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+ 86400 IN MINFO sun04.abc.foo.bar.liu.zhang.han.cnnic.fn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+ 86400 IN MINFO sun04.abc.foo.bar.liu.zhang.han.cnnic.gn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+ 86400 RRSIG MINFO 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ZI7hm5Zn9qwBl7HVkMLFLOrv5E4ggMSNsJ4w
+ MRJCIv+69fdhS43NYA/W2hQfUzOXa/JhFk/i
+ z+guQ6N6XhllidIaT53W6AIHZu/19QKpL2VS
+ VMQ4pDrtJYzQNsemeTcvfGzZdBmbPc/5QryR
+ zbswkajykzSDL9Au08M8TncCB3c= )
+ 3600 NSEC test.non-terminal.multiple-type-minfo-record.example.com. MINFO RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ fUwTo84k6vpmBltSZR1MZNtTDdZSGQ1/+ICZ
+ ummg0tYmImI6Ml3VBSgZepkIDT+7fa4JDWPT
+ EpYp7GK19OPgv8ijQhmPU3OVNAeqhvMpjK3g
+ w9IoR+OEQRYhgezsA0hyKIhd5OJ9bW/FBJTf
+ 04Q8bo9tHqfUSpM2yK9c9xoaL70= )
+test.non-terminal.multiple-type-minfo-record.example.com. 86400 IN MINFO sun00.abc.foo.bar.liu.zhang.han.cnnic.cn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+ 86400 IN MINFO sun01.abc.foo.bar.liu.zhang.han.cnnic.cn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+ 86400 IN MINFO sun02.abc.foo.bar.liu.zhang.han.cnnic.cn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+ 86400 IN MINFO sun03.abc.foo.bar.liu.zhang.han.cnnic.cn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+ 86400 IN MINFO sun04.abc.foo.bar.liu.zhang.han.cnnic.cn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+ 86400 IN MINFO sun04.abc.foo.bar.liu.zhang.han.cnnic.dn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+ 86400 IN MINFO sun04.abc.foo.bar.liu.zhang.han.cnnic.en. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+ 86400 IN MINFO sun04.abc.foo.bar.liu.zhang.han.cnnic.fn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+ 86400 IN MINFO sun04.abc.foo.bar.liu.zhang.han.cnnic.gn. pipo.fifo.lilo.tito.gigo.bibo.riro.siso.vivo.cico.cn.
+ 86400 RRSIG MINFO 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ eUJ2HVgSxrFxBXmoEMHybIZ4CScum7nVIjJB
+ TRXwAZBoqTFWAxZ8v3tt2e0aIDk5lu3H/lLa
+ Z2ThcXpFYmibcBid4eWhwhsUoj+/vsProK6Q
+ spXz2+GPg9C/1aVmblO3JfUUQ/XHbDGLSOyJ
+ TtWC0MqUDbKu86jDlKOTTo5tyiw= )
+ 3600 NSEC multiple-type-mx-record.example.com. MINFO RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ YK9blDNd/KdWiDYEFQi3wPAiY3r7+kk44aRl
+ IV0E/Mwpg6Uy/n6h8fS8Jxv35lWusKFjR76F
+ 6ekvGjn+a9aXZ1INxR2F2aLMxI/pM9qnntty
+ PdBx+X8OQlrT3ZU4Egt+Edl+TYZEmLYVCCaV
+ nvQw5+tXChTPlgjxCs0MsJe+LSo= )
+multiple-type-mx-record.example.com. 86400 IN MX 10 mail1.example.com.
+ 86400 IN MX 10 mail2.example.com.
+ 86400 IN MX 10 mail3.example.com.
+ 86400 IN MX 10 mail4.example.com.
+ 86400 IN MX 10 mail5.example.com.
+ 86400 IN MX 10 mail6.example.com.
+ 86400 IN MX 10 mail7.example.com.
+ 86400 IN MX 10 mail8.example.com.
+ 86400 IN MX 10 mail9.example.com.
+ 86400 IN MX 10 mail10.example.com.
+ 86400 IN MX 10 mail11.example.com.
+ 86400 IN MX 10 mail12.example.com.
+ 86400 IN MX 20 mail13.example.com.
+ 86400 IN MX 30 mail14.example.com.
+ 86400 IN MX 40 mail15.example.com.
+ 86400 IN MX 50 mail16.example.com.
+ 86400 IN MX 60 mail17.example.com.
+ 86400 IN MX 70 mail18.example.com.
+ 86400 IN MX 80 mail19.example.com.
+ 86400 IN MX 90 mail20.example.com.
+ 86400 RRSIG MX 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ n1a9V6z3XbAXFUwAtE0eqS1Cq5wJhIG8AZkF
+ rABGfxtLR7zatMeRwIjx4aUoUI5vLWN0E+di
+ 1xOAEDiFOjw+jFYklcR6dqREdrEbJFYAOPwY
+ MCCKeOPay3VcJxW/Z5yjLSBPnq7jq9ERawcB
+ MJnOnKS49WaibS3VYiWuXOXfn2s= )
+ 3600 NSEC test.non-terminal.multiple-type-mx-record.example.com. MX RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ U1f48jBPDKboX/uyoNm8/bRKVV9ro2iNx28C
+ 0QAyRv/Wm3oc+u9dJQZF0lobbf12XiYOP+G1
+ UTSBTx8TKPNqkeQWYE/jjpiB7DOF24Ua6Mh+
+ d+bofYik7Eissuyqm6jJbkfJjSjNluAixbKc
+ iRmt1BNYGIMfXj4FsJHYESRMW1M= )
+test.non-terminal.multiple-type-mx-record.example.com. 86400 IN MX 10 mail1.example.com.
+ 86400 IN MX 10 mail2.example.com.
+ 86400 IN MX 10 mail3.example.com.
+ 86400 IN MX 10 mail4.example.com.
+ 86400 IN MX 10 mail5.example.com.
+ 86400 IN MX 10 mail6.example.com.
+ 86400 IN MX 10 mail7.example.com.
+ 86400 IN MX 10 mail8.example.com.
+ 86400 IN MX 10 mail9.example.com.
+ 86400 IN MX 10 mail10.example.com.
+ 86400 IN MX 10 mail11.example.com.
+ 86400 IN MX 10 mail12.example.com.
+ 86400 IN MX 20 mail13.example.com.
+ 86400 IN MX 30 mail14.example.com.
+ 86400 IN MX 40 mail15.example.com.
+ 86400 IN MX 50 mail16.example.com.
+ 86400 IN MX 60 mail17.example.com.
+ 86400 IN MX 70 mail18.example.com.
+ 86400 IN MX 80 mail19.example.com.
+ 86400 IN MX 90 mail20.example.com.
+ 86400 RRSIG MX 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ BTXMAaDMhKrLa9vsctT6XkutEC4KRzmyFej5
+ PbCv/n+q81Nyevyp5VZjH2/u30JNA2BDjhcA
+ EvMUncGljMiz9hKvqW04R295Z+aSq0xINM8H
+ wE0S+Ef1KQDNJv4z9jHwnvtJx8BXT+RXeXMK
+ t9+uv7X/ejrWFrgLGEVnrP9MexE= )
+ 3600 NSEC multiple-type-ns-record.example.com. MX RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ AFH7WPdHrW3IhPeWuE7kBvgLWqa/Qd7zm+69
+ RzH0tC7ZEB/LH7noLvHr3a4L0gYR0CD7p6Oh
+ q6e7KNGcA/bUoS8YXxlQiyl/ByGQxSe5jUVi
+ zbAk/6p7QlRg/6q3HlphjK0r+C23FlUsElcu
+ kV0WEzGZ8rONYzxbduUVluTW0Co= )
+dns1.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.1
+test.non-terminal.dns1.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.1
+dns10.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.10
+test.non-terminal.dns10.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.10
+dns11.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.11
+test.non-terminal.dns11.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.11
+dns12.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.12
+test.non-terminal.dns12.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.12
+dns13.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.13
+test.non-terminal.dns13.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.13
+dns14.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.14
+test.non-terminal.dns14.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.14
+dns15.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.15
+test.non-terminal.dns15.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.15
+dns16.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.16
+test.non-terminal.dns16.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.16
+dns17.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.17
+test.non-terminal.dns17.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.17
+dns18.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.18
+test.non-terminal.dns18.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.18
+dns19.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.19
+test.non-terminal.dns19.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.19
+dns2.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.2
+test.non-terminal.dns2.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.2
+dns20.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.20
+test.non-terminal.dns20.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.20
+dns21.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.21
+test.non-terminal.dns21.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.21
+dns22.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.22
+test.non-terminal.dns22.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.22
+dns23.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.23
+test.non-terminal.dns23.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.23
+dns24.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.24
+test.non-terminal.dns24.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.24
+dns25.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.25
+test.non-terminal.dns25.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.25
+dns3.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.3
+test.non-terminal.dns3.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.3
+dns4.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.4
+test.non-terminal.dns4.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.4
+dns5.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.5
+test.non-terminal.dns5.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.5
+dns6.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.6
+test.non-terminal.dns6.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.6
+dns7.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.7
+test.non-terminal.dns7.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.7
+dns8.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.8
+test.non-terminal.dns8.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.8
+dns9.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.9
+test.non-terminal.dns9.multiple-type-ns-record.example.com. 86400 IN A 192.168.4.9
+test.non-terminal.multiple-type-ns-record.example.com. 86400 IN NS dns1.multiple-type-ns-record.example.com.
+ 86400 IN NS dns2.multiple-type-ns-record.example.com.
+ 86400 IN NS dns3.multiple-type-ns-record.example.com.
+ 86400 IN NS dns4.multiple-type-ns-record.example.com.
+ 86400 IN NS dns5.multiple-type-ns-record.example.com.
+ 86400 IN NS dns6.multiple-type-ns-record.example.com.
+ 86400 IN NS dns7.multiple-type-ns-record.example.com.
+ 86400 IN NS dns8.multiple-type-ns-record.example.com.
+ 86400 IN NS dns9.multiple-type-ns-record.example.com.
+ 86400 IN NS dns10.multiple-type-ns-record.example.com.
+ 86400 IN NS dns11.multiple-type-ns-record.example.com.
+ 86400 IN NS dns12.multiple-type-ns-record.example.com.
+ 86400 IN NS dns13.multiple-type-ns-record.example.com.
+ 86400 IN NS dns14.multiple-type-ns-record.example.com.
+ 86400 IN NS dns15.multiple-type-ns-record.example.com.
+ 86400 IN NS dns16.multiple-type-ns-record.example.com.
+ 86400 IN NS dns17.multiple-type-ns-record.example.com.
+ 86400 IN NS dns18.multiple-type-ns-record.example.com.
+ 86400 IN NS dns19.multiple-type-ns-record.example.com.
+ 86400 IN NS dns20.multiple-type-ns-record.example.com.
+ 86400 IN NS dns21.multiple-type-ns-record.example.com.
+ 86400 IN NS dns22.multiple-type-ns-record.example.com.
+ 86400 IN NS dns23.multiple-type-ns-record.example.com.
+ 86400 IN NS dns24.multiple-type-ns-record.example.com.
+multiple-type-ipseckey-record.example.com. 86400 IN IPSECKEY ( 10 1 2 192.0.2.3
+ AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6
+ BSGvgqt4AQ== )
+ 86400 IN IPSECKEY ( 10 1 2 192.0.2.4
+ BQNRU3mG7TVTO2BkR47usntb102uFJtugbo6
+ BSGvgqt4AQ== )
+ 86400 IN IPSECKEY ( 10 1 2 192.0.2.5
+ CQNRU3mG7TVTO2BkR47usntb102uFJtugbo6
+ BSGvgqt4AQ== )
+ 86400 IN IPSECKEY ( 10 1 2 192.0.2.6
+ DQNRU3mG7TVTO2BkR47usntb102uFJtugbo6
+ BSGvgqt4AQ== )
+ 86400 IN IPSECKEY ( 10 1 2 192.0.2.7
+ EQNRU3mG7TVTO2BkR47usntb102uFJtugbo6
+ BSGvgqt4AQ== )
+ 86400 IN IPSECKEY ( 10 1 2 192.0.2.8
+ FQNRU3mG7TVTO2BkR47usntb102uFJtugbo6
+ BSGvgqt4AQ== )
+ 86400 IN IPSECKEY ( 10 1 2 192.0.2.9
+ GQNRU3mG7TVTO2BkR47usntb102uFJtugbo6
+ BSGvgqt4AQ== )
+ 86400 IN IPSECKEY ( 10 1 2 192.0.2.10
+ HQNRU3mG7TVTO2BkR47usntb102uFJtugbo6
+ BSGvgqt4AQ== )
+ 86400 IN IPSECKEY ( 10 1 2 192.0.2.11
+ IQNRU3mG7TVTO2BkR47usntb102uFJtugbo6
+ BSGvgqt4AQ== )
+ 86400 RRSIG IPSECKEY 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ S6gFr+bJMrovfOsEzphLuH/peRKpC1e9CIw1
+ MxMQNN4YRW0XtJ0P6R4crYkRIE6hOtMsAHlD
+ PTAOZmnInmM/8Nhv0f7917NFJLrXpmpcqFLu
+ lolxyYPgTvDEaD4hE6ufCbHoxcQVPvDoNNUW
+ MA6sat8kv+I+6/uR2yTNUuDn5xk= )
+ 3600 NSEC multiple-type-kx-record.example.com. IPSECKEY RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ bSTvLRt+Gky6rF00U36bSN5SkSqtMQYlYvvP
+ GpulB8CBePWtgvyfgoqqldDTxfrqNzNMJ9ty
+ VZuHP96F9g15C/hOcuatoYri+HxTaNnUnk6c
+ bKGx7EKkkw7DCwO/WeD+DxAYiGVv1ugJ1hVz
+ MV4zSmYKajwf1TicojyQsxedD5o= )
+multiple-type-ns-record.example.com. 86400 IN NS dns1.multiple-type-ns-record.example.com.
+ 86400 IN NS dns2.multiple-type-ns-record.example.com.
+ 86400 IN NS dns3.multiple-type-ns-record.example.com.
+ 86400 IN NS dns4.multiple-type-ns-record.example.com.
+ 86400 IN NS dns5.multiple-type-ns-record.example.com.
+ 86400 IN NS dns6.multiple-type-ns-record.example.com.
+ 86400 IN NS dns7.multiple-type-ns-record.example.com.
+ 86400 IN NS dns8.multiple-type-ns-record.example.com.
+ 86400 IN NS dns9.multiple-type-ns-record.example.com.
+ 86400 IN NS dns10.multiple-type-ns-record.example.com.
+ 86400 IN NS dns11.multiple-type-ns-record.example.com.
+ 86400 IN NS dns12.multiple-type-ns-record.example.com.
+ 86400 IN NS dns13.multiple-type-ns-record.example.com.
+ 86400 IN NS dns14.multiple-type-ns-record.example.com.
+ 86400 IN NS dns15.multiple-type-ns-record.example.com.
+ 86400 IN NS dns16.multiple-type-ns-record.example.com.
+ 86400 IN NS dns17.multiple-type-ns-record.example.com.
+ 86400 IN NS dns18.multiple-type-ns-record.example.com.
+ 86400 IN NS dns19.multiple-type-ns-record.example.com.
+ 86400 IN NS dns20.multiple-type-ns-record.example.com.
+ 86400 IN NS dns21.multiple-type-ns-record.example.com.
+ 86400 IN NS dns22.multiple-type-ns-record.example.com.
+ 86400 IN NS dns23.multiple-type-ns-record.example.com.
+ 86400 IN NS dns24.multiple-type-ns-record.example.com.
+ 3600 NSEC multiple-type-nsap-record.example.com. NS RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ hGy291VFD0/csxNnK9OwnL52ufIRnZpta7MK
+ 1KQ2XboDyUTxJEKbKFiQpD33eUDDkNgcbueF
+ 57BBm2A+O1Kmn5I58ri22hQOZGVEqXlFJsFe
+ tQ76bHy0LUUt1fy2vXdjeC2Z1KonDbxJiRpa
+ 772s419tSBNU500199iHoH368yc= )
+multiple-type-kx-record.example.com. 86400 IN KX 0 kaku0.google.com.
+ 86400 IN KX 10 kaku1.google.com.
+ 86400 IN KX 20 kaku2.google.com.
+ 86400 IN KX 30 kaku3.google.com.
+ 86400 IN KX 40 kaku4.google.com.
+ 86400 IN KX 50 kaku5.google.com.
+ 86400 IN KX 60 kaku6.google.com.
+ 86400 IN KX 70 kaku7.google.com.
+ 86400 IN KX 80 kaku8.google.com.
+ 86400 IN KX 90 kaku9.google.com.
+ 86400 IN KX 100 kaku10.google.com.
+ 86400 IN KX 110 kaku11.google.com.
+ 86400 IN KX 120 kaku12.google.com.
+ 86400 IN KX 130 kaku13.google.com.
+ 86400 RRSIG KX 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ tdUveI5DwuJTkM1NOfp+IGWO5bYyLjb4ujTo
+ 1IlGJoVzyzA4NxGQGhX7zHVMx3uI0Mj85eQ0
+ pLsUi9SLP/gXNcvz7KHnEc7UnBFraochDS0n
+ Uop0Y1Kh7PjL8/jrTjgnDsz0Tg9yAJPNrIMa
+ JHQWasZjphbO9iRFrlJ4XTKHx6A= )
+ 3600 NSEC test.non-terminal.multiple-type-kx-record.example.com. KX RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ TuV2ESpHYIOFm2VZ10JCEPLLmoIRg36FVY5O
+ qj6vfg/6vzIxLviMtBlq+SYoiADw+w+EeQaq
+ cYhuv44V6G5LlfViSLNFWPXntBnEkIUQlLVc
+ B9vbD2bYb7pPBW40qn8m22d5xDaz+VFi7/hV
+ JeRNhEjb0nl1De7Vw4yrYXguF9E= )
+multiple-type-nsap-record.example.com. 86400 IN NSAP 0x47000580ffff0000003210999911112222333345
+ 86400 IN NSAP 0x47000580ffff0000003210999911112222333346
+ 86400 IN NSAP 0x47000580ffff0000003210999911112222333347
+ 86400 IN NSAP 0x47000580ffff0000003210999911112222333348
+ 86400 IN NSAP 0x47000580ffff0000003210999911112222333349
+ 86400 IN NSAP 0x47000580ffff000000321099991111222233334a
+ 86400 IN NSAP 0x47000580ffff000000321099991111222233334b
+ 86400 IN NSAP 0x47000580ffff000000321099991111222233334c
+ 86400 IN NSAP 0x47000580ffff000000321099991111222233334d
+ 86400 IN NSAP 0x47000580ffff000000321099991111222233334e
+ 86400 IN NSAP 0x47000580ffff000000321099991111222233334f
+ 86400 IN NSAP 0x47000580ffff0000003210999911112222333350
+ 86400 IN NSAP 0x47000580ffff0000003210999911112222333351
+ 86400 IN NSAP 0x47000580ffff0000003210999911112222333352
+ 86400 IN NSAP 0x47000580ffff0000003210999911112222333353
+ 86400 RRSIG NSAP 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ VjjJ7wbuhaC7NRGHCYvLvMcfIq4NfrqsKPUT
+ R3MGYS2BDQV4zRH2+O3ZZvJPowMYjRLtirZb
+ zCufgAeMSffttz0NYaeFc3aPt3P99Svdyj8A
+ 8a/A31rCsT2pX3JKpjqsbWvZ71ezJtlysizF
+ chSvSB+zfVzrZkYUIaAxj4GQOmw= )
+ 3600 NSEC test.non-terminal.multiple-type-nsap-record.example.com. NSAP RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Wtp2ageuXKacRJvnPgqHi7DFetvEH2Sti3Y3
+ ofcZlCu0k9vH60DHGPQVZZDXMsJqNbm6rEP/
+ 8gl/FULxmdbYt54xrXzhTVj5LLQ/zIwHfYcC
+ ybz6EnBR5ECIm7AYDssaGYS30q378ILGaIJp
+ pE9ekJ7BMuvlnfcY16cpIrTla2I= )
+multiple-type-ptr-record.example.com. 86400 IN PTR 192.168.2.1.example.com.
+ 86400 IN PTR 192.168.2.2.example.com.
+ 86400 IN PTR 192.168.2.3.example.com.
+ 86400 IN PTR 192.168.2.4.example.com.
+ 86400 IN PTR 192.168.2.5.example.com.
+ 86400 IN PTR 192.168.2.6.example.com.
+ 86400 IN PTR 192.168.2.7.example.com.
+ 86400 IN PTR 192.168.2.8.example.com.
+ 86400 IN PTR 192.168.2.9.example.com.
+ 86400 IN PTR 192.168.2.10.example.com.
+ 86400 IN PTR 192.168.2.11.example.com.
+ 86400 IN PTR 192.168.2.12.example.com.
+ 86400 IN PTR 192.168.2.13.example.com.
+ 86400 IN PTR 192.168.2.14.example.com.
+ 86400 IN PTR 192.168.2.15.example.com.
+ 86400 IN PTR 192.168.2.16.example.com.
+ 86400 IN PTR 192.168.2.17.example.com.
+ 86400 IN PTR 192.168.2.18.example.com.
+ 86400 RRSIG PTR 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ xMr0GjsJdcM49li65zthlitnHMAn9TnOvwZG
+ BCq3Z6tfwLqMjQ+OE5GJL4LxRwbzeD4He5F/
+ E0jgt53h5UBXIDGQW5JVn37eymOpq85AZXXj
+ DPwzSE52wPSiglYdE8yD1YCiuMsUzwuxIuB4
+ vmsQ6Uhk290QA1B+HSF2lOozQ6M= )
+ 3600 NSEC test.non-terminal.multiple-type-ptr-record.example.com. PTR RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ Ycs286OBLxSiSUj//nyrgzM4A/RjGADr3q5B
+ zyX8lCk2DyBIOVzJi6s17uy/FhuPiIHDXUMG
+ TN/30+tlo0PNaK+sA7wSY01djNVdcGuWv5id
+ LNaeHi5poNlOw2LwulKvDH7jbctBTDd7yaPu
+ S00drnPpXu0BhF5+QrBnRS7G3pw= )
+test.non-terminal.multiple-type-ptr-record.example.com. 86400 IN PTR 192.168.2.1.example.com.
+ 86400 IN PTR 192.168.2.2.example.com.
+ 86400 IN PTR 192.168.2.3.example.com.
+ 86400 IN PTR 192.168.2.4.example.com.
+ 86400 IN PTR 192.168.2.5.example.com.
+ 86400 IN PTR 192.168.2.6.example.com.
+ 86400 IN PTR 192.168.2.7.example.com.
+ 86400 IN PTR 192.168.2.8.example.com.
+ 86400 IN PTR 192.168.2.9.example.com.
+ 86400 IN PTR 192.168.2.10.example.com.
+ 86400 IN PTR 192.168.2.11.example.com.
+ 86400 IN PTR 192.168.2.12.example.com.
+ 86400 IN PTR 192.168.2.13.example.com.
+ 86400 IN PTR 192.168.2.14.example.com.
+ 86400 IN PTR 192.168.2.15.example.com.
+ 86400 IN PTR 192.168.2.16.example.com.
+ 86400 IN PTR 192.168.2.17.example.com.
+ 86400 IN PTR 192.168.2.18.example.com.
+ 86400 RRSIG PTR 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ cU6aFz/ZFM8Sn/3faM0jdOxmQ7l3H4yBNIkz
+ dDK/NhisaScsEVifPDSkDOye3Z0mCB22eJSt
+ Z5OKiLEfG7LIskHVFckYcjtX1/z9Atiimqfk
+ EKyqefWHDmYgcN79Ik212BR77qrAaFc9VbE3
+ pt0fImdLIoavysX2H6ja+LddfWg= )
+ 3600 NSEC multiple-type-px-record.example.com. PTR RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ iW85YGRBWXGMMKOCwy9jObygUotQ+qtYXvGV
+ DhlNSa92e9fr3lkJXmkTobs8yM8Y6y26sgMO
+ N7Pu7ecOoj8lrGqnhvh0qDQ6XHi0yZndTsAy
+ nx6oe2MjTmn5Qfo+a1JLCf6DPTPvq8WJTdPl
+ WOuYYdxULuYWZxwhMfpO6udbeWI= )
+multiple-type-px-record.example.com. 86400 IN PX 10 ab.net2.it. O-ab.PRMD-net2.ADMDb.C-it.
+ 86400 IN PX 11 ab.net3.it. 1-ab.PRMD-net2.ADMDb.C-it.
+ 86400 IN PX 12 ab.net4.it. 2-ab.PRMD-net2.ADMDb.C-it.
+ 86400 IN PX 13 ab.net5.it. 3-ab.PRMD-net2.ADMDb.C-it.
+ 86400 IN PX 14 ab.net6.it. 4-ab.PRMD-net2.ADMDb.C-it.
+ 86400 IN PX 15 ab.net7.it. 5-ab.PRMD-net2.ADMDb.C-it.
+ 86400 IN PX 16 ab.net8.it. 6-ab.PRMD-net2.ADMDb.C-it.
+ 86400 IN PX 10 ab.net9.it. 7-ab.PRMD-net2.ADMDb.C-it.
+ 86400 IN PX 10 ab.net2.it. 8-ab.PRMD-net2.ADMDb.C-it.
+ 86400 IN PX 10 ab.net2.it. 9-ab.PRMD-net2.ADMDb.C-it.
+ 86400 RRSIG PX 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ L4Ei+7bRt5fC/yz5QKoLdjDQHf4tFRfueF0H
+ RXKm5ytymaaNfbA+MWVB1YAo/4volienHpz8
+ 6xwW2UEdBmSlAN+F2ITp9vy3Rbt4WRrvW1f+
+ EHfZUAW9b9wNfjY2gYNiBkD+/Ilw4le/gG3M
+ 4bD2RDndIcDrS0ibgPhfJV9yBnM= )
+ 3600 NSEC test.non-terminal.multiple-type-px-record.example.com. PX RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ n8tYwZFxp04RsaevVGSgiJYIUB4yQ8PUH13r
+ CtOMhyZ9pOKRapoZo+oSCP7XKPrjpAu/IoJw
+ Z0ZIEgDEGvMmrd7eJF5kvx/Ac7Ev11M3LsfP
+ Vqo5yyMbTEzdeQjx8Jy+4PXs8Q7L4t2p1Qal
+ Yju8Lbn5PW0trhw2mQd9lr3UIXQ= )
+test.non-terminal.multiple-type-px-record.example.com. 86400 IN PX 10 ab.net2.it. O-ab.PRMD-net2.ADMDb.C-it.
+ 86400 IN PX 11 ab.net3.it. 1-ab.PRMD-net2.ADMDb.C-it.
+ 86400 IN PX 12 ab.net4.it. 2-ab.PRMD-net2.ADMDb.C-it.
+ 86400 IN PX 13 ab.net5.it. 3-ab.PRMD-net2.ADMDb.C-it.
+ 86400 IN PX 14 ab.net6.it. 4-ab.PRMD-net2.ADMDb.C-it.
+ 86400 IN PX 15 ab.net7.it. 5-ab.PRMD-net2.ADMDb.C-it.
+ 86400 IN PX 16 ab.net8.it. 6-ab.PRMD-net2.ADMDb.C-it.
+ 86400 IN PX 10 ab.net9.it. 7-ab.PRMD-net2.ADMDb.C-it.
+ 86400 IN PX 10 ab.net2.it. 8-ab.PRMD-net2.ADMDb.C-it.
+ 86400 IN PX 10 ab.net2.it. 9-ab.PRMD-net2.ADMDb.C-it.
+ 86400 RRSIG PX 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ T5eoO8YYxMN4gJ7wbonQn2qt+QuMXk9OqErP
+ HhqWbrCGhdgj+n4KvbqzAgutcBWcNDEM72F1
+ J5kcNJyw7KB5Cgc5LPOYFLr0e0GLdKMDKR8D
+ 2HictxvGwxNa044z54ArZB57K8dj0ZvVKD4x
+ gBddOCAdo6xjA0yDPSqThASjEPA= )
+ 3600 NSEC multiple-type-spf-record.example.com. PX RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ W7UWZhx9H+WRE4rWvaqN6WNA+sjnAwOJ9qvr
+ oacCBklJMCu/8Dq8OyK4TbJ/jQdcZHWPA7Ck
+ Sm1A3dw3WjD6xrNXFdk53UzHBV4hpIgFMMaU
+ cPRnGoH2oYMeysqHxxG8kaP/snz3FFM795E+
+ 7p7SutdJRwxtAgYEJ0lTMbnYYQY= )
+multiple-type-spf-record.example.com. 3600 IN NSEC test.non-terminal.multiple-type-spf-record.example.com. RRSIG NSEC SPF
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ fYl7qQa5MF35eatIE/SXaNuHSStpVPruc2nJ
+ TP6A6uwDz3mG52EJg55ppiy4geSS6PO/LHU9
+ hnf0PP7uL8tgyDcxlLEvtCkaSaZ9H6yrsCn2
+ 28j916U/OTEzOxtz6jvHZL2dXr4jizTJIaAp
+ hCrRq/7pzZfzcubwzwfqpZW/TbY= )
+ 86400 SPF "'asdfghjkl"
+ 86400 SPF "'sina"
+ 86400 SPF "'cnnic"
+ 86400 SPF "'jkl"
+ 86400 SPF "'c=sina.com.'"
+ 86400 SPF "'fw=fff.com.cn.'"
+ 86400 SPF "'ibm"
+ 86400 SPF "'dell"
+ 86400 SPF "'google" "-" "microsoft"
+ 86400 SPF "'leibusi"
+ 86400 SPF "v=spf1"
+ 86400 SPF "v=spf1 -all"
+ 86400 SPF "v=spf1 ip4:192.168.0.1/16 -all "
+ 86400 SPF "v=spf1 ip4:192.168.1.1/16 -all "
+ 86400 SPF "v=spf1 ip4:192.168.2.1/16 -all "
+ 86400 SPF "v=spf1 ip4:192.168.3.1/16 -all "
+ 86400 SPF "v=spf1 ip4:192.168.4.1/16 -all "
+ 86400 SPF "v=spf1 ip4:192.168.5.1/16 -all "
+ 86400 SPF "v=spf1 ip4:192.168.6.1/16 -all "
+ 86400 SPF "v=spf1 ip4:192.168.7.1/16 -all "
+ 86400 RRSIG SPF 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ nIzHN3gjvwLEZxKGRIX8ip+LLb6F4zPkkV7P
+ zgNkeUwrT9/1kTxn6dM7JLUs4B2e3TTOVVau
+ /8keis6ERbW51w0dR6glneGUqvWOk+GH1Qdo
+ nJLOkpPnXqUKr50pcLxS8YCf0bqYXZOy3uWh
+ 4eEKEKlgnYGys/+oZdiB8ulPR2E= )
+test.non-terminal.multiple-type-spf-record.example.com. 3600 IN NSEC multiple-type-srv-record.example.com. RRSIG NSEC SPF
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ uCohn+WaZg8LrCFrvjz0xRgKR2FTGMh2Vmw1
+ HrHnzdFj4RhAKIlcD+CMsaWlNYetu4AvK0Xw
+ uB+Q1GjkOjMhm843RxjNSXacCzvIoixYrt8w
+ XR8fLeRzv6fZbYocyKjgXuOmiIlBQp47yOW3
+ ptItmoFKrcxoZ5KW3dIvAYLNISM= )
+ 86400 SPF "'asdfghjkl"
+ 86400 SPF "'sina"
+ 86400 SPF "'cnnic"
+ 86400 SPF "'jkl"
+ 86400 SPF "'c=sina.com.'"
+ 86400 SPF "'fw=fff.com.cn.'"
+ 86400 SPF "'ibm"
+ 86400 SPF "'dell"
+ 86400 SPF "'google" "-" "microsoft"
+ 86400 SPF "'leibusi"
+ 86400 SPF "v=spf1"
+ 86400 SPF "v=spf1 -all"
+ 86400 SPF "v=spf1 ip4:192.168.0.1/16 -all "
+ 86400 SPF "v=spf1 ip4:192.168.1.1/16 -all "
+ 86400 SPF "v=spf1 ip4:192.168.2.1/16 -all "
+ 86400 SPF "v=spf1 ip4:192.168.3.1/16 -all "
+ 86400 SPF "v=spf1 ip4:192.168.4.1/16 -all "
+ 86400 SPF "v=spf1 ip4:192.168.5.1/16 -all "
+ 86400 SPF "v=spf1 ip4:192.168.6.1/16 -all "
+ 86400 SPF "v=spf1 ip4:192.168.7.1/16 -all "
+ 86400 RRSIG SPF 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ CjyonA4FOC7BYfeSGe7dJNO3sn/8SkVAH3+m
+ P1pxkJzMRzemMu65sFI6vlnRtbCvh6Q5wPRH
+ s2YDpiO0+QXDn6+75vS2Fzgmn5nOppt2SSsA
+ oRBM+uDaAmsBreYFJkXtx4PdpbaL/pGE3hx5
+ qmOAHRxS6snoZtewleyWvCnr6GY= )
+test.non-terminal.multiple-type-nsap-record.example.com. 86400 IN NSAP 0x47000580ffff0000003210999911112222333345
+ 86400 IN NSAP 0x47000580ffff0000003210999911112222333346
+ 86400 IN NSAP 0x47000580ffff0000003210999911112222333347
+ 86400 IN NSAP 0x47000580ffff0000003210999911112222333348
+ 86400 IN NSAP 0x47000580ffff0000003210999911112222333349
+ 86400 IN NSAP 0x47000580ffff000000321099991111222233334a
+ 86400 IN NSAP 0x47000580ffff000000321099991111222233334b
+ 86400 IN NSAP 0x47000580ffff000000321099991111222233334c
+ 86400 IN NSAP 0x47000580ffff000000321099991111222233334d
+ 86400 IN NSAP 0x47000580ffff000000321099991111222233334e
+ 86400 IN NSAP 0x47000580ffff000000321099991111222233334f
+ 86400 IN NSAP 0x47000580ffff0000003210999911112222333350
+ 86400 IN NSAP 0x47000580ffff0000003210999911112222333351
+ 86400 IN NSAP 0x47000580ffff0000003210999911112222333352
+ 86400 IN NSAP 0x47000580ffff0000003210999911112222333353
+ 86400 RRSIG NSAP 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ xefH7sd6NOTwJzREvnIXvOnh6bokfP6rjCJ6
+ Nwdl/Sgh6bDsbrrJTVIPIgZOXsjU7/OKakFG
+ ICOdpVWYmYnLnYcLyu/VP1zgXDnRydEFyYVp
+ WT/67H1dsCcYWM7KHq6eVdhMZe2pKturt1cD
+ W20lTJ0jdg7AK3Cg8v7K74Fpqzs= )
+ 3600 NSEC multiple-type-ptr-record.example.com. NSAP RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ w51cGk1/OFOq2wQoOUaswnmf7SAQkj3hc1xI
+ 9SRdhrG+FwVn+4wxP43/kBdvWI/auSUgWqtT
+ OGGg4vBCq3AXw3ujRIZlVmfJjUtIOSZQp9mC
+ 8pwU9tRhQJxMNBp3YpI2wlDZH4oUvZ//OAqI
+ 1zHHt8nwM49xbnZN/RVZwsITVKI= )
+multiple-type-sshfp-record.example.com. 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7890 )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7891 )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7892 )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7893 )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7894 )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7895 )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7896 )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7897 )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7898 )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7899 )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 789A )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 789B )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 789C )
+ 86400 RRSIG SSHFP 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ diDyrgPWHOROwzvA4uiTMlMt7TecCExaW4Di
+ lAcbaKw0L9FFm7Y/NFzbMnbTHil7oQXsj7YL
+ ACSfB2VEYOcbz+634MAP6OhWAbYi2tH4NtCo
+ NN7s0FO+X1OY4loW+YUzqv07GQx3rGU1Rp8H
+ ZN9SBxByLYX6/iv70IOoiOzwGIo= )
+ 3600 NSEC test.non-terminal.multiple-type-sshfp-record.example.com. SSHFP RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ jdMPQ4Z+FZBsMN8U8avHc2rz+YgCM9QzMK+J
+ DSP23aELopJTeocG1unpLkEjw5btJqPW1Hxj
+ bA2G/rojgP8hUOi4qLis1AiA6rjHILnW/sD+
+ 6H7DAxB7/tvD0SSJn55D3vmqU5WMrti9ofuA
+ n2LYz/MooVo2OMZATdrHvHGvuz4= )
+test.non-terminal.multiple-type-sshfp-record.example.com. 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7890 )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7891 )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7892 )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7893 )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7894 )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7895 )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7896 )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7897 )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7898 )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 7899 )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 789A )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 789B )
+ 86400 IN SSHFP 2 1 (
+ 123456789ABCDEF67890123456789ABCDEF6
+ 789C )
+ 86400 RRSIG SSHFP 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ AZgsDXFCkg8QK/kb+myeB2S7Rt2/UoDtLZbi
+ iNmCi+ichEtXHsrYFW+cwnRC1ooUGGmR8RWq
+ IY+i/K1DdifcNu1eR7Fw8jvSGSwdP5PjcmZv
+ D7qsy9a1z6S4w8DV76yPSscc87feqJeFteDT
+ DDOY5qfTjDlU8NK0BeYyhIuAvIM= )
+ 3600 NSEC multiple-type-txt-record.example.com. SSHFP RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ gD4t70ymAKs3OGFjmOapjt4j7Sj4jxZoqtHP
+ /appQRN8b+sfq7I8bPuldmjGY/3dqoOuqXI5
+ i13PMeixxs6tWkfNAIc34/5V2jCnXH0ew+4f
+ NYP5Jf3En5XgXL/tMrMbduQvQL/WSqRj/eDX
+ JMX4Q7kAzPeey5dRrOhugnnVU5Y= )
+test.non-terminal.multiple-type-srv-record.example.com. 86400 IN SRV 0 2 80 www.movie0.edu.
+ 86400 IN SRV 1 3 80 www.movie1.edu.
+ 86400 IN SRV 2 4 80 www.movie2.edu.
+ 86400 IN SRV 3 5 80 www.movie3.edu.
+ 86400 IN SRV 4 6 80 www.movie4.edu.
+ 86400 IN SRV 5 7 80 www.movie5.edu.
+ 86400 IN SRV 6 8 80 www.movie6.edu.
+ 86400 IN SRV 7 9 80 www.movie7.edu.
+ 86400 IN SRV 8 10 80 www.movie8.edu.
+ 86400 IN SRV 9 11 80 www.movie9.edu.
+ 86400 IN SRV 10 12 80 www.movie10.edu.
+ 86400 IN SRV 11 13 80 www.movie11.edu.
+ 86400 IN SRV 12 14 80 www.movie12.edu.
+ 86400 RRSIG SRV 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ogZhDnKwKdVkMzz5tdzNb4g6Ob/eLvTYKDrl
+ V+lI1twfv79u2wRrrDGMPopIoqt2R0L8TCFd
+ 6R9ZRGuqaXnH7RJO7dcMrPtfqaOXrfHobxI3
+ /869BlqTZTHh5KXAnxc2ecLPMz5ZKRvbu0Z3
+ a3+Ltis8XxQbA06VsgpPhxsEWc8= )
+ 3600 NSEC multiple-type-sshfp-record.example.com. SRV RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ lMSeqTve8vhMIrgCXFvFTvmV2oGxXtTTowxB
+ WK7WSwXBc3HI/sXPLlH4WkM9lYG0A7W/RtnI
+ Q1rmeiTCGr/Jnedn6fDfi3drLPxN1PktZyiT
+ aqguYMh5O8o7Bn3WDF7jsHoTCO2RBWVu/C5P
+ mOCIbM/bI0+Pz+Fr+bQXufBk/wU= )
+test.non-terminal.multiple-type-txt-record.example.com. 86400 IN TXT "txt::1"
+ 86400 IN TXT "txt::2"
+ 86400 IN TXT "txt::3"
+ 86400 IN TXT "txt::4"
+ 86400 IN TXT "txt::5"
+ 86400 IN TXT "txt::6"
+ 86400 IN TXT "txt::7"
+ 86400 IN TXT "txt::8"
+ 86400 IN TXT "txt::9"
+ 86400 IN TXT "txt::10"
+ 86400 IN TXT "txt::11"
+ 86400 IN TXT "txt::12"
+ 86400 IN TXT "txt::13"
+ 86400 IN TXT "txt::14"
+ 86400 IN TXT "txt::15"
+ 86400 IN TXT "txt::16"
+ 86400 IN TXT "txt::17"
+ 86400 IN TXT "txt::18"
+ 86400 IN TXT "txt::19"
+ 86400 IN TXT "txt::20"
+ 86400 IN TXT "txt::21"
+ 86400 IN TXT "txt::22"
+ 86400 IN TXT "txt::23"
+ 86400 IN TXT "txt::24"
+ 86400 IN TXT "txt::25"
+ 86400 IN TXT "txt::26"
+ 86400 IN TXT "txt::27"
+ 86400 IN TXT "txt::28"
+ 86400 IN TXT "txt::29"
+ 86400 IN TXT "txt::30"
+ 86400 IN TXT "txt::31"
+ 86400 RRSIG TXT 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ EI+oudyovCkHhDkHJO5B8KWQkKBowxFVXgPE
+ Aglas+tpdVlsyJ0DrOc3z1vOoJXnKW85SUH0
+ 6DkPd+0PAmSraPNKHZmiL1onBgWjZgoXl4vD
+ NTTnBpnRrHTmxXF50x/j0tBwnSrIwqWW/exk
+ kkjthFL9jS/fJfSve2PHGqrZhtY= )
+ 3600 NSEC multiple-type-wks-record.example.com. TXT RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ jSP0eD1wN/KI8yAI4a3JqUXdN2a3zZVxdYgg
+ XaheCG4ftdh5RLMfZzZygx4OAFM3i9xKH2ul
+ sS8fyDcNx2yC8K5apt9CvQERQK6DgzvOMLv0
+ w/SJ9r7VsPwGQYGFkgL5lM/8j+OT8yWfqHKV
+ UqRVp2N9llMBgsZvONbcOAgk5y0= )
+multiple-type-wks-record.example.com. 86400 IN WKS 218.241.109.1 6 23 25 53
+ 86400 IN WKS 218.241.109.2 6 23 25 53
+ 86400 IN WKS 218.241.109.3 6 23 25 53
+ 86400 IN WKS 218.241.109.4 6 23 25 53
+ 86400 IN WKS 218.241.109.5 6 23 25 53
+ 86400 IN WKS 218.241.109.6 6 23 25 53 6000
+ 86400 IN WKS 218.241.109.7 6 23 25 53
+ 86400 IN WKS 218.241.109.8 6 23 25 53
+ 86400 IN WKS 218.241.109.9 6 23 25 53
+ 86400 IN WKS 218.241.109.10 6 23 25 53
+ 86400 IN WKS 218.241.109.11 6 22 23 25 53
+ 86400 IN WKS 218.241.109.12 6 22 23 25 53
+ 86400 IN WKS 218.241.109.13 6 22 23 25 53
+ 86400 IN WKS 218.241.109.14 6 22 25 53 80
+ 86400 IN WKS 218.241.109.15 6 22 25 53 80
+ 86400 IN WKS 218.241.109.16 6 22 25 80 6000
+ 86400 RRSIG WKS 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Ay1hCHvEA0uCa7qBEi0ABZrf3qsAswLbfBoA
+ ep+6yXF1e0Yv7nQPVlc9qJT1yoDLgVdNzpO4
+ O7DyZ/sWVjoXxFu5pAiKY+X4rgr4XT48NuBm
+ 0uzE2u9fNS/fi8lZoozhpWgGCLvP9+96pjGk
+ T9WMZOh9qPCLs8O0f3VFK+KLlzE= )
+ 3600 NSEC test.non-terminal.multiple-type-wks-record.example.com. WKS RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ pzOvjfjiGC9VJvwetU61b5K90963EiKAeTou
+ zgBFZslR6OYGDUeoYNuYi9CDJPyOctb8NAsq
+ 6EZXU8WBAGAPJbXp3+VtWYVX8Cu7nI1fMdbA
+ KUA5GCiUBlNp/w75unen6fQ9imtblyjg+/XC
+ kIlek+vR08q1TBM3WUbKVYUinGU= )
+test.non-terminal.multiple-type-wks-record.example.com. 86400 IN WKS 218.241.109.1 6 23 25 53
+ 86400 IN WKS 218.241.109.2 6 23 25 53
+ 86400 IN WKS 218.241.109.3 6 23 25 53
+ 86400 IN WKS 218.241.109.4 6 23 25 53
+ 86400 IN WKS 218.241.109.5 6 23 25 53
+ 86400 IN WKS 218.241.109.6 6 23 25 53 6000
+ 86400 IN WKS 218.241.109.7 6 23 25 53
+ 86400 IN WKS 218.241.109.8 6 23 25 53
+ 86400 IN WKS 218.241.109.9 6 23 25 53
+ 86400 IN WKS 218.241.109.10 6 23 25 53
+ 86400 IN WKS 218.241.109.11 6 22 23 25 53
+ 86400 IN WKS 218.241.109.12 6 22 23 25 53
+ 86400 IN WKS 218.241.109.13 6 22 23 25 53
+ 86400 IN WKS 218.241.109.14 6 22 25 53 80
+ 86400 IN WKS 218.241.109.15 6 22 25 53 80
+ 86400 IN WKS 218.241.109.16 6 22 25 80 6000
+ 86400 RRSIG WKS 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ bh+t72rURTD/AUNkK7tSgUNR1MfoksE2IlYg
+ bVwdLtmoIZdG6bH1ZjGI+EqxFL+jDGLiCHC/
+ HvZ8zc2QEjDYCvIvWU1NdaeVFAxqLNSDuz8g
+ d4l47H99JPTQgzRTGynfuJndDzFo76QEwSph
+ PhPQMgp2LQekn9IJ09ld+afY+4Q= )
+ 3600 NSEC NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com. WKS RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ O50OPaNiLok8UClIxTBPo9b/yE/3Ouyp2u4j
+ 6WPPzEMBqYb2fZ5YTlF89hJBcR9COabqc6Zz
+ yJnU0cyKBWu8r7kIcuIDCb0BrPN3/50b18CQ
+ qp1oarmS8E1SU+yPkPLbJzQcDiZpSb89Uqpe
+ pNDtVGe8SkYkcgzHI0jOnRCrSSQ= )
+test.non-terminal.NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com. 86400 IN NS ns1.NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com.
+ns1.NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com. 86400 IN A 192.168.2.1
+test.non-terminal.ns1.NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com. 86400 IN A 192.168.2.1
+NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com. 86400 IN NS ns1.NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com.
+ 3600 NSEC testa.no-type.example.com. NS RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ AeXmrYa9++hgSgWI8qLyDG/6HnVUFGjv/Jh3
+ Sbcbz/Wkt35RywxgixoMPizs3rxlEmy/jBCC
+ C3p4cBQIhSZ2vOsExbEpadNbbCNaI0Qilwx3
+ LSOScfgBKeUdpDjaUnJPEgd8EbMDjBGDhySf
+ KOki0VRaVnqP6EFLtlFyf1wQXto= )
+multiple-type-txt-record.example.com. 86400 IN TXT "txt::1"
+ 86400 IN TXT "txt::2"
+ 86400 IN TXT "txt::3"
+ 86400 IN TXT "txt::4"
+ 86400 IN TXT "txt::5"
+ 86400 IN TXT "txt::6"
+ 86400 IN TXT "txt::7"
+ 86400 IN TXT "txt::8"
+ 86400 IN TXT "txt::9"
+ 86400 IN TXT "txt::10"
+ 86400 IN TXT "txt::11"
+ 86400 IN TXT "txt::12"
+ 86400 IN TXT "txt::13"
+ 86400 IN TXT "txt::14"
+ 86400 IN TXT "txt::15"
+ 86400 IN TXT "txt::16"
+ 86400 IN TXT "txt::17"
+ 86400 IN TXT "txt::18"
+ 86400 IN TXT "txt::19"
+ 86400 IN TXT "txt::20"
+ 86400 IN TXT "txt::21"
+ 86400 IN TXT "txt::22"
+ 86400 IN TXT "txt::23"
+ 86400 IN TXT "txt::24"
+ 86400 IN TXT "txt::25"
+ 86400 IN TXT "txt::26"
+ 86400 IN TXT "txt::27"
+ 86400 IN TXT "txt::28"
+ 86400 IN TXT "txt::29"
+ 86400 IN TXT "txt::30"
+ 86400 IN TXT "txt::31"
+ 86400 RRSIG TXT 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ e7Y+piYf7OeKFSgsjUABzPA8Io5ZRNv+euzl
+ 4LY8VvzcVsORAITUUVGhBM21MK7qGOvJ3uIZ
+ 9rh6Ojv4XAx8fzBLMaGLJLTUeZjC2CASD1t2
+ Sahbxvmmv1/Ikj7lSe8hsLjp85yuZ4KWKryl
+ a6kK+QW2/3IvVHF0P5T35EiZ158= )
+ 3600 NSEC test.non-terminal.multiple-type-txt-record.example.com. TXT RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ nN89y/xJwgkmhrr6HsGqcKubezzlYDVQJI2J
+ 7vXUFik+AVZwsJfoVmfnX87osJX+wrYzVG1w
+ RtUN0L57zc7O+SYfvb00OjeQjIwYfEQprhm+
+ orrbmStdGehT+qSeGoDitupTJYgY0rUpVb9o
+ ap0qcZWH7QBNdTQrqdwTXj0oaQ4= )
+multiple-type-srv-record.example.com. 86400 IN SRV 0 2 80 www.movie0.edu.
+ 86400 IN SRV 1 3 80 www.movie1.edu.
+ 86400 IN SRV 2 4 80 www.movie2.edu.
+ 86400 IN SRV 3 5 80 www.movie3.edu.
+ 86400 IN SRV 4 6 80 www.movie4.edu.
+ 86400 IN SRV 5 7 80 www.movie5.edu.
+ 86400 IN SRV 6 8 80 www.movie6.edu.
+ 86400 IN SRV 7 9 80 www.movie7.edu.
+ 86400 IN SRV 8 10 80 www.movie8.edu.
+ 86400 IN SRV 9 11 80 www.movie9.edu.
+ 86400 IN SRV 10 12 80 www.movie10.edu.
+ 86400 IN SRV 11 13 80 www.movie11.edu.
+ 86400 IN SRV 12 14 80 www.movie12.edu.
+ 86400 RRSIG SRV 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ LYlM0amkBW4UvNWm/dJEqk4BDDNndLZ11kdF
+ 03qFuHTgXsRqmwWFuZo5y4pQ3r7Zvt1T9EgS
+ 1JtftwnqmtdD1017G8Te8nOtNIWZZfEL6Jbr
+ FFbPoNY6o5ATSCZ+qMVsyPAcPZy4LUZlbnQc
+ In0YPMUnSuIqmawOwkHuhwN4okI= )
+ 3600 NSEC test.non-terminal.multiple-type-srv-record.example.com. SRV RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ tcZ7KwV1sX6P/tBKrok6DTp5AqJDHvXioeO5
+ RIXmfQyPQLWsc2i3EokkABiFz80PGARx2BEd
+ RxZUxkHXhCaoVXkQHDih+90uOVEOJIBMmd6e
+ KLfF2k0cmaUwP2ZrUcXV1i6hz04ouyWj3ZS8
+ 9+vibTjaKHRQfFHd8pj2+KbMuE8= )
+NS1.example.com. 86400 IN A 218.241.111.236
+ 86400 RRSIG A 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ rqS35MJl9mPPZiLU3qRIxBLxO7vGn2lDoh3f
+ 4YXB8t0bKCxvldlINNermQ+3filYHqxst4DF
+ 2baZCXU8bTpBEr2gtrhRp5/kDan85kTicZzj
+ tnJgdtDEdK7QBIcxtC6W/UoZAskINhfHEAvp
+ VrfeGxq9FB/ZM7mA4RAJbd9nTIw= )
+ 3600 NSEC sub.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ kvH+Drx2kDQXzhuXyscBF12sQ4BXeuUwPb4t
+ oj6rddztnktJV8Y6w3JLBDwIIUxw/ciqrRt0
+ M5AO14ujKlGgeG90Q8By9em2T7X16zYfLKIt
+ Dvi1VWmggPHVec1TeX9IqNs6ub/bK2MZ4T+x
+ +ehCHwojKTP8Y/b4nvx/kvskhBM= )
+test.non-terminal.sub.example.com. 86400 IN NS ns.sub.example.com.
+ns.sub.example.com. 86400 IN A 218.241.111.236
+test.non-terminal.ns.sub.example.com. 86400 IN A 218.241.111.236
+sub.example.com. 86400 IN NS ns.sub.example.com.
+ 86400 DS 49822 5 1 (
+ 6E7920E917F926300EDFB5F61B57588CF2B5
+ 2ADF )
+ 86400 DS 49822 5 2 (
+ 3EBE7AF8D46657F51149714AC5FF2FB23F5A
+ D8258A2229764475C86C9B5B1A59 )
+ 86400 RRSIG DS 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ ZAl7uANYIwncfhAV+AGiunvt4BflavkEnJGV
+ KXPgcLdpPCsBTLCXPbyAqxiu0ywgXQ5JuIHm
+ AF0AKzeE+abEiPipP816jCi3rQiSljI/zwHI
+ t4fcB5zvM0yBE0HkAVP+ftNbda2RvF8cjXH4
+ aPieL89lCcC3zuVwEo1NZIommKo= )
+ 3600 NSEC sub-cname.example.com. NS DS RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ nesi4ehQeGU8evobfldaepUGLmgw57nf2Wg/
+ F/A6TkmbgnVoWWPkT4KBSMgTmuym2TfFq7AT
+ b6hIsVh+OYToioFZha6UwrIgtiqxcplgCKwY
+ WB/tLtprKcTMlcaPWTtgzA18m/j0p7enlL13
+ kAJxjJIbKD4YKIRC0yWzlgk/Grc= )
+sub-cname.example.com. 86400 IN CNAME www.sub.example.com.
+ 86400 RRSIG CNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ aWW0K9aKL99ZOTnljdoWQxANkr5aZ0velC9D
+ WOob680cmhJ+8OlQVMNbcMZyPU7Zr8nHKAXe
+ 0On+72WLqsiGEQfZvBvMbm70R5jrEbtfFlL2
+ 8UdkIzkMPJf+IJlg+qFdZk7w1i6xlRxDOOKB
+ vZgZQwD3eTO2971kyypBYK+/4aU= )
+ 3600 NSEC test.non-terminal.sub-cname.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ AtfbnSLONvl0EB0k7oNBEqQCL3WIrsCmf+sn
+ CB5AOLE7/lWzsLm0vCN8lbrOXhqzg6iswPVO
+ vEvxkqpuA9I0iObyiqwYNfo7Dr1DWKSTjq+b
+ WdjKHw3LZ9s1BbrJX6Z5qtAU0I/22Tia4OMi
+ UFn0sPWOka7LNW8imGdsjV6K9cI= )
+test.non-terminal.sub-cname.example.com. 86400 IN CNAME www.sub.example.com.
+ 86400 RRSIG CNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ cvcWxilQsUeAl698HIsB+hfZO4jeYJHTSGCC
+ Y1eX8QEPox2LLmzkuB+j4VnBq9p0bOyg5S1r
+ FS4I8piCKJNt0xmCnXsVgaeEZ1uwBmkXN5nH
+ C9ba32o3aYUwEyAX/TJyNnKjc5Hl1Z8ePFOX
+ 05KRjn0Q9DjYsICA7F7ZMVYIWhE= )
+ 3600 NSEC sub-dname.example.com. CNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ M4TFyUkhvxkTPg+VD6v04O3DN5W15itA7iXI
+ 2JbePRx0MSK1nMx+tgKpYu/6hmsMMTcKpwph
+ TtZf+ieQTD04YoCk8hOm/QgHHVbt1HM47wMZ
+ AjdMosBvTAzv3Os1I1tENctPLPSCEdWUbmuI
+ JvmKiUG8Zn/9dvadT8rWu58kBOE= )
+sub-dname.example.com. 86400 IN DNAME sub.example.com.
+ 86400 RRSIG DNAME 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ pI27ntzYV8TIzdk9ObcvyV5VTdiMjCb0IPFi
+ gt/R2MXT9p5c/am6PyO6npjbxFIvibIyUvZg
+ YTtcN1vkE/d4RpgIZtaT0Zc7SNobXz1xVWXM
+ kOA7sK4cdI+7hv7bcQbrowXyF2TJnxO8FK8d
+ JWngaQS23xT4dSujJ5Q+gHP6kGQ= )
+ 3600 NSEC test.non-terminal.sub-dname.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ z67GTr+8vik0Gc+xI2efUrBZD4xw/4bb9dzP
+ AmnqEtIcuUdZnpBybe4KlwvbtYpalkF0lil2
+ P7zFNhMHc8Afb5aPLTUBQQFGo5XRZABzo83g
+ EnCmK+wCnGT50EZMJq5DZBRleCsynVd+ltKV
+ ZD+dVp/NwpQXJC7GRiotTK1oh8U= )
+test.non-terminal.sub-dname.example.com. 86400 IN DNAME sub.example.com.
+ 86400 RRSIG DNAME 5 5 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ hn45X0G/jwq6aqv1b6R9gS+la+mJUE8tpnQa
+ Sn1dk4Bcrf6tkI5GHvL/CeQTVAMfaKlnbnNE
+ wduF99rru4LzAz0kI4I70Oo0R2TfqzHjCD7P
+ BgtOg5rym8Z0gVA8DYlXQ6fwZvxzsoY9nuGR
+ P2yDYo4nY1kTTttzi41KIoYI0+Q= )
+ 3600 NSEC www.a.b.sub2.example.com. DNAME RRSIG NSEC
+ 3600 RRSIG NSEC 5 5 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ RejBSjNeUjtNBFw0N7tnaDXlDddCiAQIBlKS
+ swczhQxS72crD1vnPh4lg2TAxSytTlXUeF60
+ VRKmD5C+7zXMcKhukzTipWjLFaaQr83VfAUa
+ htA2UN1fNu2AGBWdZKJvKc18AtDNsgdwbxKY
+ 6zGg9r8lDdDv8yrt1EhVlETC9eo= )
+www.a.b.sub2.example.com. 86400 IN A 192.168.1.1
+ 86400 RRSIG A 5 6 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ OI3kSrtJbMMv+qbScv46yi9qfSupzUvD7R28
+ T5KBKUe1lIBM/nP3w4W/WUoYnG+ao5XNdSN3
+ BuxYOd1gDOMr3ZSSbzAMOvoOviVSxbW1X3Lm
+ P0/nEHkQF9L0UygDn4qnZg56Tmt5VGHDWk7U
+ HZdJ3Sa6jMX+aPKPbchyaG5wiqA= )
+ 3600 NSEC test.non-terminal.www.a.b.sub2.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 6 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ wTJX72cgdq0aNwh5MpKg5N3lpMxdI7oaEqjQ
+ 7LFdlNhge9pKGFdq4qpvKrqqt8H8evlW5CMB
+ ZtDV58SY8mLuNoJZt/ZEkc5BAe6SEF/Jshzs
+ AcZenhh2LhXRC9yTbIc2uUCFOf/t7w5DZRSF
+ qgLA4tfw0I8tlndjbZsd7owPixI= )
+subdn.example.com. 86400 IN NS ns.subdn.cn.
+ 3600 NSEC subdomain.example.com. NS RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ nCfBP/IRCUZJEG8TyfP13MrhQZOXPsEPZWdd
+ qLQkrXgywK4whngLQBC7RvmHJrmjZFhfNIGM
+ ATfsP6Ii5BgqQDrjxqvftMNta81rTxnXZEOb
+ I6wgo+F4OlFZ0esMgdNTtsVawXV5rxMCL3hA
+ a0HXZrxSp+ZOrn11rOYGKZ3XvXs= )
+test.non-terminal.subdn.example.com. 86400 IN NS ns.subdn.cn.
+testa.no-type.example.com. 86400 IN A 10.1.1.1
+ 86400 RRSIG A 5 4 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ aKBQAJSupqxsqeTrD/UTweU75M2V2wv8bLlw
+ yqp3FnzpLUeakTS4a6Y0qtvzumUohe1gmHj0
+ DQTtLMRaxNQcIleU02fCUI+d9BUh4xLhYevD
+ vP/t2k/zKoLWuVttDkQBarpifVq8axpguPEl
+ TT/kRyzk+VCpCzQSK4rik59OXA4= )
+ 3600 NSEC testaaaa.no-type.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 4 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ mSGRBg1l+w1qsFWrIt3tFNT2S4OOHteoiaJH
+ K+T2Smsy7o3OdJ9mL3F1Hh35QXDy4HDTjib3
+ 3odGn+4dot3ZY3aaafUW9y5Hdqprf+T0u8Ir
+ m3THIDMQB23pviwXZq9yhykzTKFFVPUL1Gat
+ sLleGYbv4X3R+cZ8aafVs1bGxaE= )
+test.non-terminal.subdomain.example.com. 86400 IN NS ns1.mysub.com.
+ 86400 IN NS ns2.mysub.com.
+test.non-terminal.www.a.b.sub2.example.com. 86400 IN A 192.168.1.1
+ 86400 RRSIG A 5 8 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ d//X2Ycwf5qOjOPnuGu3VHqIwDgnrTFqVMBq
+ jZn3CtYDE0hOTjwZNYyisTV+XJjUQZWko6XG
+ Usu3xKvyoxjLYQygY9nhzBMZG9lYvobJAHLw
+ 2Cd7QmfgwSzLKDVPh3ONyZy/BbZmnMubaWwO
+ k9EO1hGarRPIfvSi14bTa+VfEqM= )
+ 3600 NSEC subdn.example.com. A RRSIG NSEC
+ 3600 RRSIG NSEC 5 8 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ CTVkFc2+9gdljg6aNEN7dhDqqtZJXz8juhOt
+ lM4iNhwMWUy2kTEfGC3koSp8aVG/h+NIMH5m
+ lPDX+4BYM2XtLC23SWyyc/s/nnUDqTPw7PAL
+ R0/+0Rcv8YGk0N35G5jX+LBN2tXGNNMuvThM
+ p7jCSbFwO8Y7H8rlMf5i6Ygunu4= )
+testaaaa.no-type.example.com. 86400 IN AAAA ::1
+ 86400 RRSIG AAAA 5 4 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ eWUKLr3s4Flt/t8FjM5q7cRykBc/FNFXwTN9
+ pq2ucDrkuiLfe5ej4MNe6aNO6EOncRWVH6Qa
+ uJ0nisOuUZg2OVFIEHqLP1YF58O/xlhK3dDb
+ 1kAIr1+cM3CEkN0l3AJ6yd92j6P0611Yu26s
+ 7JlF3ZuX52VZpve9N+uk5uEsW/o= )
+ 3600 NSEC NS1.example.com. AAAA RRSIG NSEC
+ 3600 RRSIG NSEC 5 4 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ FcHjt3C/q4MU3ZV2q7FoF4zsop0qJDf9sR7y
+ Bx5pqk6AvXKcrpqUMIHlGlRxE5MJHi4bGBTi
+ Hyr3tZ6eXBVPqM+PBm3iT4HqnHGkwJm1dFWj
+ bayBY/7q4LTyQhReP3PaZjApkhqv3ehIlG1J
+ zuIHw5Axvw3bTzexBUlNgmDvrNQ= )
+subdomain.example.com. 86400 IN NS ns1.mysub.com.
+ 86400 IN NS ns2.mysub.com.
+ 86400 DS 6613 5 1 (
+ 39A2A64CA73B103E983EE77305E8DAEE9DBB
+ B0FA )
+ 86400 DS 6613 5 2 (
+ 8D24DBE7FEA6E40A27382B45EE189FBF30B0
+ 0FB38734BA5415A7695B11FE5CE7 )
+ 86400 RRSIG DS 5 3 86400 20110408061651 (
+ 20110309061651 27366 example.com.
+ Hsr5Z2S0t6NrbGYI69ynQyZYZfujoq4ANuCs
+ NqRkWa4fVQQ8uJr04pCAe2Dzm3R1dWyAHOAM
+ kUtt7GwYYH/hjjs4K3E0h63cqAkbxmyOdss/
+ lelPaVAGt66D5QSE1SRXKGKnQUD+sJM0plkz
+ 1KrMV/PNibJ1R3U8hYYtwh+gAyE= )
+ 3600 NSEC example.com. NS DS RRSIG NSEC
+ 3600 RRSIG NSEC 5 3 3600 20110408061651 (
+ 20110309061651 27366 example.com.
+ EWh5yFAxcePS0iGoif8JFj4ZvWuPtXSguzrB
+ OEl8BNMY4KeMVmwBLoGRpECKpybqqTXB/His
+ 7mejU9HzP47cNrD0eV73UvbHe0qc2DlgfL5Q
+ hXVMdQJZ0GJO4r6HNwoyMxOPZMXnDSijjVkG
+ UikyHQsGCfF7um8cw2KBmp73xqI= )
More information about the bind10-changes
mailing list